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.23";
30 #include <linux/config.h>
31 #include <linux/module.h>
32 #include <linux/version.h>
33 #include <linux/init.h>
35 #include <linux/vmalloc.h>
36 #include <linux/slab.h>
37 #include <linux/proc_fs.h>
38 #include <linux/pagemap.h>
39 #include <linux/usb.h>
41 #include <asm/semaphore.h>
42 #include <linux/wrapper.h>
46 static int flickerless
=0;
47 static int video_nr
= -1;
49 static struct usb_device_id device_table
[] = {
50 { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
51 { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
52 { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
53 { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
54 { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
58 MODULE_DEVICE_TABLE(usb
, device_table
);
60 MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
61 MODULE_DESCRIPTION("SE401 USB Camera Driver");
62 MODULE_LICENSE("GPL");
63 MODULE_PARM(flickerless
, "i");
64 MODULE_PARM_DESC(flickerless
, "Net frequency to adjust exposure time to (0/50/60)");
65 MODULE_PARM(video_nr
, "i");
69 static struct usb_driver se401_driver
;
72 /**********************************************************************
76 **********************************************************************/
78 /* Here we want the physical address of the memory.
79 * This is used when initializing the contents of the area.
81 static inline unsigned long kvirt_to_pa(unsigned long adr
)
83 unsigned long kva
, ret
;
85 kva
= (unsigned long) page_address(vmalloc_to_page((void *)adr
));
86 kva
|= adr
& (PAGE_SIZE
-1); /* restore the offset */
91 static void *rvmalloc(unsigned long size
)
96 size
= PAGE_ALIGN(size
);
97 mem
= vmalloc_32(size
);
101 memset(mem
, 0, size
); /* Clear the ram out, no junk to the user */
102 adr
= (unsigned long) mem
;
104 mem_map_reserve(vmalloc_to_page((void *)adr
));
112 static void rvfree(void *mem
, unsigned long size
)
119 adr
= (unsigned long) mem
;
120 while ((long) size
> 0) {
121 mem_map_unreserve(vmalloc_to_page((void *)adr
));
130 /****************************************************************************
134 ***************************************************************************/
136 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
138 static struct proc_dir_entry
*se401_proc_entry
= NULL
;
139 extern struct proc_dir_entry
*video_proc_entry
;
141 #define YES_NO(x) ((x) ? "yes" : "no")
143 static int se401_read_proc(char *page
, char **start
, off_t off
, int count
,
144 int *eof
, void *data
)
148 struct usb_se401
*se401
= data
;
150 /* Stay under PAGE_SIZE or else bla bla bla.... */
152 out
+=sprintf(out
, "driver_version : %s\n", version
);
153 out
+=sprintf(out
, "model : %s\n", se401
->camera_name
);
154 out
+=sprintf(out
, "in use : %s\n", YES_NO (se401
->user
));
155 out
+=sprintf(out
, "streaming : %s\n", YES_NO (se401
->streaming
));
156 out
+=sprintf(out
, "button state : %s\n", YES_NO (se401
->button
));
157 out
+=sprintf(out
, "button pressed : %s\n", YES_NO (se401
->buttonpressed
));
158 out
+=sprintf(out
, "num_frames : %d\n", SE401_NUMFRAMES
);
160 out
+=sprintf(out
, "Sizes :");
161 for (i
=0; i
<se401
->sizes
; i
++) {
162 out
+=sprintf(out
, " %dx%d", se401
->width
[i
],
165 out
+=sprintf(out
, "\n");
167 out
+=sprintf(out
, "Frames total : %d\n", se401
->readcount
);
168 out
+=sprintf(out
, "Frames read : %d\n", se401
->framecount
);
169 out
+=sprintf(out
, "Packets dropped : %d\n", se401
->dropped
);
170 out
+=sprintf(out
, "Decoding Errors : %d\n", se401
->error
);
176 if (len
<= 0) return 0;
185 static int se401_write_proc(struct file
*file
, const char *buffer
,
186 unsigned long count
, void *data
)
191 static void create_proc_se401_cam (struct usb_se401
*se401
)
194 struct proc_dir_entry
*ent
;
196 if (!se401_proc_entry
|| !se401
)
199 sprintf (name
, "video%d", se401
->vdev
.minor
);
201 ent
= create_proc_entry(name
, S_IFREG
| S_IRUGO
| S_IWUSR
,
208 ent
->read_proc
= se401_read_proc
;
209 ent
->write_proc
= se401_write_proc
;
210 se401
->proc_entry
= ent
;
213 static void destroy_proc_se401_cam (struct usb_se401
*se401
)
215 /* One to much, just to be sure :) */
218 if (!se401
|| !se401
->proc_entry
)
221 sprintf(name
, "video%d", se401
->vdev
.minor
);
222 remove_proc_entry(name
, se401_proc_entry
);
223 se401
->proc_entry
= NULL
;
226 static void proc_se401_create (void)
228 if (video_proc_entry
== NULL
) {
229 err("/proc/video/ doesn't exist");
233 se401_proc_entry
=create_proc_entry("se401", S_IFDIR
, video_proc_entry
);
235 if (se401_proc_entry
)
236 se401_proc_entry
->owner
= THIS_MODULE
;
238 err("Unable to initialize /proc/video/se401");
241 static void proc_se401_destroy(void)
243 if (se401_proc_entry
== NULL
)
246 remove_proc_entry("se401", video_proc_entry
);
248 #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
251 /****************************************************************************
253 * se401 register read/write functions
255 ***************************************************************************/
257 static int se401_sndctrl(int set
, struct usb_se401
*se401
, unsigned short req
,
258 unsigned short value
, unsigned char *cp
, int size
)
260 return usb_control_msg (
262 set
? usb_sndctrlpipe(se401
->dev
, 0) : usb_rcvctrlpipe(se401
->dev
, 0),
264 (set
? USB_DIR_OUT
: USB_DIR_IN
) | USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
273 static int se401_set_feature(struct usb_se401
*se401
, unsigned short selector
,
274 unsigned short param
)
276 /* specs say that the selector (address) should go in the value field
277 and the param in index, but in the logs of the windows driver they do
278 this the other way around...
280 return usb_control_msg (
282 usb_sndctrlpipe(se401
->dev
, 0),
283 SE401_REQ_SET_EXT_FEATURE
,
284 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
293 static unsigned short se401_get_feature(struct usb_se401
*se401
,
294 unsigned short selector
)
296 /* For 'set' the selecetor should be in index, not sure if the spec is
302 usb_rcvctrlpipe(se401
->dev
, 0),
303 SE401_REQ_GET_EXT_FEATURE
,
304 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_DEVICE
,
311 return cp
[0]+cp
[1]*256;
314 /****************************************************************************
318 ***************************************************************************/
321 static int se401_send_pict(struct usb_se401
*se401
)
323 se401_set_feature(se401
, HV7131_REG_TITL
, se401
->expose_l
);/* integration time low */
324 se401_set_feature(se401
, HV7131_REG_TITM
, se401
->expose_m
);/* integration time mid */
325 se401_set_feature(se401
, HV7131_REG_TITU
, se401
->expose_h
);/* integration time mid */
326 se401_set_feature(se401
, HV7131_REG_ARLV
, se401
->resetlevel
);/* reset level value */
327 se401_set_feature(se401
, HV7131_REG_ARCG
, se401
->rgain
);/* red color gain */
328 se401_set_feature(se401
, HV7131_REG_AGCG
, se401
->ggain
);/* green color gain */
329 se401_set_feature(se401
, HV7131_REG_ABCG
, se401
->bgain
);/* blue color gain */
334 static void se401_set_exposure(struct usb_se401
*se401
, int brightness
)
336 int integration
=brightness
<<5;
338 if (flickerless
==50) {
339 integration
=integration
-integration
%106667;
341 if (flickerless
==60) {
342 integration
=integration
-integration
%88889;
344 se401
->brightness
=integration
>>5;
345 se401
->expose_h
=(integration
>>16)&0xff;
346 se401
->expose_m
=(integration
>>8)&0xff;
347 se401
->expose_l
=integration
&0xff;
350 static int se401_get_pict(struct usb_se401
*se401
, struct video_picture
*p
)
352 p
->brightness
=se401
->brightness
;
353 if (se401
->enhance
) {
360 p
->hue
=se401
->rgain
<<10;
361 p
->palette
=se401
->palette
;
362 p
->depth
=3; /* rgb24 */
367 static int se401_set_pict(struct usb_se401
*se401
, struct video_picture
*p
)
369 if (p
->palette
!= VIDEO_PALETTE_RGB24
)
371 se401
->palette
=p
->palette
;
372 if (p
->hue
!=se401
->hue
) {
373 se401
->rgain
= p
->hue
>>10;
374 se401
->bgain
= 0x40-(p
->hue
>>10);
377 if (p
->brightness
!=se401
->brightness
) {
378 se401_set_exposure(se401
, p
->brightness
);
380 if (p
->whiteness
>=32768) {
385 se401_send_pict(se401
);
386 se401_send_pict(se401
);
391 Hyundai have some really nice docs about this and other sensor related
392 stuff on their homepage: www.hei.co.kr
394 static void se401_auto_resetlevel(struct usb_se401
*se401
)
396 unsigned int ahrc
, alrc
;
397 int oldreset
=se401
->resetlevel
;
399 /* For some reason this normally read-only register doesn't get reset
400 to zero after reading them just once...
402 se401_get_feature(se401
, HV7131_REG_HIREFNOH
);
403 se401_get_feature(se401
, HV7131_REG_HIREFNOL
);
404 se401_get_feature(se401
, HV7131_REG_LOREFNOH
);
405 se401_get_feature(se401
, HV7131_REG_LOREFNOL
);
406 ahrc
=256*se401_get_feature(se401
, HV7131_REG_HIREFNOH
) +
407 se401_get_feature(se401
, HV7131_REG_HIREFNOL
);
408 alrc
=256*se401_get_feature(se401
, HV7131_REG_LOREFNOH
) +
409 se401_get_feature(se401
, HV7131_REG_LOREFNOL
);
411 /* Not an exact science, but it seems to work pretty well... */
413 while (alrc
>=10 && se401
->resetlevel
< 63) {
417 } else if (ahrc
> 20) {
418 while (ahrc
>=20 && se401
->resetlevel
> 0) {
423 if (se401
->resetlevel
!=oldreset
)
424 se401_set_feature(se401
, HV7131_REG_ARLV
, se401
->resetlevel
);
429 /* irq handler for snapshot button */
430 static void se401_button_irq(struct urb
*urb
)
432 struct usb_se401
*se401
= urb
->context
;
435 info("ohoh: device vapourished");
439 if (urb
->actual_length
>=2 && !urb
->status
) {
441 se401
->buttonpressed
=1;
445 static void se401_video_irq(struct urb
*urb
)
447 struct usb_se401
*se401
= urb
->context
;
448 int length
= urb
->actual_length
;
451 if (!se401
->streaming
)
455 info ("ohoh: device vapourished");
459 /* 0 sized packets happen if we are to fast, but sometimes the camera
460 keeps sending them forever...
462 if (length
&& !urb
->status
) {
463 se401
->nullpackets
=0;
464 switch(se401
->scratch
[se401
->scratch_next
].state
) {
470 case BUFFER_UNUSED
: {
471 memcpy(se401
->scratch
[se401
->scratch_next
].data
, (unsigned char *)urb
->transfer_buffer
, length
);
472 se401
->scratch
[se401
->scratch_next
].state
=BUFFER_READY
;
473 se401
->scratch
[se401
->scratch_next
].offset
=se401
->bayeroffset
;
474 se401
->scratch
[se401
->scratch_next
].length
=length
;
475 if (waitqueue_active(&se401
->wq
)) {
476 wake_up_interruptible(&se401
->wq
);
478 se401
->scratch_overflow
=0;
479 se401
->scratch_next
++;
480 if (se401
->scratch_next
>=SE401_NUMSCRATCH
)
481 se401
->scratch_next
=0;;
485 se401
->bayeroffset
+=length
;
486 if (se401
->bayeroffset
>=se401
->cheight
*se401
->cwidth
) {
487 se401
->bayeroffset
=0;
490 se401
->nullpackets
++;
491 if (se401
->nullpackets
> SE401_MAX_NULLPACKETS
) {
492 if (waitqueue_active(&se401
->wq
)) {
493 wake_up_interruptible(&se401
->wq
);
498 /* Resubmit urb for new data */
501 if(usb_submit_urb(urb
))
502 info("urb burned down");
506 static void se401_send_size(struct usb_se401
*se401
, int width
, int height
)
509 int mode
=0x03; /* No compression */
510 int sendheight
=height
;
513 /* JangGu compression can only be used with the camera supported sizes,
514 but bayer seems to work with any size that fits on the sensor.
515 We check if we can use compression with the current size with either
516 4 or 16 times subcapturing, if not we use uncompressed bayer data
517 but this will result in cutouts of the maximum size....
519 while (i
<se401
->sizes
&& !(se401
->width
[i
]==width
&& se401
->height
[i
]==height
))
521 while (i
<se401
->sizes
) {
522 if (se401
->width
[i
]==width
*2 && se401
->height
[i
]==height
*2) {
523 sendheight
=se401
->height
[i
];
524 sendwidth
=se401
->width
[i
];
527 if (se401
->width
[i
]==width
*4 && se401
->height
[i
]==height
*4) {
528 sendheight
=se401
->height
[i
];
529 sendwidth
=se401
->width
[i
];
535 se401_sndctrl(1, se401
, SE401_REQ_SET_WIDTH
, sendwidth
, NULL
, 0);
536 se401_sndctrl(1, se401
, SE401_REQ_SET_HEIGHT
, sendheight
, NULL
, 0);
537 se401_set_feature(se401
, SE401_OPERATINGMODE
, mode
);
540 se401
->format
=FMT_BAYER
;
542 se401
->format
=FMT_JANGGU
;
549 In this function se401_send_pict is called several times,
550 for some reason (depending on the state of the sensor and the phase of
551 the moon :) doing this only in either place doesn't always work...
553 static int se401_start_stream(struct usb_se401
*se401
)
559 se401_sndctrl(1, se401
, SE401_REQ_CAMERA_POWER
, 1, NULL
, 0);
560 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 1, NULL
, 0);
562 /* Set picture settings */
563 se401_set_feature(se401
, HV7131_REG_MODE_B
, 0x05);/*windowed + pix intg */
564 se401_send_pict(se401
);
566 se401_send_size(se401
, se401
->cwidth
, se401
->cheight
);
568 se401_sndctrl(1, se401
, SE401_REQ_START_CONTINUOUS_CAPTURE
, 0, NULL
, 0);
570 /* Do some memory allocation */
571 for (i
=0; i
<SE401_NUMFRAMES
; i
++) {
572 se401
->frame
[i
].data
=se401
->fbuf
+ i
* se401
->maxframesize
;
573 se401
->frame
[i
].curpix
=0;
575 for (i
=0; i
<SE401_NUMSBUF
; i
++) {
576 se401
->sbuf
[i
].data
=kmalloc(SE401_PACKETSIZE
, GFP_KERNEL
);
579 se401
->bayeroffset
=0;
580 se401
->scratch_next
=0;
581 se401
->scratch_use
=0;
582 se401
->scratch_overflow
=0;
583 for (i
=0; i
<SE401_NUMSCRATCH
; i
++) {
584 se401
->scratch
[i
].data
=kmalloc(SE401_PACKETSIZE
, GFP_KERNEL
);
585 se401
->scratch
[i
].state
=BUFFER_UNUSED
;
588 for (i
=0; i
<SE401_NUMSBUF
; i
++) {
589 urb
=usb_alloc_urb(0);
593 FILL_BULK_URB(urb
, se401
->dev
,
594 usb_rcvbulkpipe(se401
->dev
, SE401_VIDEO_ENDPOINT
),
595 se401
->sbuf
[i
].data
, SE401_PACKETSIZE
,
598 urb
->transfer_flags
|= USB_QUEUE_BULK
;
602 err
=usb_submit_urb(se401
->urb
[i
]);
604 err("urb burned down");
612 static int se401_stop_stream(struct usb_se401
*se401
)
616 if (!se401
->streaming
|| !se401
->dev
)
621 se401_sndctrl(1, se401
, SE401_REQ_STOP_CONTINUOUS_CAPTURE
, 0, NULL
, 0);
623 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 0, NULL
, 0);
624 se401_sndctrl(1, se401
, SE401_REQ_CAMERA_POWER
, 0, NULL
, 0);
626 for (i
=0; i
<SE401_NUMSBUF
; i
++) if (se401
->urb
[i
]) {
627 se401
->urb
[i
]->next
=NULL
;
628 usb_unlink_urb(se401
->urb
[i
]);
629 usb_free_urb(se401
->urb
[i
]);
631 kfree(se401
->sbuf
[i
].data
);
633 for (i
=0; i
<SE401_NUMSCRATCH
; i
++) {
634 kfree(se401
->scratch
[i
].data
);
635 se401
->scratch
[i
].data
=NULL
;
641 static int se401_set_size(struct usb_se401
*se401
, int width
, int height
)
643 int wasstreaming
=se401
->streaming
;
644 /* Check to see if we need to change */
645 if (se401
->cwidth
==width
&& se401
->cheight
==height
)
648 /* Check for a valid mode */
649 if (width
<= 0 || height
<= 0)
651 if ((width
& 1) || (height
& 1))
653 if (width
>se401
->width
[se401
->sizes
-1])
655 if (height
>se401
->height
[se401
->sizes
-1])
658 /* Stop a current stream and start it again at the new size */
660 se401_stop_stream(se401
);
662 se401
->cheight
=height
;
664 se401_start_stream(se401
);
669 /****************************************************************************
673 ***************************************************************************/
676 This shouldn't really be done in a v4l driver....
677 But it does make the image look a lot more usable.
678 Basicly it lifts the dark pixels more than the light pixels.
680 static inline void enhance_picture(unsigned char *frame
, int len
)
683 *frame
=(((*frame
^255)*(*frame
^255))/255)^255;
688 static inline void decode_JangGu_integrate(struct usb_se401
*se401
, int data
)
690 struct se401_frame
*frame
=&se401
->frame
[se401
->curframe
];
691 int linelength
=se401
->cwidth
*3;
693 if (frame
->curlinepix
>= linelength
) {
695 frame
->curline
+=linelength
;
698 /* First three are absolute, all others relative.
699 * Format is rgb from right to left (mirrorred image),
700 * we flip it to get bgr from left to right. */
701 if (frame
->curlinepix
< 3) {
702 *(frame
->curline
-frame
->curlinepix
)=1+data
*4;
704 *(frame
->curline
-frame
->curlinepix
)=
705 *(frame
->curline
-frame
->curlinepix
+3)+data
*4;
710 static inline void decode_JangGu_vlc (struct usb_se401
*se401
, unsigned char *data
, int bit_exp
, int packetlength
)
719 while (pos
< packetlength
) {
721 while (bit_cur
&& bit_exp
) {
722 bit
=((*data
)>>(bit_cur
-1))&1;
728 decode_JangGu_integrate(se401
, 0);
736 if (!bit
) vlc_data
=-(1<<vlc_size
)+1;
740 vlc_data
+=bit
<<vlc_size
;
742 decode_JangGu_integrate(se401
, vlc_data
);
754 static inline void decode_JangGu (struct usb_se401
*se401
, struct se401_scratch
*buffer
)
756 unsigned char *data
=buffer
->data
;
757 int len
=buffer
->length
;
758 int bit_exp
=0, pix_exp
=0, frameinfo
=0, packetlength
=0, size
;
762 if (!se401
->frame
[se401
->curframe
].curpix
) {
763 se401
->frame
[se401
->curframe
].curlinepix
=0;
764 se401
->frame
[se401
->curframe
].curline
=
765 se401
->frame
[se401
->curframe
].data
+
767 if (se401
->frame
[se401
->curframe
].grabstate
==FRAME_READY
)
768 se401
->frame
[se401
->curframe
].grabstate
=FRAME_GRABBING
;
771 while (datapos
< len
) {
772 size
=1024-se401
->vlcdatapos
;
773 if (size
+datapos
> len
)
775 memcpy(se401
->vlcdata
+se401
->vlcdatapos
, data
+datapos
, size
);
776 se401
->vlcdatapos
+=size
;
778 if (se401
->vlcdatapos
>= 4) {
779 bit_exp
=se401
->vlcdata
[3]+(se401
->vlcdata
[2]<<8);
780 pix_exp
=se401
->vlcdata
[1]+((se401
->vlcdata
[0]&0x3f)<<8);
781 frameinfo
=se401
->vlcdata
[0]&0xc0;
782 packetlength
=((bit_exp
+47)>>4)<<1;
783 if (packetlength
> 1024) {
788 se401
->frame
[se401
->curframe
].curpix
=0;
791 if (packetlength
&& se401
->vlcdatapos
>= packetlength
) {
792 decode_JangGu_vlc(se401
, se401
->vlcdata
, bit_exp
, packetlength
);
793 se401
->frame
[se401
->curframe
].curpix
+=pix_exp
*3;
794 datapos
+=size
-(se401
->vlcdatapos
-packetlength
);
796 if (se401
->frame
[se401
->curframe
].curpix
>=se401
->cwidth
*se401
->cheight
*3) {
797 if (se401
->frame
[se401
->curframe
].curpix
==se401
->cwidth
*se401
->cheight
*3) {
798 if (se401
->frame
[se401
->curframe
].grabstate
==FRAME_GRABBING
) {
799 se401
->frame
[se401
->curframe
].grabstate
=FRAME_DONE
;
803 if (se401
->frame
[(se401
->curframe
+1)&(SE401_NUMFRAMES
-1)].grabstate
==FRAME_READY
) {
804 se401
->curframe
=(se401
->curframe
+1) & (SE401_NUMFRAMES
-1);
809 se401
->frame
[se401
->curframe
].curpix
=0;
818 static inline void decode_bayer (struct usb_se401
*se401
, struct se401_scratch
*buffer
)
820 unsigned char *data
=buffer
->data
;
821 int len
=buffer
->length
;
822 int offset
=buffer
->offset
;
823 int datasize
=se401
->cwidth
*se401
->cheight
;
824 struct se401_frame
*frame
=&se401
->frame
[se401
->curframe
];
826 unsigned char *framedata
=frame
->data
, *curline
, *nextline
;
827 int width
=se401
->cwidth
;
828 int blineoffset
=0, bline
;
829 int linelength
=width
*3, i
;
832 if (frame
->curpix
==0) {
833 if (frame
->grabstate
==FRAME_READY
) {
834 frame
->grabstate
=FRAME_GRABBING
;
836 frame
->curline
=framedata
+linelength
;
840 if (offset
!=frame
->curpix
) {
841 /* Regard frame as lost :( */
847 /* Check if we have to much data */
848 if (frame
->curpix
+len
> datasize
) {
849 len
=datasize
-frame
->curpix
;
851 if (se401
->cheight
%4)
853 bline
=frame
->curpix
/se401
->cwidth
+blineoffset
;
855 curline
=frame
->curline
;
856 nextline
=curline
+linelength
;
857 if (nextline
>= framedata
+datasize
*3)
860 if (frame
->curlinepix
>=width
) {
861 frame
->curlinepix
-=width
;
862 bline
=frame
->curpix
/width
+blineoffset
;
863 curline
+=linelength
*2;
864 nextline
+=linelength
*2;
865 if (curline
>= framedata
+datasize
*3) {
873 if (nextline
>= framedata
+datasize
*3)
877 if ((frame
->curlinepix
&1)) {
884 (*(curline
+1)+*data
)/2;
886 (*(curline
-2)+*data
)/2;
891 if ((frame
->curlinepix
&1)) {
893 (*(curline
+1)+*data
)/2;
895 (*(curline
-2)+*data
)/2;
912 frame
->curline
=curline
;
914 if (frame
->curpix
>=datasize
) {
915 /* Fix the top line */
916 framedata
+=linelength
;
917 for (i
=0; i
<linelength
; i
++) {
919 *framedata
=*(framedata
+linelength
);
921 /* Fix the left side (green is already present) */
922 for (i
=0; i
<se401
->cheight
; i
++) {
923 *framedata
=*(framedata
+3);
924 *(framedata
+1)=*(framedata
+4);
925 *(framedata
+2)=*(framedata
+5);
926 framedata
+=linelength
;
929 frame
->grabstate
=FRAME_DONE
;
932 if (se401
->frame
[(se401
->curframe
+1)&(SE401_NUMFRAMES
-1)].grabstate
==FRAME_READY
) {
933 se401
->curframe
=(se401
->curframe
+1) & (SE401_NUMFRAMES
-1);
938 static int se401_newframe(struct usb_se401
*se401
, int framenr
)
940 DECLARE_WAITQUEUE(wait
, current
);
943 while (se401
->streaming
&&
944 (se401
->frame
[framenr
].grabstate
==FRAME_READY
||
945 se401
->frame
[framenr
].grabstate
==FRAME_GRABBING
) ) {
946 if(!se401
->frame
[framenr
].curpix
) {
950 se401
->scratch
[se401
->scratch_use
].state
!=BUFFER_READY
,
954 if (se401
->nullpackets
> SE401_MAX_NULLPACKETS
) {
955 se401
->nullpackets
=0;
956 info("to many null length packets, restarting capture");
957 se401_stop_stream(se401
);
958 se401_start_stream(se401
);
960 if (se401
->scratch
[se401
->scratch_use
].state
!=BUFFER_READY
) {
961 se401
->frame
[framenr
].grabstate
=FRAME_ERROR
;
964 se401
->scratch
[se401
->scratch_use
].state
=BUFFER_BUSY
;
965 if (se401
->format
==FMT_JANGGU
) {
966 decode_JangGu(se401
, &se401
->scratch
[se401
->scratch_use
]);
968 decode_bayer(se401
, &se401
->scratch
[se401
->scratch_use
]);
970 se401
->scratch
[se401
->scratch_use
].state
=BUFFER_UNUSED
;
971 se401
->scratch_use
++;
972 if (se401
->scratch_use
>=SE401_NUMSCRATCH
)
973 se401
->scratch_use
=0;
974 if (errors
> SE401_MAX_ERRORS
) {
976 info("to much errors, restarting capture");
977 se401_stop_stream(se401
);
978 se401_start_stream(se401
);
983 if (se401
->frame
[framenr
].grabstate
==FRAME_DONE
)
985 enhance_picture(se401
->frame
[framenr
].data
, se401
->cheight
*se401
->cwidth
*3);
989 static inline void usb_se401_remove_disconnected (struct usb_se401
*se401
)
994 se401
->frame
[0].grabstate
= FRAME_ERROR
;
995 se401
->frame
[1].grabstate
= FRAME_ERROR
;
997 se401
->streaming
= 0;
999 wake_up_interruptible(&se401
->wq
);
1001 for (i
=0; i
<SE401_NUMSBUF
; i
++) if (se401
->urb
[i
]) {
1002 se401
->urb
[i
]->next
= NULL
;
1003 usb_unlink_urb(se401
->urb
[i
]);
1004 usb_free_urb(se401
->urb
[i
]);
1005 se401
->urb
[i
] = NULL
;
1006 kfree(se401
->sbuf
[i
].data
);
1008 for (i
=0; i
<SE401_NUMSCRATCH
; i
++) if (se401
->scratch
[i
].data
) {
1009 kfree(se401
->scratch
[i
].data
);
1011 if (se401
->inturb
) {
1012 usb_unlink_urb(se401
->inturb
);
1013 usb_free_urb(se401
->inturb
);
1015 info("%s disconnected", se401
->camera_name
);
1017 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1018 destroy_proc_se401_cam(se401
);
1021 /* Free the memory */
1022 kfree(se401
->width
);
1023 kfree(se401
->height
);
1028 /****************************************************************************
1032 ***************************************************************************/
1035 static int se401_open(struct video_device
*dev
, int flags
)
1037 struct usb_se401
*se401
= (struct usb_se401
*)dev
;
1040 /* we are called with the BKL held */
1044 se401
->fbuf
=rvmalloc(se401
->maxframesize
* SE401_NUMFRAMES
);
1045 if(!se401
->fbuf
) err
=-ENOMEM
;
1055 static void se401_close(struct video_device
*dev
)
1057 /* called with BKL held */
1058 struct usb_se401
*se401
= (struct usb_se401
*)dev
;
1061 for (i
=0; i
<SE401_NUMFRAMES
; i
++)
1062 se401
->frame
[i
].grabstate
=FRAME_UNUSED
;
1063 if (se401
->streaming
)
1064 se401_stop_stream(se401
);
1066 rvfree(se401
->fbuf
, se401
->maxframesize
* SE401_NUMFRAMES
);
1069 if (se401
->removed
) {
1070 video_unregister_device(&se401
->vdev
);
1071 kfree(se401
->width
);
1072 kfree(se401
->height
);
1075 info("device unregistered");
1081 static int se401_init_done(struct video_device
*dev
)
1083 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1084 create_proc_se401_cam((struct usb_se401
*)dev
);
1090 static long se401_write(struct video_device
*dev
, const char *buf
, unsigned long
1096 static int se401_ioctl(struct video_device
*vdev
, unsigned int cmd
, void *arg
)
1098 struct usb_se401
*se401
= (struct usb_se401
*)vdev
;
1106 struct video_capability b
;
1107 strcpy(b
.name
, se401
->camera_name
);
1108 b
.type
= VID_TYPE_CAPTURE
;
1111 b
.maxwidth
= se401
->width
[se401
->sizes
-1];
1112 b
.maxheight
= se401
->height
[se401
->sizes
-1];
1113 b
.minwidth
= se401
->width
[0];
1114 b
.minheight
= se401
->height
[0];
1116 if (copy_to_user(arg
, &b
, sizeof(b
)))
1123 struct video_channel v
;
1125 if (copy_from_user(&v
, arg
, sizeof(v
)))
1132 v
.type
= VIDEO_TYPE_CAMERA
;
1133 strcpy(v
.name
, "Camera");
1135 if (copy_to_user(arg
, &v
, sizeof(v
)))
1144 if (copy_from_user(&v
, arg
, sizeof(v
)))
1154 struct video_picture p
;
1156 se401_get_pict(se401
, &p
);
1158 if (copy_to_user(arg
, &p
, sizeof(p
)))
1164 struct video_picture p
;
1166 if (copy_from_user(&p
, arg
, sizeof(p
)))
1169 if (se401_set_pict(se401
, &p
))
1175 struct video_window vw
;
1177 if (copy_from_user(&vw
, arg
, sizeof(vw
)))
1183 if (se401_set_size(se401
, vw
.width
, vw
.height
))
1190 struct video_window vw
;
1192 vw
.x
= 0; /* FIXME */
1197 vw
.width
= se401
->cwidth
;
1198 vw
.height
= se401
->cheight
;
1200 if (copy_to_user(arg
, &vw
, sizeof(vw
)))
1207 struct video_mbuf vm
;
1210 memset(&vm
, 0, sizeof(vm
));
1211 vm
.size
= SE401_NUMFRAMES
* se401
->maxframesize
;
1212 vm
.frames
= SE401_NUMFRAMES
;
1213 for (i
=0; i
<SE401_NUMFRAMES
; i
++)
1214 vm
.offsets
[i
] = se401
->maxframesize
* i
;
1216 if (copy_to_user((void *)arg
, (void *)&vm
, sizeof(vm
)))
1221 case VIDIOCMCAPTURE
:
1223 struct video_mmap vm
;
1225 if (copy_from_user(&vm
, arg
, sizeof(vm
)))
1227 if (vm
.format
!= VIDEO_PALETTE_RGB24
)
1229 if (vm
.frame
>= SE401_NUMFRAMES
)
1231 if (se401
->frame
[vm
.frame
].grabstate
!= FRAME_UNUSED
)
1234 /* Is this according to the v4l spec??? */
1235 if (se401_set_size(se401
, vm
.width
, vm
.height
))
1237 se401
->frame
[vm
.frame
].grabstate
=FRAME_READY
;
1239 if (!se401
->streaming
)
1240 se401_start_stream(se401
);
1242 /* Set the picture properties */
1243 if (se401
->framecount
==0)
1244 se401_send_pict(se401
);
1245 /* Calibrate the reset level after a few frames. */
1246 if (se401
->framecount
%20==1)
1247 se401_auto_resetlevel(se401
);
1255 if (copy_from_user((void *)&frame
, arg
, sizeof(int)))
1258 if(frame
<0 || frame
>= SE401_NUMFRAMES
)
1261 ret
=se401_newframe(se401
, frame
);
1262 se401
->frame
[frame
].grabstate
=FRAME_UNUSED
;
1267 struct video_buffer vb
;
1269 memset(&vb
, 0, sizeof(vb
));
1270 vb
.base
= NULL
; /* frame buffer not supported, not used */
1272 if (copy_to_user((void *)arg
, (void *)&vb
, sizeof(vb
)))
1293 return -ENOIOCTLCMD
;
1299 static long se401_read(struct video_device
*dev
, char *buf
, unsigned long count
,
1302 int realcount
=count
, ret
=0;
1303 struct usb_se401
*se401
= (struct usb_se401
*)dev
;
1306 if (se401
->dev
== NULL
)
1308 if (realcount
> se401
->cwidth
*se401
->cheight
*3)
1309 realcount
=se401
->cwidth
*se401
->cheight
*3;
1311 /* Shouldn't happen: */
1312 if (se401
->frame
[0].grabstate
==FRAME_GRABBING
)
1314 se401
->frame
[0].grabstate
=FRAME_READY
;
1315 se401
->frame
[1].grabstate
=FRAME_UNUSED
;
1318 if (!se401
->streaming
)
1319 se401_start_stream(se401
);
1321 /* Set the picture properties */
1322 if (se401
->framecount
==0)
1323 se401_send_pict(se401
);
1324 /* Calibrate the reset level after a few frames. */
1325 if (se401
->framecount
%20==1)
1326 se401_auto_resetlevel(se401
);
1328 ret
=se401_newframe(se401
, 0);
1330 se401
->frame
[0].grabstate
=FRAME_UNUSED
;
1333 if (copy_to_user(buf
, se401
->frame
[0].data
, realcount
))
1339 static int se401_mmap(struct video_device
*dev
, const char *adr
,
1342 struct usb_se401
*se401
= (struct usb_se401
*)dev
;
1343 unsigned long start
= (unsigned long)adr
;
1344 unsigned long page
, pos
;
1348 if (se401
->dev
== NULL
) {
1352 if (size
> (((SE401_NUMFRAMES
* se401
->maxframesize
) + PAGE_SIZE
- 1) & ~(PAGE_SIZE
- 1))) {
1356 pos
= (unsigned long)se401
->fbuf
;
1358 page
= kvirt_to_pa(pos
);
1359 if (remap_page_range(start
, page
, PAGE_SIZE
, PAGE_SHARED
)) {
1365 if (size
> PAGE_SIZE
)
1375 static struct video_device se401_template
= {
1376 name
: "se401 USB camera",
1377 type
: VID_TYPE_CAPTURE
,
1378 hardware
: VID_HARDWARE_SE401
,
1385 initialize
: se401_init_done
,
1390 /***************************/
1391 static int se401_init(struct usb_se401
*se401
)
1394 unsigned char cp
[0x40];
1398 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 1, NULL
, 0);
1400 /* get camera descriptor */
1401 rc
=se401_sndctrl(0, se401
, SE401_REQ_GET_CAMERA_DESCRIPTOR
, 0, cp
, sizeof(cp
));
1403 err("Wrong descriptor type");
1406 sprintf (temp
, "ExtraFeatures: %d", cp
[3]);
1408 se401
->sizes
=cp
[4]+cp
[5]*256;
1409 se401
->width
=kmalloc(se401
->sizes
*sizeof(int), GFP_KERNEL
);
1412 se401
->height
=kmalloc(se401
->sizes
*sizeof(int), GFP_KERNEL
);
1413 if (!se401
->height
) {
1414 kfree(se401
->width
);
1417 for (i
=0; i
<se401
->sizes
; i
++) {
1418 se401
->width
[i
]=cp
[6+i
*4+0]+cp
[6+i
*4+1]*256;
1419 se401
->height
[i
]=cp
[6+i
*4+2]+cp
[6+i
*4+3]*256;
1421 sprintf (temp
, "%s Sizes:", temp
);
1422 for (i
=0; i
<se401
->sizes
; i
++) {
1423 sprintf(temp
, "%s %dx%d", temp
, se401
->width
[i
], se401
->height
[i
]);
1426 se401
->maxframesize
=se401
->width
[se401
->sizes
-1]*se401
->height
[se401
->sizes
-1]*3;
1428 rc
=se401_sndctrl(0, se401
, SE401_REQ_GET_WIDTH
, 0, cp
, sizeof(cp
));
1429 se401
->cwidth
=cp
[0]+cp
[1]*256;
1430 rc
=se401_sndctrl(0, se401
, SE401_REQ_GET_HEIGHT
, 0, cp
, sizeof(cp
));
1431 se401
->cheight
=cp
[0]+cp
[1]*256;
1433 if (!cp
[2] && SE401_FORMAT_BAYER
) {
1434 err("Bayer format not supported!");
1437 /* set output mode (BAYER) */
1438 se401_sndctrl(1, se401
, SE401_REQ_SET_OUTPUT_MODE
, SE401_FORMAT_BAYER
, NULL
, 0);
1440 rc
=se401_sndctrl(0, se401
, SE401_REQ_GET_BRT
, 0, cp
, sizeof(cp
));
1441 se401
->brightness
=cp
[0]+cp
[1]*256;
1442 /* some default values */
1443 se401
->resetlevel
=0x2d;
1447 se401_set_exposure(se401
, 20000);
1448 se401
->palette
=VIDEO_PALETTE_RGB24
;
1452 se401
->framecount
=0;
1455 /* Start interrupt transfers for snapshot button */
1456 se401
->inturb
=usb_alloc_urb(0);
1457 if (!se401
->inturb
) {
1458 info("Allocation of inturb failed");
1461 FILL_INT_URB(se401
->inturb
, se401
->dev
,
1462 usb_rcvintpipe(se401
->dev
, SE401_BUTTON_ENDPOINT
),
1463 &se401
->button
, sizeof(se401
->button
),
1468 if (usb_submit_urb(se401
->inturb
)) {
1469 info("int urb burned down");
1474 se401_sndctrl(1, se401
, SE401_REQ_CAMERA_POWER
, 1, NULL
, 0);
1475 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 1, NULL
, 0);
1476 se401_sndctrl(1, se401
, SE401_REQ_CAMERA_POWER
, 0, NULL
, 0);
1477 se401_sndctrl(1, se401
, SE401_REQ_LED_CONTROL
, 0, NULL
, 0);
1482 static void* se401_probe(struct usb_device
*dev
, unsigned int ifnum
,
1483 const struct usb_device_id
*id
)
1485 struct usb_interface_descriptor
*interface
;
1486 struct usb_se401
*se401
;
1487 char *camera_name
=NULL
;
1489 /* We don't handle multi-config cameras */
1490 if (dev
->descriptor
.bNumConfigurations
!= 1)
1493 interface
= &dev
->actconfig
->interface
[ifnum
].altsetting
[0];
1495 /* Is it an se401? */
1496 if (dev
->descriptor
.idVendor
== 0x03e8 &&
1497 dev
->descriptor
.idProduct
== 0x0004) {
1498 camera_name
="Endpoints/Aox SE401";
1499 } else if (dev
->descriptor
.idVendor
== 0x0471 &&
1500 dev
->descriptor
.idProduct
== 0x030b) {
1501 camera_name
="Philips PCVC665K";
1502 } else if (dev
->descriptor
.idVendor
== 0x047d &&
1503 dev
->descriptor
.idProduct
== 0x5001) {
1504 camera_name
="Kensington VideoCAM 67014";
1505 } else if (dev
->descriptor
.idVendor
== 0x047d &&
1506 dev
->descriptor
.idProduct
== 0x5002) {
1507 camera_name
="Kensington VideoCAM 6701(5/7)";
1508 } else if (dev
->descriptor
.idVendor
== 0x047d &&
1509 dev
->descriptor
.idProduct
== 0x5003) {
1510 camera_name
="Kensington VideoCAM 67016";
1514 /* Checking vendor/product should be enough, but what the hell */
1515 if (interface
->bInterfaceClass
!= 0x00)
1517 if (interface
->bInterfaceSubClass
!= 0x00)
1521 info("SE401 camera found: %s", camera_name
);
1523 if ((se401
= kmalloc(sizeof(*se401
), GFP_KERNEL
)) == NULL
) {
1524 err("couldn't kmalloc se401 struct");
1528 memset(se401
, 0, sizeof(*se401
));
1531 se401
->iface
= interface
->bInterfaceNumber
;
1532 se401
->camera_name
= camera_name
;
1534 info("firmware version: %02x", dev
->descriptor
.bcdDevice
& 255);
1536 if (se401_init(se401
)) {
1541 memcpy(&se401
->vdev
, &se401_template
, sizeof(se401_template
));
1542 memcpy(se401
->vdev
.name
, se401
->camera_name
, strlen(se401
->camera_name
));
1543 init_waitqueue_head(&se401
->wq
);
1544 init_MUTEX(&se401
->lock
);
1547 if (video_register_device(&se401
->vdev
, VFL_TYPE_GRABBER
, video_nr
) == -1) {
1549 err("video_register_device failed");
1552 info("registered new video device: video%d", se401
->vdev
.minor
);
1557 static void se401_disconnect(struct usb_device
*dev
, void *ptr
)
1559 struct usb_se401
*se401
= (struct usb_se401
*) ptr
;
1562 /* We don't want people trying to open up the device */
1564 video_unregister_device(&se401
->vdev
);
1565 usb_se401_remove_disconnected(se401
);
1572 static struct usb_driver se401_driver
= {
1574 id_table
: device_table
,
1576 disconnect
: se401_disconnect
1581 /****************************************************************************
1585 ***************************************************************************/
1587 static int __init
usb_se401_init(void)
1589 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1590 proc_se401_create();
1593 info("SE401 usb camera driver version %s registering", version
);
1595 if (flickerless
!=50 && flickerless
!=60) {
1596 info("Invallid flickerless value, use 0, 50 or 60.");
1599 if (usb_register(&se401_driver
) < 0)
1604 static void __exit
usb_se401_exit(void)
1606 usb_deregister(&se401_driver
);
1607 info("SE401 driver deregistered");
1609 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1610 proc_se401_destroy();
1614 module_init(usb_se401_init
);
1615 module_exit(usb_se401_exit
);