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/module.h>
31 #include <linux/init.h>
32 #include <linux/vmalloc.h>
33 #include <linux/slab.h>
34 #include <linux/smp_lock.h>
35 #include <linux/pagemap.h>
36 #include <linux/usb.h>
39 static int flickerless;
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,
58 "Net frequency to adjust exposure time to (0/50/60)");
59 module_param(video_nr, int, 0);
61 static struct usb_driver se401_driver;
64 /**********************************************************************
68 **********************************************************************/
69 static void *rvmalloc(unsigned long size)
74 size = PAGE_ALIGN(size);
75 mem = vmalloc_32(size);
79 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
80 adr = (unsigned long) mem;
82 SetPageReserved(vmalloc_to_page((void *)adr));
90 static void rvfree(void *mem, unsigned long size)
97 adr = (unsigned long) mem;
98 while ((long) size > 0) {
99 ClearPageReserved(vmalloc_to_page((void *)adr));
108 /****************************************************************************
110 * se401 register read/write functions
112 ***************************************************************************/
114 static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
115 unsigned short value, unsigned char *cp, int size)
117 return usb_control_msg(
119 set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
121 (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
130 static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
131 unsigned short param)
133 /* specs say that the selector (address) should go in the value field
134 and the param in index, but in the logs of the windows driver they do
135 this the other way around...
137 return usb_control_msg(
139 usb_sndctrlpipe(se401->dev, 0),
140 SE401_REQ_SET_EXT_FEATURE,
141 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
150 static unsigned short se401_get_feature(struct usb_se401 *se401,
151 unsigned short selector)
153 /* For 'set' the selecetor should be in index, not sure if the spec is
159 usb_rcvctrlpipe(se401->dev, 0),
160 SE401_REQ_GET_EXT_FEATURE,
161 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
168 return cp[0]+cp[1]*256;
171 /****************************************************************************
175 ***************************************************************************/
178 static int se401_send_pict(struct usb_se401 *se401)
180 /* integration time low */
181 se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);
182 /* integration time mid */
183 se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);
184 /* integration time mid */
185 se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);
186 /* reset level value */
187 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
189 se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);
190 /* green color gain */
191 se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);
192 /* blue color gain */
193 se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);
198 static void se401_set_exposure(struct usb_se401 *se401, int brightness)
200 int integration = brightness << 5;
202 if (flickerless == 50)
203 integration = integration-integration % 106667;
204 if (flickerless == 60)
205 integration = integration-integration % 88889;
206 se401->brightness = integration >> 5;
207 se401->expose_h = (integration >> 16) & 0xff;
208 se401->expose_m = (integration >> 8) & 0xff;
209 se401->expose_l = integration & 0xff;
212 static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
214 p->brightness = se401->brightness;
216 p->whiteness = 32768;
222 p->hue = se401->rgain << 10;
223 p->palette = se401->palette;
224 p->depth = 3; /* rgb24 */
229 static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
231 if (p->palette != VIDEO_PALETTE_RGB24)
233 se401->palette = p->palette;
234 if (p->hue != se401->hue) {
235 se401->rgain = p->hue >> 10;
236 se401->bgain = 0x40-(p->hue >> 10);
239 if (p->brightness != se401->brightness)
240 se401_set_exposure(se401, p->brightness);
242 if (p->whiteness >= 32768)
246 se401_send_pict(se401);
247 se401_send_pict(se401);
252 Hyundai have some really nice docs about this and other sensor related
253 stuff on their homepage: www.hei.co.kr
255 static void se401_auto_resetlevel(struct usb_se401 *se401)
257 unsigned int ahrc, alrc;
258 int oldreset = se401->resetlevel;
260 /* For some reason this normally read-only register doesn't get reset
261 to zero after reading them just once...
263 se401_get_feature(se401, HV7131_REG_HIREFNOH);
264 se401_get_feature(se401, HV7131_REG_HIREFNOL);
265 se401_get_feature(se401, HV7131_REG_LOREFNOH);
266 se401_get_feature(se401, HV7131_REG_LOREFNOL);
267 ahrc = 256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
268 se401_get_feature(se401, HV7131_REG_HIREFNOL);
269 alrc = 256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
270 se401_get_feature(se401, HV7131_REG_LOREFNOL);
272 /* Not an exact science, but it seems to work pretty well... */
274 while (alrc >= 10 && se401->resetlevel < 63) {
278 } else if (ahrc > 20) {
279 while (ahrc >= 20 && se401->resetlevel > 0) {
284 if (se401->resetlevel != oldreset)
285 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
290 /* irq handler for snapshot button */
291 static void se401_button_irq(struct urb *urb)
293 struct usb_se401 *se401 = urb->context;
297 dev_info(&urb->dev->dev, "device vapourished\n");
301 switch (urb->status) {
308 /* this urb is terminated, clean up */
309 dbg("%s - urb shutting down with status: %d",
310 __func__, urb->status);
313 dbg("%s - nonzero urb status received: %d",
314 __func__, urb->status);
318 if (urb->actual_length >= 2)
320 se401->buttonpressed = 1;
322 status = usb_submit_urb(urb, GFP_ATOMIC);
324 err("%s - usb_submit_urb failed with result %d",
328 static void se401_video_irq(struct urb *urb)
330 struct usb_se401 *se401 = urb->context;
331 int length = urb->actual_length;
334 if (!se401->streaming)
338 dev_info(&urb->dev->dev, "device vapourished\n");
342 /* 0 sized packets happen if we are to fast, but sometimes the camera
343 keeps sending them forever...
345 if (length && !urb->status) {
346 se401->nullpackets = 0;
347 switch (se401->scratch[se401->scratch_next].state) {
353 memcpy(se401->scratch[se401->scratch_next].data,
354 (unsigned char *)urb->transfer_buffer, length);
355 se401->scratch[se401->scratch_next].state
357 se401->scratch[se401->scratch_next].offset
358 = se401->bayeroffset;
359 se401->scratch[se401->scratch_next].length = length;
360 if (waitqueue_active(&se401->wq))
361 wake_up_interruptible(&se401->wq);
362 se401->scratch_overflow = 0;
363 se401->scratch_next++;
364 if (se401->scratch_next >= SE401_NUMSCRATCH)
365 se401->scratch_next = 0;
368 se401->bayeroffset += length;
369 if (se401->bayeroffset >= se401->cheight * se401->cwidth)
370 se401->bayeroffset = 0;
372 se401->nullpackets++;
373 if (se401->nullpackets > SE401_MAX_NULLPACKETS)
374 if (waitqueue_active(&se401->wq))
375 wake_up_interruptible(&se401->wq);
378 /* Resubmit urb for new data */
380 urb->dev = se401->dev;
381 if (usb_submit_urb(urb, GFP_KERNEL))
382 dev_info(&urb->dev->dev, "urb burned down\n");
386 static void se401_send_size(struct usb_se401 *se401, int width, int height)
389 int mode = 0x03; /* No compression */
390 int sendheight = height;
391 int sendwidth = width;
393 /* JangGu compression can only be used with the camera supported sizes,
394 but bayer seems to work with any size that fits on the sensor.
395 We check if we can use compression with the current size with either
396 4 or 16 times subcapturing, if not we use uncompressed bayer data
397 but this will result in cutouts of the maximum size....
399 while (i < se401->sizes && !(se401->width[i] == width &&
400 se401->height[i] == height))
402 while (i < se401->sizes) {
403 if (se401->width[i] == width * 2 &&
404 se401->height[i] == height * 2) {
405 sendheight = se401->height[i];
406 sendwidth = se401->width[i];
409 if (se401->width[i] == width * 4 &&
410 se401->height[i] == height * 4) {
411 sendheight = se401->height[i];
412 sendwidth = se401->width[i];
418 se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
419 se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
420 se401_set_feature(se401, SE401_OPERATINGMODE, mode);
423 se401->format = FMT_BAYER;
425 se401->format = FMT_JANGGU;
429 In this function se401_send_pict is called several times,
430 for some reason (depending on the state of the sensor and the phase of
431 the moon :) doing this only in either place doesn't always work...
433 static int se401_start_stream(struct usb_se401 *se401)
437 se401->streaming = 1;
439 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
440 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
442 /* Set picture settings */
443 /* windowed + pix intg */
444 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);
445 se401_send_pict(se401);
447 se401_send_size(se401, se401->cwidth, se401->cheight);
449 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE,
452 /* Do some memory allocation */
453 for (i = 0; i < SE401_NUMFRAMES; i++) {
454 se401->frame[i].data = se401->fbuf + i * se401->maxframesize;
455 se401->frame[i].curpix = 0;
457 for (i = 0; i < SE401_NUMSBUF; i++) {
458 se401->sbuf[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
459 if (!se401->sbuf[i].data) {
460 for (i = i - 1; i >= 0; i--) {
461 kfree(se401->sbuf[i].data);
462 se401->sbuf[i].data = NULL;
468 se401->bayeroffset = 0;
469 se401->scratch_next = 0;
470 se401->scratch_use = 0;
471 se401->scratch_overflow = 0;
472 for (i = 0; i < SE401_NUMSCRATCH; i++) {
473 se401->scratch[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
474 if (!se401->scratch[i].data) {
475 for (i = i - 1; i >= 0; i--) {
476 kfree(se401->scratch[i].data);
477 se401->scratch[i].data = NULL;
481 se401->scratch[i].state = BUFFER_UNUSED;
484 for (i = 0; i < SE401_NUMSBUF; i++) {
485 urb = usb_alloc_urb(0, GFP_KERNEL);
487 for (i = i - 1; i >= 0; i--) {
488 usb_kill_urb(se401->urb[i]);
489 usb_free_urb(se401->urb[i]);
490 se401->urb[i] = NULL;
495 usb_fill_bulk_urb(urb, se401->dev,
496 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
497 se401->sbuf[i].data, SE401_PACKETSIZE,
503 err = usb_submit_urb(se401->urb[i], GFP_KERNEL);
505 err("urb burned down");
508 se401->framecount = 0;
513 for (i = 0; i < SE401_NUMSCRATCH; i++) {
514 kfree(se401->scratch[i].data);
515 se401->scratch[i].data = NULL;
518 for (i = 0; i < SE401_NUMSBUF; i++) {
519 kfree(se401->sbuf[i].data);
520 se401->sbuf[i].data = NULL;
525 static int se401_stop_stream(struct usb_se401 *se401)
529 if (!se401->streaming || !se401->dev)
532 se401->streaming = 0;
534 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
536 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
537 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
539 for (i = 0; i < SE401_NUMSBUF; i++)
541 usb_kill_urb(se401->urb[i]);
542 usb_free_urb(se401->urb[i]);
543 se401->urb[i] = NULL;
544 kfree(se401->sbuf[i].data);
546 for (i = 0; i < SE401_NUMSCRATCH; i++) {
547 kfree(se401->scratch[i].data);
548 se401->scratch[i].data = NULL;
554 static int se401_set_size(struct usb_se401 *se401, int width, int height)
556 int wasstreaming = se401->streaming;
557 /* Check to see if we need to change */
558 if (se401->cwidth == width && se401->cheight == height)
561 /* Check for a valid mode */
562 if (!width || !height)
564 if ((width & 1) || (height & 1))
566 if (width > se401->width[se401->sizes-1])
568 if (height > se401->height[se401->sizes-1])
571 /* Stop a current stream and start it again at the new size */
573 se401_stop_stream(se401);
574 se401->cwidth = width;
575 se401->cheight = height;
577 se401_start_stream(se401);
582 /****************************************************************************
586 ***************************************************************************/
589 This shouldn't really be done in a v4l driver....
590 But it does make the image look a lot more usable.
591 Basically it lifts the dark pixels more than the light pixels.
593 static inline void enhance_picture(unsigned char *frame, int len)
596 *frame = (((*frame^255)*(*frame^255))/255)^255;
601 static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
603 struct se401_frame *frame = &se401->frame[se401->curframe];
604 int linelength = se401->cwidth * 3;
606 if (frame->curlinepix >= linelength) {
607 frame->curlinepix = 0;
608 frame->curline += linelength;
611 /* First three are absolute, all others relative.
612 * Format is rgb from right to left (mirrorred image),
613 * we flip it to get bgr from left to right. */
614 if (frame->curlinepix < 3)
615 *(frame->curline-frame->curlinepix) = 1 + data * 4;
617 *(frame->curline-frame->curlinepix) =
618 *(frame->curline-frame->curlinepix + 3) + data * 4;
622 static inline void decode_JangGu_vlc(struct usb_se401 *se401,
623 unsigned char *data, int bit_exp, int packetlength)
632 while (pos < packetlength) {
634 while (bit_cur && bit_exp) {
635 bit = ((*data) >> (bit_cur-1))&1;
641 decode_JangGu_integrate(se401, 0);
650 vlc_data = -(1 << vlc_size) + 1;
654 vlc_data += bit << vlc_size;
656 decode_JangGu_integrate(se401, vlc_data);
668 static inline void decode_JangGu(struct usb_se401 *se401,
669 struct se401_scratch *buffer)
671 unsigned char *data = buffer->data;
672 int len = buffer->length;
673 int bit_exp = 0, pix_exp = 0, frameinfo = 0, packetlength = 0, size;
677 if (!se401->frame[se401->curframe].curpix) {
678 se401->frame[se401->curframe].curlinepix = 0;
679 se401->frame[se401->curframe].curline =
680 se401->frame[se401->curframe].data+
681 se401->cwidth * 3 - 1;
682 if (se401->frame[se401->curframe].grabstate == FRAME_READY)
683 se401->frame[se401->curframe].grabstate = FRAME_GRABBING;
684 se401->vlcdatapos = 0;
686 while (datapos < len) {
687 size = 1024 - se401->vlcdatapos;
688 if (size+datapos > len)
690 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
691 se401->vlcdatapos += size;
693 if (se401->vlcdatapos >= 4) {
694 bit_exp = se401->vlcdata[3] + (se401->vlcdata[2] << 8);
695 pix_exp = se401->vlcdata[1] +
696 ((se401->vlcdata[0] & 0x3f) << 8);
697 frameinfo = se401->vlcdata[0] & 0xc0;
698 packetlength = ((bit_exp + 47) >> 4) << 1;
699 if (packetlength > 1024) {
700 se401->vlcdatapos = 0;
704 se401->frame[se401->curframe].curpix = 0;
707 if (packetlength && se401->vlcdatapos >= packetlength) {
708 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp,
710 se401->frame[se401->curframe].curpix += pix_exp * 3;
711 datapos += size-(se401->vlcdatapos-packetlength);
712 se401->vlcdatapos = 0;
713 if (se401->frame[se401->curframe].curpix >= se401->cwidth * se401->cheight * 3) {
714 if (se401->frame[se401->curframe].curpix == se401->cwidth * se401->cheight * 3) {
715 if (se401->frame[se401->curframe].grabstate == FRAME_GRABBING) {
716 se401->frame[se401->curframe].grabstate = FRAME_DONE;
720 if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY)
721 se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1);
724 se401->frame[se401->curframe].curpix = 0;
732 static inline void decode_bayer(struct usb_se401 *se401,
733 struct se401_scratch *buffer)
735 unsigned char *data = buffer->data;
736 int len = buffer->length;
737 int offset = buffer->offset;
738 int datasize = se401->cwidth * se401->cheight;
739 struct se401_frame *frame = &se401->frame[se401->curframe];
740 unsigned char *framedata = frame->data, *curline, *nextline;
741 int width = se401->cwidth;
742 int blineoffset = 0, bline;
743 int linelength = width * 3, i;
746 if (frame->curpix == 0) {
747 if (frame->grabstate == FRAME_READY)
748 frame->grabstate = FRAME_GRABBING;
750 frame->curline = framedata + linelength;
751 frame->curlinepix = 0;
754 if (offset != frame->curpix) {
755 /* Regard frame as lost :( */
761 /* Check if we have to much data */
762 if (frame->curpix + len > datasize)
763 len = datasize-frame->curpix;
765 if (se401->cheight % 4)
767 bline = frame->curpix / se401->cwidth+blineoffset;
769 curline = frame->curline;
770 nextline = curline + linelength;
771 if (nextline >= framedata+datasize * 3)
774 if (frame->curlinepix >= width) {
775 frame->curlinepix -= width;
776 bline = frame->curpix / width + blineoffset;
777 curline += linelength*2;
778 nextline += linelength*2;
779 if (curline >= framedata+datasize * 3) {
787 if (nextline >= framedata+datasize*3)
791 if (frame->curlinepix & 1) {
792 *(curline + 2) = *data;
793 *(curline - 1) = *data;
794 *(nextline + 2) = *data;
795 *(nextline - 1) = *data;
798 (*(curline + 1) + *data) / 2;
800 (*(curline - 2) + *data) / 2;
801 *(nextline + 1) = *data;
802 *(nextline - 2) = *data;
805 if (frame->curlinepix & 1) {
807 (*(curline + 1) + *data) / 2;
809 (*(curline - 2) + *data) / 2;
810 *(nextline + 1) = *data;
811 *(nextline - 2) = *data;
814 *(curline - 3) = *data;
816 *(nextline - 3) = *data;
826 frame->curline = curline;
828 if (frame->curpix >= datasize) {
829 /* Fix the top line */
830 framedata += linelength;
831 for (i = 0; i < linelength; i++) {
833 *framedata = *(framedata + linelength);
835 /* Fix the left side (green is already present) */
836 for (i = 0; i < se401->cheight; i++) {
837 *framedata = *(framedata + 3);
838 *(framedata + 1) = *(framedata + 4);
839 *(framedata + 2) = *(framedata + 5);
840 framedata += linelength;
843 frame->grabstate = FRAME_DONE;
846 if (se401->frame[(se401->curframe + 1) &
847 (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) {
848 se401->curframe = (se401->curframe+1) &
854 static int se401_newframe(struct usb_se401 *se401, int framenr)
856 DECLARE_WAITQUEUE(wait, current);
859 while (se401->streaming &&
860 (se401->frame[framenr].grabstate == FRAME_READY ||
861 se401->frame[framenr].grabstate == FRAME_GRABBING)) {
862 if (!se401->frame[framenr].curpix)
866 se401->scratch[se401->scratch_use].state != BUFFER_READY,
868 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
869 se401->nullpackets = 0;
870 dev_info(&se401->dev->dev,
871 "too many null length packets, restarting capture\n");
872 se401_stop_stream(se401);
873 se401_start_stream(se401);
875 if (se401->scratch[se401->scratch_use].state !=
877 se401->frame[framenr].grabstate = FRAME_ERROR;
880 se401->scratch[se401->scratch_use].state = BUFFER_BUSY;
881 if (se401->format == FMT_JANGGU)
883 &se401->scratch[se401->scratch_use]);
886 &se401->scratch[se401->scratch_use]);
888 se401->scratch[se401->scratch_use].state =
890 se401->scratch_use++;
891 if (se401->scratch_use >= SE401_NUMSCRATCH)
892 se401->scratch_use = 0;
893 if (errors > SE401_MAX_ERRORS) {
895 dev_info(&se401->dev->dev,
896 "too many errors, restarting capture\n");
897 se401_stop_stream(se401);
898 se401_start_stream(se401);
903 if (se401->frame[framenr].grabstate == FRAME_DONE)
905 enhance_picture(se401->frame[framenr].data,
906 se401->cheight * se401->cwidth * 3);
910 static void usb_se401_remove_disconnected(struct usb_se401 *se401)
916 for (i = 0; i < SE401_NUMSBUF; i++)
918 usb_kill_urb(se401->urb[i]);
919 usb_free_urb(se401->urb[i]);
920 se401->urb[i] = NULL;
921 kfree(se401->sbuf[i].data);
924 for (i = 0; i < SE401_NUMSCRATCH; i++)
925 kfree(se401->scratch[i].data);
928 usb_kill_urb(se401->inturb);
929 usb_free_urb(se401->inturb);
931 dev_info(&se401->dev->dev, "%s disconnected", se401->camera_name);
933 /* Free the memory */
935 kfree(se401->height);
941 /****************************************************************************
945 ***************************************************************************/
948 static int se401_open(struct file *file)
950 struct video_device *dev = video_devdata(file);
951 struct usb_se401 *se401 = (struct usb_se401 *)dev;
959 se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
961 file->private_data = dev;
970 static int se401_close(struct file *file)
972 struct video_device *dev = file->private_data;
973 struct usb_se401 *se401 = (struct usb_se401 *)dev;
976 rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
977 if (se401->removed) {
978 dev_info(&se401->dev->dev, "device unregistered\n");
979 usb_se401_remove_disconnected(se401);
981 for (i = 0; i < SE401_NUMFRAMES; i++)
982 se401->frame[i].grabstate = FRAME_UNUSED;
983 if (se401->streaming)
984 se401_stop_stream(se401);
987 file->private_data = NULL;
991 static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
993 struct video_device *vdev = file->private_data;
994 struct usb_se401 *se401 = (struct usb_se401 *)vdev;
1002 struct video_capability *b = arg;
1003 strcpy(b->name, se401->camera_name);
1004 b->type = VID_TYPE_CAPTURE;
1007 b->maxwidth = se401->width[se401->sizes-1];
1008 b->maxheight = se401->height[se401->sizes-1];
1009 b->minwidth = se401->width[0];
1010 b->minheight = se401->height[0];
1015 struct video_channel *v = arg;
1017 if (v->channel != 0)
1021 v->type = VIDEO_TYPE_CAMERA;
1022 strcpy(v->name, "Camera");
1027 struct video_channel *v = arg;
1029 if (v->channel != 0)
1035 struct video_picture *p = arg;
1037 se401_get_pict(se401, p);
1042 struct video_picture *p = arg;
1044 if (se401_set_pict(se401, p))
1050 struct video_window *vw = arg;
1056 if (se401_set_size(se401, vw->width, vw->height))
1062 struct video_window *vw = arg;
1064 vw->x = 0; /* FIXME */
1069 vw->width = se401->cwidth;
1070 vw->height = se401->cheight;
1075 struct video_mbuf *vm = arg;
1078 memset(vm, 0, sizeof(*vm));
1079 vm->size = SE401_NUMFRAMES * se401->maxframesize;
1080 vm->frames = SE401_NUMFRAMES;
1081 for (i = 0; i < SE401_NUMFRAMES; i++)
1082 vm->offsets[i] = se401->maxframesize * i;
1085 case VIDIOCMCAPTURE:
1087 struct video_mmap *vm = arg;
1089 if (vm->format != VIDEO_PALETTE_RGB24)
1091 if (vm->frame >= SE401_NUMFRAMES)
1093 if (se401->frame[vm->frame].grabstate != FRAME_UNUSED)
1096 /* Is this according to the v4l spec??? */
1097 if (se401_set_size(se401, vm->width, vm->height))
1099 se401->frame[vm->frame].grabstate = FRAME_READY;
1101 if (!se401->streaming)
1102 se401_start_stream(se401);
1104 /* Set the picture properties */
1105 if (se401->framecount == 0)
1106 se401_send_pict(se401);
1107 /* Calibrate the reset level after a few frames. */
1108 if (se401->framecount % 20 == 1)
1109 se401_auto_resetlevel(se401);
1118 if (*frame < 0 || *frame >= SE401_NUMFRAMES)
1121 ret = se401_newframe(se401, *frame);
1122 se401->frame[*frame].grabstate = FRAME_UNUSED;
1127 struct video_buffer *vb = arg;
1129 memset(vb, 0, sizeof(*vb));
1148 return -ENOIOCTLCMD;
1154 static long se401_ioctl(struct file *file,
1155 unsigned int cmd, unsigned long arg)
1157 return video_usercopy(file, cmd, arg, se401_do_ioctl);
1160 static ssize_t se401_read(struct file *file, char __user *buf,
1161 size_t count, loff_t *ppos)
1163 int realcount = count, ret = 0;
1164 struct video_device *dev = file->private_data;
1165 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1168 if (se401->dev == NULL)
1170 if (realcount > se401->cwidth*se401->cheight*3)
1171 realcount = se401->cwidth*se401->cheight*3;
1173 /* Shouldn't happen: */
1174 if (se401->frame[0].grabstate == FRAME_GRABBING)
1176 se401->frame[0].grabstate = FRAME_READY;
1177 se401->frame[1].grabstate = FRAME_UNUSED;
1178 se401->curframe = 0;
1180 if (!se401->streaming)
1181 se401_start_stream(se401);
1183 /* Set the picture properties */
1184 if (se401->framecount == 0)
1185 se401_send_pict(se401);
1186 /* Calibrate the reset level after a few frames. */
1187 if (se401->framecount%20 == 1)
1188 se401_auto_resetlevel(se401);
1190 ret = se401_newframe(se401, 0);
1192 se401->frame[0].grabstate = FRAME_UNUSED;
1195 if (copy_to_user(buf, se401->frame[0].data, realcount))
1201 static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1203 struct video_device *dev = file->private_data;
1204 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1205 unsigned long start = vma->vm_start;
1206 unsigned long size = vma->vm_end-vma->vm_start;
1207 unsigned long page, pos;
1209 mutex_lock(&se401->lock);
1211 if (se401->dev == NULL) {
1212 mutex_unlock(&se401->lock);
1215 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1)
1216 & ~(PAGE_SIZE - 1))) {
1217 mutex_unlock(&se401->lock);
1220 pos = (unsigned long)se401->fbuf;
1222 page = vmalloc_to_pfn((void *)pos);
1223 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1224 mutex_unlock(&se401->lock);
1229 if (size > PAGE_SIZE)
1234 mutex_unlock(&se401->lock);
1239 static const struct v4l2_file_operations se401_fops = {
1240 .owner = THIS_MODULE,
1242 .release = se401_close,
1245 .ioctl = se401_ioctl,
1247 static struct video_device se401_template = {
1248 .name = "se401 USB camera",
1249 .fops = &se401_fops,
1250 .release = video_device_release_empty,
1255 /***************************/
1256 static int se401_init(struct usb_se401 *se401, int button)
1259 unsigned char cp[0x40];
1264 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1266 /* get camera descriptor */
1267 rc = se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0,
1269 if (cp[1] != 0x41) {
1270 err("Wrong descriptor type");
1273 slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]);
1275 se401->sizes = cp[4] + cp[5] * 256;
1276 se401->width = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1279 se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1280 if (!se401->height) {
1281 kfree(se401->width);
1284 for (i = 0; i < se401->sizes; i++) {
1285 se401->width[i] = cp[6 + i * 4 + 0] + cp[6 + i*4 + 1] * 256;
1286 se401->height[i] = cp[6 + i * 4 + 2] + cp[6 + i * 4 + 3] * 256;
1288 slen += snprintf(temp + slen, 200 - slen, " Sizes:");
1289 for (i = 0; i < se401->sizes; i++) {
1290 slen += snprintf(temp + slen, 200 - slen,
1291 " %dx%d", se401->width[i], se401->height[i]);
1293 dev_info(&se401->dev->dev, "%s\n", temp);
1294 se401->maxframesize = se401->width[se401->sizes-1] *
1295 se401->height[se401->sizes - 1] * 3;
1297 rc = se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1298 se401->cwidth = cp[0]+cp[1]*256;
1299 rc = se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1300 se401->cheight = cp[0]+cp[1]*256;
1302 if (!(cp[2] & SE401_FORMAT_BAYER)) {
1303 err("Bayer format not supported!");
1306 /* set output mode (BAYER) */
1307 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE,
1308 SE401_FORMAT_BAYER, NULL, 0);
1310 rc = se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1311 se401->brightness = cp[0]+cp[1]*256;
1312 /* some default values */
1313 se401->resetlevel = 0x2d;
1314 se401->rgain = 0x20;
1315 se401->ggain = 0x20;
1316 se401->bgain = 0x20;
1317 se401_set_exposure(se401, 20000);
1318 se401->palette = VIDEO_PALETTE_RGB24;
1322 se401->framecount = 0;
1323 se401->readcount = 0;
1325 /* Start interrupt transfers for snapshot button */
1327 se401->inturb = usb_alloc_urb(0, GFP_KERNEL);
1328 if (!se401->inturb) {
1329 dev_info(&se401->dev->dev,
1330 "Allocation of inturb failed\n");
1333 usb_fill_int_urb(se401->inturb, se401->dev,
1334 usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1335 &se401->button, sizeof(se401->button),
1340 if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
1341 dev_info(&se401->dev->dev, "int urb burned down\n");
1345 se401->inturb = NULL;
1348 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1349 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1350 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1351 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1356 static int se401_probe(struct usb_interface *intf,
1357 const struct usb_device_id *id)
1359 struct usb_device *dev = interface_to_usbdev(intf);
1360 struct usb_interface_descriptor *interface;
1361 struct usb_se401 *se401;
1362 char *camera_name = NULL;
1365 /* We don't handle multi-config cameras */
1366 if (dev->descriptor.bNumConfigurations != 1)
1369 interface = &intf->cur_altsetting->desc;
1371 /* Is it an se401? */
1372 if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
1373 le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
1374 camera_name = "Endpoints/Aox SE401";
1375 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
1376 le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
1377 camera_name = "Philips PCVC665K";
1378 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1379 le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
1380 camera_name = "Kensington VideoCAM 67014";
1381 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1382 le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
1383 camera_name = "Kensington VideoCAM 6701(5/7)";
1384 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1385 le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
1386 camera_name = "Kensington VideoCAM 67016";
1391 /* Checking vendor/product should be enough, but what the hell */
1392 if (interface->bInterfaceClass != 0x00)
1394 if (interface->bInterfaceSubClass != 0x00)
1398 dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name);
1400 se401 = kzalloc(sizeof(*se401), GFP_KERNEL);
1401 if (se401 == NULL) {
1402 err("couldn't kmalloc se401 struct");
1407 se401->iface = interface->bInterfaceNumber;
1408 se401->camera_name = camera_name;
1410 dev_info(&intf->dev, "firmware version: %02x\n",
1411 le16_to_cpu(dev->descriptor.bcdDevice) & 255);
1413 if (se401_init(se401, button)) {
1418 memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1419 memcpy(se401->vdev.name, se401->camera_name,
1420 strlen(se401->camera_name));
1421 init_waitqueue_head(&se401->wq);
1422 mutex_init(&se401->lock);
1425 if (video_register_device(&se401->vdev,
1426 VFL_TYPE_GRABBER, video_nr) < 0) {
1428 err("video_register_device failed");
1431 dev_info(&intf->dev, "registered new video device: video%d\n",
1434 usb_set_intfdata(intf, se401);
1438 static void se401_disconnect(struct usb_interface *intf)
1440 struct usb_se401 *se401 = usb_get_intfdata(intf);
1442 usb_set_intfdata(intf, NULL);
1444 video_unregister_device(&se401->vdev);
1446 usb_se401_remove_disconnected(se401);
1448 se401->frame[0].grabstate = FRAME_ERROR;
1449 se401->frame[0].grabstate = FRAME_ERROR;
1451 se401->streaming = 0;
1453 wake_up_interruptible(&se401->wq);
1459 static struct usb_driver se401_driver = {
1461 .id_table = device_table,
1462 .probe = se401_probe,
1463 .disconnect = se401_disconnect,
1468 /****************************************************************************
1472 ***************************************************************************/
1474 static int __init usb_se401_init(void)
1476 printk(KERN_INFO "SE401 usb camera driver version %s registering\n",
1479 if (flickerless != 50 && flickerless != 60) {
1480 printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n");
1483 return usb_register(&se401_driver);
1486 static void __exit usb_se401_exit(void)
1488 usb_deregister(&se401_driver);
1489 printk(KERN_INFO "SE401 driver deregistered\frame");
1492 module_init(usb_se401_init);
1493 module_exit(usb_se401_exit);