[ARM] pxa: Gumstix Verdex PCMCIA support
[linux-2.6/verdex.git] / drivers / media / video / se401.c
blob85ffc2cba039b3e6114e5fc8d3bd4671bf9fea20
1 /*
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
16 * for more details.
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.
25 * - Jeroen Vreeken
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>
37 #include "se401.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 */
48 { }
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 /**********************************************************************
66 * Memory management
68 **********************************************************************/
69 static void *rvmalloc(unsigned long size)
71 void *mem;
72 unsigned long adr;
74 size = PAGE_ALIGN(size);
75 mem = vmalloc_32(size);
76 if (!mem)
77 return NULL;
79 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
80 adr = (unsigned long) mem;
81 while (size > 0) {
82 SetPageReserved(vmalloc_to_page((void *)adr));
83 adr += PAGE_SIZE;
84 size -= PAGE_SIZE;
87 return mem;
90 static void rvfree(void *mem, unsigned long size)
92 unsigned long adr;
94 if (!mem)
95 return;
97 adr = (unsigned long) mem;
98 while ((long) size > 0) {
99 ClearPageReserved(vmalloc_to_page((void *)adr));
100 adr += PAGE_SIZE;
101 size -= PAGE_SIZE;
103 vfree(mem);
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(
118 se401->dev,
119 set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
120 req,
121 (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
122 value,
125 size,
126 1000
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(
138 se401->dev,
139 usb_sndctrlpipe(se401->dev, 0),
140 SE401_REQ_SET_EXT_FEATURE,
141 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
142 param,
143 selector,
144 NULL,
146 1000
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
154 wrong here to....
156 unsigned char cp[2];
157 usb_control_msg(
158 se401->dev,
159 usb_rcvctrlpipe(se401->dev, 0),
160 SE401_REQ_GET_EXT_FEATURE,
161 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
163 selector,
166 1000
168 return cp[0]+cp[1]*256;
171 /****************************************************************************
173 * Camera control
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);
188 /* red color gain */
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);
195 return 0;
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;
215 if (se401->enhance)
216 p->whiteness = 32768;
217 else
218 p->whiteness = 0;
220 p->colour = 65535;
221 p->contrast = 65535;
222 p->hue = se401->rgain << 10;
223 p->palette = se401->palette;
224 p->depth = 3; /* rgb24 */
225 return 0;
229 static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
231 if (p->palette != VIDEO_PALETTE_RGB24)
232 return 1;
233 se401->palette = p->palette;
234 if (p->hue != se401->hue) {
235 se401->rgain = p->hue >> 10;
236 se401->bgain = 0x40-(p->hue >> 10);
237 se401->hue = p->hue;
239 if (p->brightness != se401->brightness)
240 se401_set_exposure(se401, p->brightness);
242 if (p->whiteness >= 32768)
243 se401->enhance = 1;
244 else
245 se401->enhance = 0;
246 se401_send_pict(se401);
247 se401_send_pict(se401);
248 return 0;
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... */
273 if (alrc > 10) {
274 while (alrc >= 10 && se401->resetlevel < 63) {
275 se401->resetlevel++;
276 alrc /= 2;
278 } else if (ahrc > 20) {
279 while (ahrc >= 20 && se401->resetlevel > 0) {
280 se401->resetlevel--;
281 ahrc /= 2;
284 if (se401->resetlevel != oldreset)
285 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
287 return;
290 /* irq handler for snapshot button */
291 static void se401_button_irq(struct urb *urb)
293 struct usb_se401 *se401 = urb->context;
294 int status;
296 if (!se401->dev) {
297 dev_info(&urb->dev->dev, "device vapourished\n");
298 return;
301 switch (urb->status) {
302 case 0:
303 /* success */
304 break;
305 case -ECONNRESET:
306 case -ENOENT:
307 case -ESHUTDOWN:
308 /* this urb is terminated, clean up */
309 dbg("%s - urb shutting down with status: %d",
310 __func__, urb->status);
311 return;
312 default:
313 dbg("%s - nonzero urb status received: %d",
314 __func__, urb->status);
315 goto exit;
318 if (urb->actual_length >= 2)
319 if (se401->button)
320 se401->buttonpressed = 1;
321 exit:
322 status = usb_submit_urb(urb, GFP_ATOMIC);
323 if (status)
324 err("%s - usb_submit_urb failed with result %d",
325 __func__, status);
328 static void se401_video_irq(struct urb *urb)
330 struct usb_se401 *se401 = urb->context;
331 int length = urb->actual_length;
333 /* ohoh... */
334 if (!se401->streaming)
335 return;
337 if (!se401->dev) {
338 dev_info(&urb->dev->dev, "device vapourished\n");
339 return;
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) {
348 case BUFFER_READY:
349 case BUFFER_BUSY:
350 se401->dropped++;
351 break;
352 case BUFFER_UNUSED:
353 memcpy(se401->scratch[se401->scratch_next].data,
354 (unsigned char *)urb->transfer_buffer, length);
355 se401->scratch[se401->scratch_next].state
356 = BUFFER_READY;
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;
366 break;
368 se401->bayeroffset += length;
369 if (se401->bayeroffset >= se401->cheight * se401->cwidth)
370 se401->bayeroffset = 0;
371 } else {
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 */
379 urb->status = 0;
380 urb->dev = se401->dev;
381 if (usb_submit_urb(urb, GFP_KERNEL))
382 dev_info(&urb->dev->dev, "urb burned down\n");
383 return;
386 static void se401_send_size(struct usb_se401 *se401, int width, int height)
388 int i = 0;
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))
401 i++;
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];
407 mode = 0x40;
409 if (se401->width[i] == width * 4 &&
410 se401->height[i] == height * 4) {
411 sendheight = se401->height[i];
412 sendwidth = se401->width[i];
413 mode = 0x42;
415 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);
422 if (mode == 0x03)
423 se401->format = FMT_BAYER;
424 else
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)
435 struct urb *urb;
436 int err = 0, i;
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,
450 0, NULL, 0);
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;
464 return -ENOMEM;
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;
479 goto nomem_sbuf;
481 se401->scratch[i].state = BUFFER_UNUSED;
484 for (i = 0; i < SE401_NUMSBUF; i++) {
485 urb = usb_alloc_urb(0, GFP_KERNEL);
486 if (!urb) {
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;
492 goto nomem_scratch;
495 usb_fill_bulk_urb(urb, se401->dev,
496 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
497 se401->sbuf[i].data, SE401_PACKETSIZE,
498 se401_video_irq,
499 se401);
501 se401->urb[i] = urb;
503 err = usb_submit_urb(se401->urb[i], GFP_KERNEL);
504 if (err)
505 err("urb burned down");
508 se401->framecount = 0;
510 return 0;
512 nomem_scratch:
513 for (i = 0; i < SE401_NUMSCRATCH; i++) {
514 kfree(se401->scratch[i].data);
515 se401->scratch[i].data = NULL;
517 nomem_sbuf:
518 for (i = 0; i < SE401_NUMSBUF; i++) {
519 kfree(se401->sbuf[i].data);
520 se401->sbuf[i].data = NULL;
522 return -ENOMEM;
525 static int se401_stop_stream(struct usb_se401 *se401)
527 int i;
529 if (!se401->streaming || !se401->dev)
530 return 1;
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++)
540 if (se401->urb[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;
551 return 0;
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)
559 return 0;
561 /* Check for a valid mode */
562 if (!width || !height)
563 return 1;
564 if ((width & 1) || (height & 1))
565 return 1;
566 if (width > se401->width[se401->sizes-1])
567 return 1;
568 if (height > se401->height[se401->sizes-1])
569 return 1;
571 /* Stop a current stream and start it again at the new size */
572 if (wasstreaming)
573 se401_stop_stream(se401);
574 se401->cwidth = width;
575 se401->cheight = height;
576 if (wasstreaming)
577 se401_start_stream(se401);
578 return 0;
582 /****************************************************************************
584 * Video Decoding
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)
595 while (len--) {
596 *frame = (((*frame^255)*(*frame^255))/255)^255;
597 frame++;
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;
616 else
617 *(frame->curline-frame->curlinepix) =
618 *(frame->curline-frame->curlinepix + 3) + data * 4;
619 frame->curlinepix++;
622 static inline void decode_JangGu_vlc(struct usb_se401 *se401,
623 unsigned char *data, int bit_exp, int packetlength)
625 int pos = 0;
626 int vlc_cod = 0;
627 int vlc_size = 0;
628 int vlc_data = 0;
629 int bit_cur;
630 int bit;
631 data += 4;
632 while (pos < packetlength) {
633 bit_cur = 8;
634 while (bit_cur && bit_exp) {
635 bit = ((*data) >> (bit_cur-1))&1;
636 if (!vlc_cod) {
637 if (bit) {
638 vlc_size++;
639 } else {
640 if (!vlc_size)
641 decode_JangGu_integrate(se401, 0);
642 else {
643 vlc_cod = 2;
644 vlc_data = 0;
647 } else {
648 if (vlc_cod == 2) {
649 if (!bit)
650 vlc_data = -(1 << vlc_size) + 1;
651 vlc_cod--;
653 vlc_size--;
654 vlc_data += bit << vlc_size;
655 if (!vlc_size) {
656 decode_JangGu_integrate(se401, vlc_data);
657 vlc_cod = 0;
660 bit_cur--;
661 bit_exp--;
663 pos++;
664 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;
674 int datapos = 0;
676 /* New image? */
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)
689 size = len-datapos;
690 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
691 se401->vlcdatapos += size;
692 packetlength = 0;
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;
701 datapos = len;
702 packetlength = 0;
703 se401->error++;
704 se401->frame[se401->curframe].curpix = 0;
707 if (packetlength && se401->vlcdatapos >= packetlength) {
708 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp,
709 packetlength);
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;
717 se401->framecount++;
718 se401->readcount++;
720 if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY)
721 se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1);
722 } else
723 se401->error++;
724 se401->frame[se401->curframe].curpix = 0;
725 datapos = len;
727 } else
728 datapos += size;
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 :( */
756 frame->curpix = 0;
757 se401->error++;
758 return;
761 /* Check if we have to much data */
762 if (frame->curpix + len > datasize)
763 len = datasize-frame->curpix;
765 if (se401->cheight % 4)
766 blineoffset = 1;
767 bline = frame->curpix / se401->cwidth+blineoffset;
769 curline = frame->curline;
770 nextline = curline + linelength;
771 if (nextline >= framedata+datasize * 3)
772 nextline = curline;
773 while (len) {
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) {
780 frame->curlinepix++;
781 curline -= 3;
782 nextline -= 3;
783 len--;
784 data++;
785 frame->curpix++;
787 if (nextline >= framedata+datasize*3)
788 nextline = curline;
790 if (bline & 1) {
791 if (frame->curlinepix & 1) {
792 *(curline + 2) = *data;
793 *(curline - 1) = *data;
794 *(nextline + 2) = *data;
795 *(nextline - 1) = *data;
796 } else {
797 *(curline + 1) =
798 (*(curline + 1) + *data) / 2;
799 *(curline-2) =
800 (*(curline - 2) + *data) / 2;
801 *(nextline + 1) = *data;
802 *(nextline - 2) = *data;
804 } else {
805 if (frame->curlinepix & 1) {
806 *(curline + 1) =
807 (*(curline + 1) + *data) / 2;
808 *(curline - 2) =
809 (*(curline - 2) + *data) / 2;
810 *(nextline + 1) = *data;
811 *(nextline - 2) = *data;
812 } else {
813 *curline = *data;
814 *(curline - 3) = *data;
815 *nextline = *data;
816 *(nextline - 3) = *data;
819 frame->curlinepix++;
820 curline -= 3;
821 nextline -= 3;
822 len--;
823 data++;
824 frame->curpix++;
826 frame->curline = curline;
828 if (frame->curpix >= datasize) {
829 /* Fix the top line */
830 framedata += linelength;
831 for (i = 0; i < linelength; i++) {
832 framedata--;
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;
842 frame->curpix = 0;
843 frame->grabstate = FRAME_DONE;
844 se401->framecount++;
845 se401->readcount++;
846 if (se401->frame[(se401->curframe + 1) &
847 (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) {
848 se401->curframe = (se401->curframe+1) &
849 (SE401_NUMFRAMES-1);
854 static int se401_newframe(struct usb_se401 *se401, int framenr)
856 DECLARE_WAITQUEUE(wait, current);
857 int errors = 0;
859 while (se401->streaming &&
860 (se401->frame[framenr].grabstate == FRAME_READY ||
861 se401->frame[framenr].grabstate == FRAME_GRABBING)) {
862 if (!se401->frame[framenr].curpix)
863 errors++;
865 wait_interruptible(
866 se401->scratch[se401->scratch_use].state != BUFFER_READY,
867 &se401->wq, &wait);
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);
874 } else {
875 if (se401->scratch[se401->scratch_use].state !=
876 BUFFER_READY) {
877 se401->frame[framenr].grabstate = FRAME_ERROR;
878 return -EIO;
880 se401->scratch[se401->scratch_use].state = BUFFER_BUSY;
881 if (se401->format == FMT_JANGGU)
882 decode_JangGu(se401,
883 &se401->scratch[se401->scratch_use]);
884 else
885 decode_bayer(se401,
886 &se401->scratch[se401->scratch_use]);
888 se401->scratch[se401->scratch_use].state =
889 BUFFER_UNUSED;
890 se401->scratch_use++;
891 if (se401->scratch_use >= SE401_NUMSCRATCH)
892 se401->scratch_use = 0;
893 if (errors > SE401_MAX_ERRORS) {
894 errors = 0;
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)
904 if (se401->enhance)
905 enhance_picture(se401->frame[framenr].data,
906 se401->cheight * se401->cwidth * 3);
907 return 0;
910 static void usb_se401_remove_disconnected(struct usb_se401 *se401)
912 int i;
914 se401->dev = NULL;
916 for (i = 0; i < SE401_NUMSBUF; i++)
917 if (se401->urb[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);
927 if (se401->inturb) {
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 */
934 kfree(se401->width);
935 kfree(se401->height);
936 kfree(se401);
941 /****************************************************************************
943 * Video4Linux
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;
952 int err = 0;
954 lock_kernel();
955 if (se401->user) {
956 unlock_kernel();
957 return -EBUSY;
959 se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
960 if (se401->fbuf)
961 file->private_data = dev;
962 else
963 err = -ENOMEM;
964 se401->user = !err;
965 unlock_kernel();
967 return err;
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;
974 int i;
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);
980 } else {
981 for (i = 0; i < SE401_NUMFRAMES; i++)
982 se401->frame[i].grabstate = FRAME_UNUSED;
983 if (se401->streaming)
984 se401_stop_stream(se401);
985 se401->user = 0;
987 file->private_data = NULL;
988 return 0;
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;
996 if (!se401->dev)
997 return -EIO;
999 switch (cmd) {
1000 case VIDIOCGCAP:
1002 struct video_capability *b = arg;
1003 strcpy(b->name, se401->camera_name);
1004 b->type = VID_TYPE_CAPTURE;
1005 b->channels = 1;
1006 b->audios = 0;
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];
1011 return 0;
1013 case VIDIOCGCHAN:
1015 struct video_channel *v = arg;
1017 if (v->channel != 0)
1018 return -EINVAL;
1019 v->flags = 0;
1020 v->tuners = 0;
1021 v->type = VIDEO_TYPE_CAMERA;
1022 strcpy(v->name, "Camera");
1023 return 0;
1025 case VIDIOCSCHAN:
1027 struct video_channel *v = arg;
1029 if (v->channel != 0)
1030 return -EINVAL;
1031 return 0;
1033 case VIDIOCGPICT:
1035 struct video_picture *p = arg;
1037 se401_get_pict(se401, p);
1038 return 0;
1040 case VIDIOCSPICT:
1042 struct video_picture *p = arg;
1044 if (se401_set_pict(se401, p))
1045 return -EINVAL;
1046 return 0;
1048 case VIDIOCSWIN:
1050 struct video_window *vw = arg;
1052 if (vw->flags)
1053 return -EINVAL;
1054 if (vw->clipcount)
1055 return -EINVAL;
1056 if (se401_set_size(se401, vw->width, vw->height))
1057 return -EINVAL;
1058 return 0;
1060 case VIDIOCGWIN:
1062 struct video_window *vw = arg;
1064 vw->x = 0; /* FIXME */
1065 vw->y = 0;
1066 vw->chromakey = 0;
1067 vw->flags = 0;
1068 vw->clipcount = 0;
1069 vw->width = se401->cwidth;
1070 vw->height = se401->cheight;
1071 return 0;
1073 case VIDIOCGMBUF:
1075 struct video_mbuf *vm = arg;
1076 int i;
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;
1083 return 0;
1085 case VIDIOCMCAPTURE:
1087 struct video_mmap *vm = arg;
1089 if (vm->format != VIDEO_PALETTE_RGB24)
1090 return -EINVAL;
1091 if (vm->frame >= SE401_NUMFRAMES)
1092 return -EINVAL;
1093 if (se401->frame[vm->frame].grabstate != FRAME_UNUSED)
1094 return -EBUSY;
1096 /* Is this according to the v4l spec??? */
1097 if (se401_set_size(se401, vm->width, vm->height))
1098 return -EINVAL;
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);
1111 return 0;
1113 case VIDIOCSYNC:
1115 int *frame = arg;
1116 int ret = 0;
1118 if (*frame < 0 || *frame >= SE401_NUMFRAMES)
1119 return -EINVAL;
1121 ret = se401_newframe(se401, *frame);
1122 se401->frame[*frame].grabstate = FRAME_UNUSED;
1123 return ret;
1125 case VIDIOCGFBUF:
1127 struct video_buffer *vb = arg;
1129 memset(vb, 0, sizeof(*vb));
1130 return 0;
1132 case VIDIOCKEY:
1133 return 0;
1134 case VIDIOCCAPTURE:
1135 return -EINVAL;
1136 case VIDIOCSFBUF:
1137 return -EINVAL;
1138 case VIDIOCGTUNER:
1139 case VIDIOCSTUNER:
1140 return -EINVAL;
1141 case VIDIOCGFREQ:
1142 case VIDIOCSFREQ:
1143 return -EINVAL;
1144 case VIDIOCGAUDIO:
1145 case VIDIOCSAUDIO:
1146 return -EINVAL;
1147 default:
1148 return -ENOIOCTLCMD;
1149 } /* end switch */
1151 return 0;
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)
1169 return -EIO;
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)
1175 return -EBUSY;
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;
1193 if (ret)
1194 return ret;
1195 if (copy_to_user(buf, se401->frame[0].data, realcount))
1196 return -EFAULT;
1198 return 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);
1213 return -EIO;
1215 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1)
1216 & ~(PAGE_SIZE - 1))) {
1217 mutex_unlock(&se401->lock);
1218 return -EINVAL;
1220 pos = (unsigned long)se401->fbuf;
1221 while (size > 0) {
1222 page = vmalloc_to_pfn((void *)pos);
1223 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1224 mutex_unlock(&se401->lock);
1225 return -EAGAIN;
1227 start += PAGE_SIZE;
1228 pos += PAGE_SIZE;
1229 if (size > PAGE_SIZE)
1230 size -= PAGE_SIZE;
1231 else
1232 size = 0;
1234 mutex_unlock(&se401->lock);
1236 return 0;
1239 static const struct v4l2_file_operations se401_fops = {
1240 .owner = THIS_MODULE,
1241 .open = se401_open,
1242 .release = se401_close,
1243 .read = se401_read,
1244 .mmap = se401_mmap,
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)
1258 int i = 0, rc;
1259 unsigned char cp[0x40];
1260 char temp[200];
1261 int slen;
1263 /* led on */
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,
1268 cp, sizeof(cp));
1269 if (cp[1] != 0x41) {
1270 err("Wrong descriptor type");
1271 return 1;
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);
1277 if (!se401->width)
1278 return 1;
1279 se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1280 if (!se401->height) {
1281 kfree(se401->width);
1282 return 1;
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!");
1304 return 1;
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;
1319 se401->enhance = 1;
1320 se401->dropped = 0;
1321 se401->error = 0;
1322 se401->framecount = 0;
1323 se401->readcount = 0;
1325 /* Start interrupt transfers for snapshot button */
1326 if (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");
1331 return 1;
1333 usb_fill_int_urb(se401->inturb, se401->dev,
1334 usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1335 &se401->button, sizeof(se401->button),
1336 se401_button_irq,
1337 se401,
1340 if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
1341 dev_info(&se401->dev->dev, "int urb burned down\n");
1342 return 1;
1344 } else
1345 se401->inturb = NULL;
1347 /* Flash the led */
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);
1353 return 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;
1363 int button = 1;
1365 /* We don't handle multi-config cameras */
1366 if (dev->descriptor.bNumConfigurations != 1)
1367 return -ENODEV;
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";
1387 button = 0;
1388 } else
1389 return -ENODEV;
1391 /* Checking vendor/product should be enough, but what the hell */
1392 if (interface->bInterfaceClass != 0x00)
1393 return -ENODEV;
1394 if (interface->bInterfaceSubClass != 0x00)
1395 return -ENODEV;
1397 /* We found one */
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");
1403 return -ENOMEM;
1406 se401->dev = dev;
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)) {
1414 kfree(se401);
1415 return -EIO;
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);
1423 wmb();
1425 if (video_register_device(&se401->vdev,
1426 VFL_TYPE_GRABBER, video_nr) < 0) {
1427 kfree(se401);
1428 err("video_register_device failed");
1429 return -EIO;
1431 dev_info(&intf->dev, "registered new video device: video%d\n",
1432 se401->vdev.num);
1434 usb_set_intfdata(intf, se401);
1435 return 0;
1438 static void se401_disconnect(struct usb_interface *intf)
1440 struct usb_se401 *se401 = usb_get_intfdata(intf);
1442 usb_set_intfdata(intf, NULL);
1443 if (se401) {
1444 video_unregister_device(&se401->vdev);
1445 if (!se401->user)
1446 usb_se401_remove_disconnected(se401);
1447 else {
1448 se401->frame[0].grabstate = FRAME_ERROR;
1449 se401->frame[0].grabstate = FRAME_ERROR;
1451 se401->streaming = 0;
1453 wake_up_interruptible(&se401->wq);
1454 se401->removed = 1;
1459 static struct usb_driver se401_driver = {
1460 .name = "se401",
1461 .id_table = device_table,
1462 .probe = se401_probe,
1463 .disconnect = se401_disconnect,
1468 /****************************************************************************
1470 * Module routines
1472 ***************************************************************************/
1474 static int __init usb_se401_init(void)
1476 printk(KERN_INFO "SE401 usb camera driver version %s registering\n",
1477 version);
1478 if (flickerless)
1479 if (flickerless != 50 && flickerless != 60) {
1480 printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n");
1481 return -1;
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);