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 **********************************************************************/
69 /* Here we want the physical address of the memory.
70 * This is used when initializing the contents of the area.
72 static inline unsigned long kvirt_to_pa(unsigned long adr
)
74 unsigned long kva
, ret
;
76 kva
= (unsigned long) page_address(vmalloc_to_page((void *)adr
));
77 kva
|= adr
& (PAGE_SIZE
-1); /* restore the offset */
82 static void *rvmalloc(unsigned long size
)
87 size
= PAGE_ALIGN(size
);
88 mem
= vmalloc_32(size
);
92 memset(mem
, 0, size
); /* Clear the ram out, no junk to the user */
93 adr
= (unsigned long) mem
;
95 SetPageReserved(vmalloc_to_page((void *)adr
));
103 static void rvfree(void *mem
, unsigned long size
)
110 adr
= (unsigned long) mem
;
111 while ((long) size
> 0) {
112 ClearPageReserved(vmalloc_to_page((void *)adr
));
121 /****************************************************************************
123 * se401 register read/write functions
125 ***************************************************************************/
127 static int se401_sndctrl(int set
, struct usb_se401
*se401
, unsigned short req
,
128 unsigned short value
, unsigned char *cp
, int size
)
130 return usb_control_msg (
132 set
? usb_sndctrlpipe(se401
->dev
, 0) : usb_rcvctrlpipe(se401
->dev
, 0),
134 (set
? USB_DIR_OUT
: USB_DIR_IN
) | USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
143 static int se401_set_feature(struct usb_se401
*se401
, unsigned short selector
,
144 unsigned short param
)
146 /* specs say that the selector (address) should go in the value field
147 and the param in index, but in the logs of the windows driver they do
148 this the other way around...
150 return usb_control_msg (
152 usb_sndctrlpipe(se401
->dev
, 0),
153 SE401_REQ_SET_EXT_FEATURE
,
154 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
163 static unsigned short se401_get_feature(struct usb_se401
*se401
,
164 unsigned short selector
)
166 /* For 'set' the selecetor should be in index, not sure if the spec is
172 usb_rcvctrlpipe(se401
->dev
, 0),
173 SE401_REQ_GET_EXT_FEATURE
,
174 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
181 return cp
[0]+cp
[1]*256;
184 /****************************************************************************
188 ***************************************************************************/
191 static int se401_send_pict(struct usb_se401
*se401
)
193 se401_set_feature(se401
, HV7131_REG_TITL
, se401
->expose_l
);/* integration time low */
194 se401_set_feature(se401
, HV7131_REG_TITM
, se401
->expose_m
);/* integration time mid */
195 se401_set_feature(se401
, HV7131_REG_TITU
, se401
->expose_h
);/* integration time mid */
196 se401_set_feature(se401
, HV7131_REG_ARLV
, se401
->resetlevel
);/* reset level value */
197 se401_set_feature(se401
, HV7131_REG_ARCG
, se401
->rgain
);/* red color gain */
198 se401_set_feature(se401
, HV7131_REG_AGCG
, se401
->ggain
);/* green color gain */
199 se401_set_feature(se401
, HV7131_REG_ABCG
, se401
->bgain
);/* blue color gain */
204 static void se401_set_exposure(struct usb_se401
*se401
, int brightness
)
206 int integration
=brightness
<<5;
208 if (flickerless
==50) {
209 integration
=integration
-integration
%106667;
211 if (flickerless
==60) {
212 integration
=integration
-integration
%88889;
214 se401
->brightness
=integration
>>5;
215 se401
->expose_h
=(integration
>>16)&0xff;
216 se401
->expose_m
=(integration
>>8)&0xff;
217 se401
->expose_l
=integration
&0xff;
220 static int se401_get_pict(struct usb_se401
*se401
, struct video_picture
*p
)
222 p
->brightness
=se401
->brightness
;
223 if (se401
->enhance
) {
230 p
->hue
=se401
->rgain
<<10;
231 p
->palette
=se401
->palette
;
232 p
->depth
=3; /* rgb24 */
237 static int se401_set_pict(struct usb_se401
*se401
, struct video_picture
*p
)
239 if (p
->palette
!= VIDEO_PALETTE_RGB24
)
241 se401
->palette
=p
->palette
;
242 if (p
->hue
!=se401
->hue
) {
243 se401
->rgain
= p
->hue
>>10;
244 se401
->bgain
= 0x40-(p
->hue
>>10);
247 if (p
->brightness
!=se401
->brightness
) {
248 se401_set_exposure(se401
, p
->brightness
);
250 if (p
->whiteness
>=32768) {
255 se401_send_pict(se401
);
256 se401_send_pict(se401
);
261 Hyundai have some really nice docs about this and other sensor related
262 stuff on their homepage: www.hei.co.kr
264 static void se401_auto_resetlevel(struct usb_se401
*se401
)
266 unsigned int ahrc
, alrc
;
267 int oldreset
=se401
->resetlevel
;
269 /* For some reason this normally read-only register doesn't get reset
270 to zero after reading them just once...
272 se401_get_feature(se401
, HV7131_REG_HIREFNOH
);
273 se401_get_feature(se401
, HV7131_REG_HIREFNOL
);
274 se401_get_feature(se401
, HV7131_REG_LOREFNOH
);
275 se401_get_feature(se401
, HV7131_REG_LOREFNOL
);
276 ahrc
=256*se401_get_feature(se401
, HV7131_REG_HIREFNOH
) +
277 se401_get_feature(se401
, HV7131_REG_HIREFNOL
);
278 alrc
=256*se401_get_feature(se401
, HV7131_REG_LOREFNOH
) +
279 se401_get_feature(se401
, HV7131_REG_LOREFNOL
);
281 /* Not an exact science, but it seems to work pretty well... */
283 while (alrc
>=10 && se401
->resetlevel
< 63) {
287 } else if (ahrc
> 20) {
288 while (ahrc
>=20 && se401
->resetlevel
> 0) {
293 if (se401
->resetlevel
!=oldreset
)
294 se401_set_feature(se401
, HV7131_REG_ARLV
, se401
->resetlevel
);
299 /* irq handler for snapshot button */
300 static void se401_button_irq(struct urb
*urb
, struct pt_regs
*regs
)
302 struct usb_se401
*se401
= urb
->context
;
306 info("ohoh: device vapourished");
310 switch (urb
->status
) {
317 /* this urb is terminated, clean up */
318 dbg("%s - urb shutting down with status: %d", __FUNCTION__
, urb
->status
);
321 dbg("%s - nonzero urb status received: %d", __FUNCTION__
, urb
->status
);
325 if (urb
->actual_length
>=2) {
327 se401
->buttonpressed
=1;
330 status
= usb_submit_urb (urb
, GFP_ATOMIC
);
332 err ("%s - usb_submit_urb failed with result %d",
333 __FUNCTION__
, status
);
336 static void se401_video_irq(struct urb
*urb
, struct pt_regs
*regs
)
338 struct usb_se401
*se401
= urb
->context
;
339 int length
= urb
->actual_length
;
342 if (!se401
->streaming
)
346 info ("ohoh: device vapourished");
350 /* 0 sized packets happen if we are to fast, but sometimes the camera
351 keeps sending them forever...
353 if (length
&& !urb
->status
) {
354 se401
->nullpackets
=0;
355 switch(se401
->scratch
[se401
->scratch_next
].state
) {
361 case BUFFER_UNUSED
: {
362 memcpy(se401
->scratch
[se401
->scratch_next
].data
, (unsigned char *)urb
->transfer_buffer
, length
);
363 se401
->scratch
[se401
->scratch_next
].state
=BUFFER_READY
;
364 se401
->scratch
[se401
->scratch_next
].offset
=se401
->bayeroffset
;
365 se401
->scratch
[se401
->scratch_next
].length
=length
;
366 if (waitqueue_active(&se401
->wq
)) {
367 wake_up_interruptible(&se401
->wq
);
369 se401
->scratch_overflow
=0;
370 se401
->scratch_next
++;
371 if (se401
->scratch_next
>=SE401_NUMSCRATCH
)
372 se401
->scratch_next
=0;
376 se401
->bayeroffset
+=length
;
377 if (se401
->bayeroffset
>=se401
->cheight
*se401
->cwidth
) {
378 se401
->bayeroffset
=0;
381 se401
->nullpackets
++;
382 if (se401
->nullpackets
> SE401_MAX_NULLPACKETS
) {
383 if (waitqueue_active(&se401
->wq
)) {
384 wake_up_interruptible(&se401
->wq
);
389 /* Resubmit urb for new data */
392 if(usb_submit_urb(urb
, GFP_KERNEL
))
393 info("urb burned down");
397 static void se401_send_size(struct usb_se401
*se401
, int width
, int height
)
400 int mode
=0x03; /* No compression */
401 int sendheight
=height
;
404 /* JangGu compression can only be used with the camera supported sizes,
405 but bayer seems to work with any size that fits on the sensor.
406 We check if we can use compression with the current size with either
407 4 or 16 times subcapturing, if not we use uncompressed bayer data
408 but this will result in cutouts of the maximum size....
410 while (i
<se401
->sizes
&& !(se401
->width
[i
]==width
&& se401
->height
[i
]==height
))
412 while (i
<se401
->sizes
) {
413 if (se401
->width
[i
]==width
*2 && se401
->height
[i
]==height
*2) {
414 sendheight
=se401
->height
[i
];
415 sendwidth
=se401
->width
[i
];
418 if (se401
->width
[i
]==width
*4 && se401
->height
[i
]==height
*4) {
419 sendheight
=se401
->height
[i
];
420 sendwidth
=se401
->width
[i
];
426 se401_sndctrl(1, se401
, SE401_REQ_SET_WIDTH
, sendwidth
, NULL
, 0);
427 se401_sndctrl(1, se401
, SE401_REQ_SET_HEIGHT
, sendheight
, NULL
, 0);
428 se401_set_feature(se401
, SE401_OPERATINGMODE
, mode
);
431 se401
->format
=FMT_BAYER
;
433 se401
->format
=FMT_JANGGU
;
440 In this function se401_send_pict is called several times,
441 for some reason (depending on the state of the sensor and the phase of
442 the moon :) doing this only in either place doesn't always work...
444 static int se401_start_stream(struct usb_se401
*se401
)
450 se401_sndctrl(1, se401
, SE401_REQ_CAMERA_POWER
, 1, NULL
, 0);
451 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 1, NULL
, 0);
453 /* Set picture settings */
454 se401_set_feature(se401
, HV7131_REG_MODE_B
, 0x05);/*windowed + pix intg */
455 se401_send_pict(se401
);
457 se401_send_size(se401
, se401
->cwidth
, se401
->cheight
);
459 se401_sndctrl(1, se401
, SE401_REQ_START_CONTINUOUS_CAPTURE
, 0, NULL
, 0);
461 /* Do some memory allocation */
462 for (i
=0; i
<SE401_NUMFRAMES
; i
++) {
463 se401
->frame
[i
].data
=se401
->fbuf
+ i
* se401
->maxframesize
;
464 se401
->frame
[i
].curpix
=0;
466 for (i
=0; i
<SE401_NUMSBUF
; i
++) {
467 se401
->sbuf
[i
].data
=kmalloc(SE401_PACKETSIZE
, GFP_KERNEL
);
470 se401
->bayeroffset
=0;
471 se401
->scratch_next
=0;
472 se401
->scratch_use
=0;
473 se401
->scratch_overflow
=0;
474 for (i
=0; i
<SE401_NUMSCRATCH
; i
++) {
475 se401
->scratch
[i
].data
=kmalloc(SE401_PACKETSIZE
, GFP_KERNEL
);
476 se401
->scratch
[i
].state
=BUFFER_UNUSED
;
479 for (i
=0; i
<SE401_NUMSBUF
; i
++) {
480 urb
=usb_alloc_urb(0, GFP_KERNEL
);
484 usb_fill_bulk_urb(urb
, se401
->dev
,
485 usb_rcvbulkpipe(se401
->dev
, SE401_VIDEO_ENDPOINT
),
486 se401
->sbuf
[i
].data
, SE401_PACKETSIZE
,
492 err
=usb_submit_urb(se401
->urb
[i
], GFP_KERNEL
);
494 err("urb burned down");
502 static int se401_stop_stream(struct usb_se401
*se401
)
506 if (!se401
->streaming
|| !se401
->dev
)
511 se401_sndctrl(1, se401
, SE401_REQ_STOP_CONTINUOUS_CAPTURE
, 0, NULL
, 0);
513 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 0, NULL
, 0);
514 se401_sndctrl(1, se401
, SE401_REQ_CAMERA_POWER
, 0, NULL
, 0);
516 for (i
=0; i
<SE401_NUMSBUF
; i
++) if (se401
->urb
[i
]) {
517 usb_unlink_urb(se401
->urb
[i
]);
518 usb_free_urb(se401
->urb
[i
]);
520 kfree(se401
->sbuf
[i
].data
);
522 for (i
=0; i
<SE401_NUMSCRATCH
; i
++) {
523 kfree(se401
->scratch
[i
].data
);
524 se401
->scratch
[i
].data
=NULL
;
530 static int se401_set_size(struct usb_se401
*se401
, int width
, int height
)
532 int wasstreaming
=se401
->streaming
;
533 /* Check to see if we need to change */
534 if (se401
->cwidth
==width
&& se401
->cheight
==height
)
537 /* Check for a valid mode */
538 if (!width
|| !height
)
540 if ((width
& 1) || (height
& 1))
542 if (width
>se401
->width
[se401
->sizes
-1])
544 if (height
>se401
->height
[se401
->sizes
-1])
547 /* Stop a current stream and start it again at the new size */
549 se401_stop_stream(se401
);
551 se401
->cheight
=height
;
553 se401_start_stream(se401
);
558 /****************************************************************************
562 ***************************************************************************/
565 This shouldn't really be done in a v4l driver....
566 But it does make the image look a lot more usable.
567 Basically it lifts the dark pixels more than the light pixels.
569 static inline void enhance_picture(unsigned char *frame
, int len
)
572 *frame
=(((*frame
^255)*(*frame
^255))/255)^255;
577 static inline void decode_JangGu_integrate(struct usb_se401
*se401
, int data
)
579 struct se401_frame
*frame
=&se401
->frame
[se401
->curframe
];
580 int linelength
=se401
->cwidth
*3;
582 if (frame
->curlinepix
>= linelength
) {
584 frame
->curline
+=linelength
;
587 /* First three are absolute, all others relative.
588 * Format is rgb from right to left (mirrorred image),
589 * we flip it to get bgr from left to right. */
590 if (frame
->curlinepix
< 3) {
591 *(frame
->curline
-frame
->curlinepix
)=1+data
*4;
593 *(frame
->curline
-frame
->curlinepix
)=
594 *(frame
->curline
-frame
->curlinepix
+3)+data
*4;
599 static inline void decode_JangGu_vlc (struct usb_se401
*se401
, unsigned char *data
, int bit_exp
, int packetlength
)
608 while (pos
< packetlength
) {
610 while (bit_cur
&& bit_exp
) {
611 bit
=((*data
)>>(bit_cur
-1))&1;
617 decode_JangGu_integrate(se401
, 0);
626 vlc_data
= -(1<<vlc_size
) + 1;
630 vlc_data
+=bit
<<vlc_size
;
632 decode_JangGu_integrate(se401
, vlc_data
);
644 static inline void decode_JangGu (struct usb_se401
*se401
, struct se401_scratch
*buffer
)
646 unsigned char *data
=buffer
->data
;
647 int len
=buffer
->length
;
648 int bit_exp
=0, pix_exp
=0, frameinfo
=0, packetlength
=0, size
;
652 if (!se401
->frame
[se401
->curframe
].curpix
) {
653 se401
->frame
[se401
->curframe
].curlinepix
=0;
654 se401
->frame
[se401
->curframe
].curline
=
655 se401
->frame
[se401
->curframe
].data
+
657 if (se401
->frame
[se401
->curframe
].grabstate
==FRAME_READY
)
658 se401
->frame
[se401
->curframe
].grabstate
=FRAME_GRABBING
;
661 while (datapos
< len
) {
662 size
=1024-se401
->vlcdatapos
;
663 if (size
+datapos
> len
)
665 memcpy(se401
->vlcdata
+se401
->vlcdatapos
, data
+datapos
, size
);
666 se401
->vlcdatapos
+=size
;
668 if (se401
->vlcdatapos
>= 4) {
669 bit_exp
=se401
->vlcdata
[3]+(se401
->vlcdata
[2]<<8);
670 pix_exp
=se401
->vlcdata
[1]+((se401
->vlcdata
[0]&0x3f)<<8);
671 frameinfo
=se401
->vlcdata
[0]&0xc0;
672 packetlength
=((bit_exp
+47)>>4)<<1;
673 if (packetlength
> 1024) {
678 se401
->frame
[se401
->curframe
].curpix
=0;
681 if (packetlength
&& se401
->vlcdatapos
>= packetlength
) {
682 decode_JangGu_vlc(se401
, se401
->vlcdata
, bit_exp
, packetlength
);
683 se401
->frame
[se401
->curframe
].curpix
+=pix_exp
*3;
684 datapos
+=size
-(se401
->vlcdatapos
-packetlength
);
686 if (se401
->frame
[se401
->curframe
].curpix
>=se401
->cwidth
*se401
->cheight
*3) {
687 if (se401
->frame
[se401
->curframe
].curpix
==se401
->cwidth
*se401
->cheight
*3) {
688 if (se401
->frame
[se401
->curframe
].grabstate
==FRAME_GRABBING
) {
689 se401
->frame
[se401
->curframe
].grabstate
=FRAME_DONE
;
693 if (se401
->frame
[(se401
->curframe
+1)&(SE401_NUMFRAMES
-1)].grabstate
==FRAME_READY
) {
694 se401
->curframe
=(se401
->curframe
+1) & (SE401_NUMFRAMES
-1);
699 se401
->frame
[se401
->curframe
].curpix
=0;
708 static inline void decode_bayer (struct usb_se401
*se401
, struct se401_scratch
*buffer
)
710 unsigned char *data
=buffer
->data
;
711 int len
=buffer
->length
;
712 int offset
=buffer
->offset
;
713 int datasize
=se401
->cwidth
*se401
->cheight
;
714 struct se401_frame
*frame
=&se401
->frame
[se401
->curframe
];
716 unsigned char *framedata
=frame
->data
, *curline
, *nextline
;
717 int width
=se401
->cwidth
;
718 int blineoffset
=0, bline
;
719 int linelength
=width
*3, i
;
722 if (frame
->curpix
==0) {
723 if (frame
->grabstate
==FRAME_READY
) {
724 frame
->grabstate
=FRAME_GRABBING
;
726 frame
->curline
=framedata
+linelength
;
730 if (offset
!=frame
->curpix
) {
731 /* Regard frame as lost :( */
737 /* Check if we have to much data */
738 if (frame
->curpix
+len
> datasize
) {
739 len
=datasize
-frame
->curpix
;
741 if (se401
->cheight
%4)
743 bline
=frame
->curpix
/se401
->cwidth
+blineoffset
;
745 curline
=frame
->curline
;
746 nextline
=curline
+linelength
;
747 if (nextline
>= framedata
+datasize
*3)
750 if (frame
->curlinepix
>=width
) {
751 frame
->curlinepix
-=width
;
752 bline
=frame
->curpix
/width
+blineoffset
;
753 curline
+=linelength
*2;
754 nextline
+=linelength
*2;
755 if (curline
>= framedata
+datasize
*3) {
763 if (nextline
>= framedata
+datasize
*3)
767 if ((frame
->curlinepix
&1)) {
774 (*(curline
+1)+*data
)/2;
776 (*(curline
-2)+*data
)/2;
781 if ((frame
->curlinepix
&1)) {
783 (*(curline
+1)+*data
)/2;
785 (*(curline
-2)+*data
)/2;
802 frame
->curline
=curline
;
804 if (frame
->curpix
>=datasize
) {
805 /* Fix the top line */
806 framedata
+=linelength
;
807 for (i
=0; i
<linelength
; i
++) {
809 *framedata
=*(framedata
+linelength
);
811 /* Fix the left side (green is already present) */
812 for (i
=0; i
<se401
->cheight
; i
++) {
813 *framedata
=*(framedata
+3);
814 *(framedata
+1)=*(framedata
+4);
815 *(framedata
+2)=*(framedata
+5);
816 framedata
+=linelength
;
819 frame
->grabstate
=FRAME_DONE
;
822 if (se401
->frame
[(se401
->curframe
+1)&(SE401_NUMFRAMES
-1)].grabstate
==FRAME_READY
) {
823 se401
->curframe
=(se401
->curframe
+1) & (SE401_NUMFRAMES
-1);
828 static int se401_newframe(struct usb_se401
*se401
, int framenr
)
830 DECLARE_WAITQUEUE(wait
, current
);
833 while (se401
->streaming
&&
834 (se401
->frame
[framenr
].grabstate
==FRAME_READY
||
835 se401
->frame
[framenr
].grabstate
==FRAME_GRABBING
) ) {
836 if(!se401
->frame
[framenr
].curpix
) {
840 se401
->scratch
[se401
->scratch_use
].state
!=BUFFER_READY
,
844 if (se401
->nullpackets
> SE401_MAX_NULLPACKETS
) {
845 se401
->nullpackets
=0;
846 info("to many null length packets, restarting capture");
847 se401_stop_stream(se401
);
848 se401_start_stream(se401
);
850 if (se401
->scratch
[se401
->scratch_use
].state
!=BUFFER_READY
) {
851 se401
->frame
[framenr
].grabstate
=FRAME_ERROR
;
854 se401
->scratch
[se401
->scratch_use
].state
=BUFFER_BUSY
;
855 if (se401
->format
==FMT_JANGGU
) {
856 decode_JangGu(se401
, &se401
->scratch
[se401
->scratch_use
]);
858 decode_bayer(se401
, &se401
->scratch
[se401
->scratch_use
]);
860 se401
->scratch
[se401
->scratch_use
].state
=BUFFER_UNUSED
;
861 se401
->scratch_use
++;
862 if (se401
->scratch_use
>=SE401_NUMSCRATCH
)
863 se401
->scratch_use
=0;
864 if (errors
> SE401_MAX_ERRORS
) {
866 info("to much errors, restarting capture");
867 se401_stop_stream(se401
);
868 se401_start_stream(se401
);
873 if (se401
->frame
[framenr
].grabstate
==FRAME_DONE
)
875 enhance_picture(se401
->frame
[framenr
].data
, se401
->cheight
*se401
->cwidth
*3);
879 static void usb_se401_remove_disconnected (struct usb_se401
*se401
)
885 for (i
=0; i
<SE401_NUMSBUF
; i
++) if (se401
->urb
[i
]) {
886 usb_unlink_urb(se401
->urb
[i
]);
887 usb_free_urb(se401
->urb
[i
]);
888 se401
->urb
[i
] = NULL
;
889 kfree(se401
->sbuf
[i
].data
);
891 for (i
=0; i
<SE401_NUMSCRATCH
; i
++) if (se401
->scratch
[i
].data
) {
892 kfree(se401
->scratch
[i
].data
);
895 usb_unlink_urb(se401
->inturb
);
896 usb_free_urb(se401
->inturb
);
898 info("%s disconnected", se401
->camera_name
);
900 /* Free the memory */
902 kfree(se401
->height
);
908 /****************************************************************************
912 ***************************************************************************/
915 static int se401_open(struct inode
*inode
, struct file
*file
)
917 struct video_device
*dev
= video_devdata(file
);
918 struct usb_se401
*se401
= (struct usb_se401
*)dev
;
923 se401
->fbuf
= rvmalloc(se401
->maxframesize
* SE401_NUMFRAMES
);
925 file
->private_data
= dev
;
933 static int se401_close(struct inode
*inode
, struct file
*file
)
935 struct video_device
*dev
= file
->private_data
;
936 struct usb_se401
*se401
= (struct usb_se401
*)dev
;
939 rvfree(se401
->fbuf
, se401
->maxframesize
* SE401_NUMFRAMES
);
940 if (se401
->removed
) {
941 usb_se401_remove_disconnected(se401
);
942 info("device unregistered");
944 for (i
=0; i
<SE401_NUMFRAMES
; i
++)
945 se401
->frame
[i
].grabstate
=FRAME_UNUSED
;
946 if (se401
->streaming
)
947 se401_stop_stream(se401
);
950 file
->private_data
= NULL
;
954 static int se401_do_ioctl(struct inode
*inode
, struct file
*file
,
955 unsigned int cmd
, void *arg
)
957 struct video_device
*vdev
= file
->private_data
;
958 struct usb_se401
*se401
= (struct usb_se401
*)vdev
;
966 struct video_capability
*b
= arg
;
967 strcpy(b
->name
, se401
->camera_name
);
968 b
->type
= VID_TYPE_CAPTURE
;
971 b
->maxwidth
= se401
->width
[se401
->sizes
-1];
972 b
->maxheight
= se401
->height
[se401
->sizes
-1];
973 b
->minwidth
= se401
->width
[0];
974 b
->minheight
= se401
->height
[0];
979 struct video_channel
*v
= arg
;
985 v
->type
= VIDEO_TYPE_CAMERA
;
986 strcpy(v
->name
, "Camera");
991 struct video_channel
*v
= arg
;
999 struct video_picture
*p
= arg
;
1001 se401_get_pict(se401
, p
);
1006 struct video_picture
*p
= arg
;
1008 if (se401_set_pict(se401
, p
))
1014 struct video_window
*vw
= arg
;
1020 if (se401_set_size(se401
, vw
->width
, vw
->height
))
1026 struct video_window
*vw
= arg
;
1028 vw
->x
= 0; /* FIXME */
1033 vw
->width
= se401
->cwidth
;
1034 vw
->height
= se401
->cheight
;
1039 struct video_mbuf
*vm
= arg
;
1042 memset(vm
, 0, sizeof(*vm
));
1043 vm
->size
= SE401_NUMFRAMES
* se401
->maxframesize
;
1044 vm
->frames
= SE401_NUMFRAMES
;
1045 for (i
=0; i
<SE401_NUMFRAMES
; i
++)
1046 vm
->offsets
[i
] = se401
->maxframesize
* i
;
1049 case VIDIOCMCAPTURE
:
1051 struct video_mmap
*vm
= arg
;
1053 if (vm
->format
!= VIDEO_PALETTE_RGB24
)
1055 if (vm
->frame
>= SE401_NUMFRAMES
)
1057 if (se401
->frame
[vm
->frame
].grabstate
!= FRAME_UNUSED
)
1060 /* Is this according to the v4l spec??? */
1061 if (se401_set_size(se401
, vm
->width
, vm
->height
))
1063 se401
->frame
[vm
->frame
].grabstate
=FRAME_READY
;
1065 if (!se401
->streaming
)
1066 se401_start_stream(se401
);
1068 /* Set the picture properties */
1069 if (se401
->framecount
==0)
1070 se401_send_pict(se401
);
1071 /* Calibrate the reset level after a few frames. */
1072 if (se401
->framecount
%20==1)
1073 se401_auto_resetlevel(se401
);
1082 if(*frame
<0 || *frame
>= SE401_NUMFRAMES
)
1085 ret
=se401_newframe(se401
, *frame
);
1086 se401
->frame
[*frame
].grabstate
=FRAME_UNUSED
;
1091 struct video_buffer
*vb
= arg
;
1093 memset(vb
, 0, sizeof(*vb
));
1112 return -ENOIOCTLCMD
;
1118 static int se401_ioctl(struct inode
*inode
, struct file
*file
,
1119 unsigned int cmd
, unsigned long arg
)
1121 return video_usercopy(inode
, file
, cmd
, arg
, se401_do_ioctl
);
1124 static ssize_t
se401_read(struct file
*file
, char __user
*buf
,
1125 size_t count
, loff_t
*ppos
)
1127 int realcount
=count
, ret
=0;
1128 struct video_device
*dev
= file
->private_data
;
1129 struct usb_se401
*se401
= (struct usb_se401
*)dev
;
1132 if (se401
->dev
== NULL
)
1134 if (realcount
> se401
->cwidth
*se401
->cheight
*3)
1135 realcount
=se401
->cwidth
*se401
->cheight
*3;
1137 /* Shouldn't happen: */
1138 if (se401
->frame
[0].grabstate
==FRAME_GRABBING
)
1140 se401
->frame
[0].grabstate
=FRAME_READY
;
1141 se401
->frame
[1].grabstate
=FRAME_UNUSED
;
1144 if (!se401
->streaming
)
1145 se401_start_stream(se401
);
1147 /* Set the picture properties */
1148 if (se401
->framecount
==0)
1149 se401_send_pict(se401
);
1150 /* Calibrate the reset level after a few frames. */
1151 if (se401
->framecount
%20==1)
1152 se401_auto_resetlevel(se401
);
1154 ret
=se401_newframe(se401
, 0);
1156 se401
->frame
[0].grabstate
=FRAME_UNUSED
;
1159 if (copy_to_user(buf
, se401
->frame
[0].data
, realcount
))
1165 static int se401_mmap(struct file
*file
, struct vm_area_struct
*vma
)
1167 struct video_device
*dev
= file
->private_data
;
1168 struct usb_se401
*se401
= (struct usb_se401
*)dev
;
1169 unsigned long start
= vma
->vm_start
;
1170 unsigned long size
= vma
->vm_end
-vma
->vm_start
;
1171 unsigned long page
, pos
;
1175 if (se401
->dev
== NULL
) {
1179 if (size
> (((SE401_NUMFRAMES
* se401
->maxframesize
) + PAGE_SIZE
- 1) & ~(PAGE_SIZE
- 1))) {
1183 pos
= (unsigned long)se401
->fbuf
;
1185 page
= kvirt_to_pa(pos
);
1186 if (remap_page_range(vma
, start
, page
, PAGE_SIZE
, PAGE_SHARED
)) {
1192 if (size
> PAGE_SIZE
)
1202 static struct file_operations se401_fops
= {
1203 .owner
= THIS_MODULE
,
1205 .release
= se401_close
,
1208 .ioctl
= se401_ioctl
,
1209 .llseek
= no_llseek
,
1211 static struct video_device se401_template
= {
1212 .owner
= THIS_MODULE
,
1213 .name
= "se401 USB camera",
1214 .type
= VID_TYPE_CAPTURE
,
1215 .hardware
= VID_HARDWARE_SE401
,
1216 .fops
= &se401_fops
,
1221 /***************************/
1222 static int se401_init(struct usb_se401
*se401
, int button
)
1225 unsigned char cp
[0x40];
1229 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 1, NULL
, 0);
1231 /* get camera descriptor */
1232 rc
=se401_sndctrl(0, se401
, SE401_REQ_GET_CAMERA_DESCRIPTOR
, 0, cp
, sizeof(cp
));
1234 err("Wrong descriptor type");
1237 sprintf (temp
, "ExtraFeatures: %d", cp
[3]);
1239 se401
->sizes
=cp
[4]+cp
[5]*256;
1240 se401
->width
=kmalloc(se401
->sizes
*sizeof(int), GFP_KERNEL
);
1243 se401
->height
=kmalloc(se401
->sizes
*sizeof(int), GFP_KERNEL
);
1244 if (!se401
->height
) {
1245 kfree(se401
->width
);
1248 for (i
=0; i
<se401
->sizes
; i
++) {
1249 se401
->width
[i
]=cp
[6+i
*4+0]+cp
[6+i
*4+1]*256;
1250 se401
->height
[i
]=cp
[6+i
*4+2]+cp
[6+i
*4+3]*256;
1252 sprintf (temp
, "%s Sizes:", temp
);
1253 for (i
=0; i
<se401
->sizes
; i
++) {
1254 sprintf(temp
, "%s %dx%d", temp
, se401
->width
[i
], se401
->height
[i
]);
1257 se401
->maxframesize
=se401
->width
[se401
->sizes
-1]*se401
->height
[se401
->sizes
-1]*3;
1259 rc
=se401_sndctrl(0, se401
, SE401_REQ_GET_WIDTH
, 0, cp
, sizeof(cp
));
1260 se401
->cwidth
=cp
[0]+cp
[1]*256;
1261 rc
=se401_sndctrl(0, se401
, SE401_REQ_GET_HEIGHT
, 0, cp
, sizeof(cp
));
1262 se401
->cheight
=cp
[0]+cp
[1]*256;
1264 if (!cp
[2] && SE401_FORMAT_BAYER
) {
1265 err("Bayer format not supported!");
1268 /* set output mode (BAYER) */
1269 se401_sndctrl(1, se401
, SE401_REQ_SET_OUTPUT_MODE
, SE401_FORMAT_BAYER
, NULL
, 0);
1271 rc
=se401_sndctrl(0, se401
, SE401_REQ_GET_BRT
, 0, cp
, sizeof(cp
));
1272 se401
->brightness
=cp
[0]+cp
[1]*256;
1273 /* some default values */
1274 se401
->resetlevel
=0x2d;
1278 se401_set_exposure(se401
, 20000);
1279 se401
->palette
=VIDEO_PALETTE_RGB24
;
1283 se401
->framecount
=0;
1286 /* Start interrupt transfers for snapshot button */
1288 se401
->inturb
=usb_alloc_urb(0, GFP_KERNEL
);
1289 if (!se401
->inturb
) {
1290 info("Allocation of inturb failed");
1293 usb_fill_int_urb(se401
->inturb
, se401
->dev
,
1294 usb_rcvintpipe(se401
->dev
, SE401_BUTTON_ENDPOINT
),
1295 &se401
->button
, sizeof(se401
->button
),
1300 if (usb_submit_urb(se401
->inturb
, GFP_KERNEL
)) {
1301 info("int urb burned down");
1308 se401_sndctrl(1, se401
, SE401_REQ_CAMERA_POWER
, 1, NULL
, 0);
1309 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 1, NULL
, 0);
1310 se401_sndctrl(1, se401
, SE401_REQ_CAMERA_POWER
, 0, NULL
, 0);
1311 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 0, NULL
, 0);
1316 static int se401_probe(struct usb_interface
*intf
,
1317 const struct usb_device_id
*id
)
1319 struct usb_device
*dev
= interface_to_usbdev(intf
);
1320 struct usb_interface_descriptor
*interface
;
1321 struct usb_se401
*se401
;
1322 char *camera_name
=NULL
;
1325 /* We don't handle multi-config cameras */
1326 if (dev
->descriptor
.bNumConfigurations
!= 1)
1329 interface
= &intf
->cur_altsetting
->desc
;
1331 /* Is it an se401? */
1332 if (dev
->descriptor
.idVendor
== 0x03e8 &&
1333 dev
->descriptor
.idProduct
== 0x0004) {
1334 camera_name
="Endpoints/Aox SE401";
1335 } else if (dev
->descriptor
.idVendor
== 0x0471 &&
1336 dev
->descriptor
.idProduct
== 0x030b) {
1337 camera_name
="Philips PCVC665K";
1338 } else if (dev
->descriptor
.idVendor
== 0x047d &&
1339 dev
->descriptor
.idProduct
== 0x5001) {
1340 camera_name
="Kensington VideoCAM 67014";
1341 } else if (dev
->descriptor
.idVendor
== 0x047d &&
1342 dev
->descriptor
.idProduct
== 0x5002) {
1343 camera_name
="Kensington VideoCAM 6701(5/7)";
1344 } else if (dev
->descriptor
.idVendor
== 0x047d &&
1345 dev
->descriptor
.idProduct
== 0x5003) {
1346 camera_name
="Kensington VideoCAM 67016";
1351 /* Checking vendor/product should be enough, but what the hell */
1352 if (interface
->bInterfaceClass
!= 0x00)
1354 if (interface
->bInterfaceSubClass
!= 0x00)
1358 info("SE401 camera found: %s", camera_name
);
1360 if ((se401
= kmalloc(sizeof(*se401
), GFP_KERNEL
)) == NULL
) {
1361 err("couldn't kmalloc se401 struct");
1365 memset(se401
, 0, sizeof(*se401
));
1368 se401
->iface
= interface
->bInterfaceNumber
;
1369 se401
->camera_name
= camera_name
;
1371 info("firmware version: %02x", dev
->descriptor
.bcdDevice
& 255);
1373 if (se401_init(se401
, button
)) {
1378 memcpy(&se401
->vdev
, &se401_template
, sizeof(se401_template
));
1379 memcpy(se401
->vdev
.name
, se401
->camera_name
, strlen(se401
->camera_name
));
1380 init_waitqueue_head(&se401
->wq
);
1381 init_MUTEX(&se401
->lock
);
1384 if (video_register_device(&se401
->vdev
, VFL_TYPE_GRABBER
, video_nr
) == -1) {
1386 err("video_register_device failed");
1389 info("registered new video device: video%d", se401
->vdev
.minor
);
1391 usb_set_intfdata (intf
, se401
);
1395 static void se401_disconnect(struct usb_interface
*intf
)
1397 struct usb_se401
*se401
= usb_get_intfdata (intf
);
1399 usb_set_intfdata (intf
, NULL
);
1401 video_unregister_device(&se401
->vdev
);
1403 usb_se401_remove_disconnected(se401
);
1405 se401
->frame
[0].grabstate
= FRAME_ERROR
;
1406 se401
->frame
[0].grabstate
= FRAME_ERROR
;
1408 se401
->streaming
= 0;
1410 wake_up_interruptible(&se401
->wq
);
1416 static struct usb_driver se401_driver
= {
1417 .owner
= THIS_MODULE
,
1419 .id_table
= device_table
,
1420 .probe
= se401_probe
,
1421 .disconnect
= se401_disconnect
,
1426 /****************************************************************************
1430 ***************************************************************************/
1432 static int __init
usb_se401_init(void)
1434 info("SE401 usb camera driver version %s registering", version
);
1436 if (flickerless
!=50 && flickerless
!=60) {
1437 info("Invallid flickerless value, use 0, 50 or 60.");
1440 return usb_register(&se401_driver
);
1443 static void __exit
usb_se401_exit(void)
1445 usb_deregister(&se401_driver
);
1446 info("SE401 driver deregistered");
1449 module_init(usb_se401_init
);
1450 module_exit(usb_se401_exit
);