File: /usr/src/linux/drivers/usb/se401.c
1 /*
2 * Endpoints (formerly known as AOX) se401 USB Camera Driver
3 *
4 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
5 *
6 * Still somewhat based on the Linux ov511 driver.
7 *
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.
12 *
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.
17 *
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.
21 *
22 *
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
26 */
27
28 static const char version[] = "0.23";
29
30 #include <linux/config.h>
31 #include <linux/module.h>
32 #include <linux/version.h>
33 #include <linux/init.h>
34 #include <linux/fs.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>
40 #include <asm/io.h>
41 #include <asm/semaphore.h>
42 #include <linux/wrapper.h>
43
44 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
45 #define virt_to_page(arg) MAP_NR(arg)
46 #define vmalloc_32 vmalloc
47 #endif
48
49 #include "se401.h"
50
51 static int flickerless=0;
52 static int video_nr = -1;
53
54 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 0)
55 static __devinitdata struct usb_device_id device_table [] = {
56 { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
57 { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
58 { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
59 { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
60 { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
61 { }
62 };
63
64 MODULE_DEVICE_TABLE(usb, device_table);
65 #endif
66
67 MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
68 MODULE_DESCRIPTION("SE401 USB Camera Driver");
69 MODULE_LICENSE("GPL");
70 MODULE_PARM(flickerless, "i");
71 MODULE_PARM_DESC(flickerless, "Net frequency to adjust exposure time to (0/50/60)");
72 MODULE_PARM(video_nr, "i");
73 EXPORT_NO_SYMBOLS;
74
75
76 static struct usb_driver se401_driver;
77
78
79 /**********************************************************************
80 *
81 * Memory management
82 *
83 * This is a shameless copy from the USB-cpia driver (linux kernel
84 * version 2.3.29 or so, I have no idea what this code actually does ;).
85 * Actually it seems to be a copy of a shameless copy of the bttv-driver.
86 * Or that is a copy of a shameless copy of ... (To the powers: is there
87 * no generic kernel-function to do this sort of stuff?)
88 *
89 * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
90 * there will be one, but apparentely not yet -jerdfelt
91 *
92 * So I copied it again for the ov511 driver -claudio
93 *
94 * Same for the se401 driver -Jeroen
95 **********************************************************************/
96
97 /* Given PGD from the address space's page table, return the kernel
98 * virtual mapping of the physical memory mapped at ADR.
99 */
100 static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
101 {
102 unsigned long ret = 0UL;
103 pmd_t *pmd;
104 pte_t *ptep, pte;
105
106 if (!pgd_none(*pgd)) {
107 pmd = pmd_offset(pgd, adr);
108 if (!pmd_none(*pmd)) {
109 ptep = pte_offset(pmd, adr);
110 pte = *ptep;
111 if (pte_present(pte)) {
112 ret = (unsigned long) page_address(pte_page(pte));
113 ret |= (adr & (PAGE_SIZE - 1));
114 }
115 }
116 }
117
118 return ret;
119 }
120
121 /* Here we want the physical address of the memory.
122 * This is used when initializing the contents of the
123 * area and marking the pages as reserved.
124 */
125 static inline unsigned long kvirt_to_pa(unsigned long adr)
126 {
127 unsigned long va, kva, ret;
128
129 va = VMALLOC_VMADDR(adr);
130 kva = uvirt_to_kva(pgd_offset_k(va), va);
131 ret = __pa(kva);
132 return ret;
133 }
134
135 static void *rvmalloc(unsigned long size)
136 {
137 void *mem;
138 unsigned long adr, page;
139
140 /* Round it off to PAGE_SIZE */
141 size += (PAGE_SIZE - 1);
142 size &= ~(PAGE_SIZE - 1);
143
144 mem = vmalloc_32(size);
145 if (!mem)
146 return NULL;
147
148 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
149 adr = (unsigned long) mem;
150 while (size > 0) {
151 page = kvirt_to_pa(adr);
152 mem_map_reserve(virt_to_page(__va(page)));
153 adr += PAGE_SIZE;
154 if (size > PAGE_SIZE)
155 size -= PAGE_SIZE;
156 else
157 size = 0;
158 }
159
160 return mem;
161 }
162
163 static void rvfree(void *mem, unsigned long size)
164 {
165 unsigned long adr, page;
166
167 if (!mem)
168 return;
169
170 size += (PAGE_SIZE - 1);
171 size &= ~(PAGE_SIZE - 1);
172
173 adr=(unsigned long) mem;
174 while (size > 0) {
175 page = kvirt_to_pa(adr);
176 mem_map_unreserve(virt_to_page(__va(page)));
177 adr += PAGE_SIZE;
178 if (size > PAGE_SIZE)
179 size -= PAGE_SIZE;
180 else
181 size = 0;
182 }
183 vfree(mem);
184 }
185
186
187
188 /****************************************************************************
189 *
190 * /proc interface
191 *
192 ***************************************************************************/
193
194 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
195
196 static struct proc_dir_entry *se401_proc_entry = NULL;
197 extern struct proc_dir_entry *video_proc_entry;
198
199 #define YES_NO(x) ((x) ? "yes" : "no")
200
201 static int se401_read_proc(char *page, char **start, off_t off, int count,
202 int *eof, void *data)
203 {
204 char *out = page;
205 int i, len;
206 struct usb_se401 *se401 = data;
207
208 /* Stay under PAGE_SIZE or else bla bla bla.... */
209
210 out+=sprintf(out, "driver_version : %s\n", version);
211 out+=sprintf(out, "model : %s\n", se401->camera_name);
212 out+=sprintf(out, "in use : %s\n", YES_NO (se401->user));
213 out+=sprintf(out, "streaming : %s\n", YES_NO (se401->streaming));
214 out+=sprintf(out, "button state : %s\n", YES_NO (se401->button));
215 out+=sprintf(out, "button pressed : %s\n", YES_NO (se401->buttonpressed));
216 out+=sprintf(out, "num_frames : %d\n", SE401_NUMFRAMES);
217
218 out+=sprintf(out, "Sizes :");
219 for (i=0; i<se401->sizes; i++) {
220 out+=sprintf(out, " %dx%d", se401->width[i],
221 se401->height[i]);
222 }
223 out+=sprintf(out, "\n");
224
225 out+=sprintf(out, "Frames total : %d\n", se401->readcount);
226 out+=sprintf(out, "Frames read : %d\n", se401->framecount);
227 out+=sprintf(out, "Packets dropped : %d\n", se401->dropped);
228 out+=sprintf(out, "Decoding Errors : %d\n", se401->error);
229
230 len = out - page;
231 len -= off;
232 if (len < count) {
233 *eof = 1;
234 if (len <= 0) return 0;
235 } else
236 len = count;
237
238 *start = page + off;
239
240 return len;
241 }
242
243 static int se401_write_proc(struct file *file, const char *buffer,
244 unsigned long count, void *data)
245 {
246 return -EINVAL;
247 }
248
249 static void create_proc_se401_cam (struct usb_se401 *se401)
250 {
251 char name[7];
252 struct proc_dir_entry *ent;
253
254 if (!se401_proc_entry || !se401)
255 return;
256
257 sprintf (name, "video%d", se401->vdev.minor);
258
259 ent = create_proc_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
260 se401_proc_entry);
261
262 if (!ent)
263 return;
264
265 ent->data = se401;
266 ent->read_proc = se401_read_proc;
267 ent->write_proc = se401_write_proc;
268 se401->proc_entry = ent;
269 }
270
271 static void destroy_proc_se401_cam (struct usb_se401 *se401)
272 {
273 /* One to much, just to be sure :) */
274 char name[9];
275
276 if (!se401 || !se401->proc_entry)
277 return;
278
279 sprintf(name, "video%d", se401->vdev.minor);
280 remove_proc_entry(name, se401_proc_entry);
281 se401->proc_entry = NULL;
282 }
283
284 static void proc_se401_create (void)
285 {
286 if (video_proc_entry == NULL) {
287 err("/proc/video/ doesn't exist");
288 return;
289 }
290
291 se401_proc_entry=create_proc_entry("se401", S_IFDIR, video_proc_entry);
292
293 if (se401_proc_entry)
294 se401_proc_entry->owner = THIS_MODULE;
295 else
296 err("Unable to initialize /proc/video/se401");
297 }
298
299 static void proc_se401_destroy(void)
300 {
301 if (se401_proc_entry == NULL)
302 return;
303
304 remove_proc_entry("se401", video_proc_entry);
305 }
306 #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
307
308
309 /****************************************************************************
310 *
311 * se401 register read/write functions
312 *
313 ***************************************************************************/
314
315 static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
316 unsigned short value, unsigned char *cp, int size)
317 {
318 return usb_control_msg (
319 se401->dev,
320 set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
321 req,
322 (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
323 value,
324 0,
325 cp,
326 size,
327 HZ
328 );
329 }
330
331 static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
332 unsigned short param)
333 {
334 /* specs say that the selector (address) should go in the value field
335 and the param in index, but in the logs of the windows driver they do
336 this the other way around...
337 */
338 return usb_control_msg (
339 se401->dev,
340 usb_sndctrlpipe(se401->dev, 0),
341 SE401_REQ_SET_EXT_FEATURE,
342 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
343 param,
344 selector,
345 NULL,
346 0,
347 HZ
348 );
349 }
350
351 static unsigned short se401_get_feature(struct usb_se401 *se401,
352 unsigned short selector)
353 {
354 /* For 'set' the selecetor should be in index, not sure if the spec is
355 wrong here to....
356 */
357 unsigned char cp[2];
358 usb_control_msg (
359 se401->dev,
360 usb_rcvctrlpipe(se401->dev, 0),
361 SE401_REQ_GET_EXT_FEATURE,
362 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
363 0,
364 selector,
365 cp,
366 2,
367 HZ
368 );
369 return cp[0]+cp[1]*256;
370 }
371
372 /****************************************************************************
373 *
374 * Camera control
375 *
376 ***************************************************************************/
377
378
379 static int se401_send_pict(struct usb_se401 *se401)
380 {
381 se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);/* integration time low */
382 se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);/* integration time mid */
383 se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);/* integration time mid */
384 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);/* reset level value */
385 se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);/* red color gain */
386 se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);/* green color gain */
387 se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);/* blue color gain */
388
389 return 0;
390 }
391
392 static void se401_set_exposure(struct usb_se401 *se401, int brightness)
393 {
394 int integration=brightness<<5;
395
396 if (flickerless==50) {
397 integration=integration-integration%106667;
398 }
399 if (flickerless==60) {
400 integration=integration-integration%88889;
401 }
402 se401->brightness=integration>>5;
403 se401->expose_h=(integration>>16)&0xff;
404 se401->expose_m=(integration>>8)&0xff;
405 se401->expose_l=integration&0xff;
406 }
407
408 static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
409 {
410 p->brightness=se401->brightness;
411 if (se401->enhance) {
412 p->whiteness=32768;
413 } else {
414 p->whiteness=0;
415 }
416 p->colour=65535;
417 p->contrast=65535;
418 p->hue=se401->rgain<<10;
419 p->palette=se401->palette;
420 p->depth=3; /* rgb24 */
421 return 0;
422 }
423
424
425 static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
426 {
427 if (p->palette != VIDEO_PALETTE_RGB24)
428 return 1;
429 se401->palette=p->palette;
430 if (p->hue!=se401->hue) {
431 se401->rgain= p->hue>>10;
432 se401->bgain= 0x40-(p->hue>>10);
433 se401->hue=p->hue;
434 }
435 if (p->brightness!=se401->brightness) {
436 se401_set_exposure(se401, p->brightness);
437 }
438 if (p->whiteness>=32768) {
439 se401->enhance=1;
440 } else {
441 se401->enhance=0;
442 }
443 se401_send_pict(se401);
444 se401_send_pict(se401);
445 return 0;
446 }
447
448 /*
449 Hyundai have some really nice docs about this and other sensor related
450 stuff on their homepage: www.hei.co.kr
451 */
452 static void se401_auto_resetlevel(struct usb_se401 *se401)
453 {
454 unsigned int ahrc, alrc;
455 int oldreset=se401->resetlevel;
456
457 /* For some reason this normally read-only register doesn't get reset
458 to zero after reading them just once...
459 */
460 se401_get_feature(se401, HV7131_REG_HIREFNOH);
461 se401_get_feature(se401, HV7131_REG_HIREFNOL);
462 se401_get_feature(se401, HV7131_REG_LOREFNOH);
463 se401_get_feature(se401, HV7131_REG_LOREFNOL);
464 ahrc=256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
465 se401_get_feature(se401, HV7131_REG_HIREFNOL);
466 alrc=256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
467 se401_get_feature(se401, HV7131_REG_LOREFNOL);
468
469 /* Not an exact science, but it seems to work pretty well... */
470 if (alrc > 10) {
471 while (alrc>=10 && se401->resetlevel < 63) {
472 se401->resetlevel++;
473 alrc /=2;
474 }
475 } else if (ahrc > 20) {
476 while (ahrc>=20 && se401->resetlevel > 0) {
477 se401->resetlevel--;
478 ahrc /=2;
479 }
480 }
481 if (se401->resetlevel!=oldreset)
482 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
483
484 return;
485 }
486
487 /* irq handler for snapshot button */
488 static void se401_button_irq(struct urb *urb)
489 {
490 struct usb_se401 *se401 = urb->context;
491
492 if (!se401->dev) {
493 info("ohoh: device vapourished");
494 return;
495 }
496
497 if (urb->actual_length >=2 && !urb->status) {
498 if (se401->button)
499 se401->buttonpressed=1;
500 }
501 }
502
503 static void se401_video_irq(struct urb *urb)
504 {
505 struct usb_se401 *se401 = urb->context;
506 int length = urb->actual_length;
507
508 /* ohoh... */
509 if (!se401->streaming)
510 return;
511
512 if (!se401->dev) {
513 info ("ohoh: device vapourished");
514 return;
515 }
516
517 /* 0 sized packets happen if we are to fast, but sometimes the camera
518 keeps sending them forever...
519 */
520 if (length && !urb->status) {
521 se401->nullpackets=0;
522 switch(se401->scratch[se401->scratch_next].state) {
523 case BUFFER_READY:
524 case BUFFER_BUSY: {
525 se401->dropped++;
526 break;
527 }
528 case BUFFER_UNUSED: {
529 memcpy(se401->scratch[se401->scratch_next].data, (unsigned char *)urb->transfer_buffer, length);
530 se401->scratch[se401->scratch_next].state=BUFFER_READY;
531 se401->scratch[se401->scratch_next].offset=se401->bayeroffset;
532 se401->scratch[se401->scratch_next].length=length;
533 if (waitqueue_active(&se401->wq)) {
534 wake_up_interruptible(&se401->wq);
535 }
536 se401->scratch_overflow=0;
537 se401->scratch_next++;
538 if (se401->scratch_next>=SE401_NUMSCRATCH)
539 se401->scratch_next=0;;
540 break;
541 }
542 }
543 se401->bayeroffset+=length;
544 if (se401->bayeroffset>=se401->cheight*se401->cwidth) {
545 se401->bayeroffset=0;
546 }
547 } else {
548 se401->nullpackets++;
549 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
550 if (waitqueue_active(&se401->wq)) {
551 wake_up_interruptible(&se401->wq);
552 }
553 }
554 }
555
556 /* Resubmit urb for new data */
557 urb->status=0;
558 urb->dev=se401->dev;
559 if(usb_submit_urb(urb))
560 info("urb burned down");
561 return;
562 }
563
564 static void se401_send_size(struct usb_se401 *se401, int width, int height)
565 {
566 int i=0;
567 int mode=0x03; /* No compression */
568 int sendheight=height;
569 int sendwidth=width;
570
571 /* JangGu compression can only be used with the camera supported sizes,
572 but bayer seems to work with any size that fits on the sensor.
573 We check if we can use compression with the current size with either
574 4 or 16 times subcapturing, if not we use uncompressed bayer data
575 but this will result in cutouts of the maximum size....
576 */
577 while (i<se401->sizes && !(se401->width[i]==width && se401->height[i]==height))
578 i++;
579 while (i<se401->sizes) {
580 if (se401->width[i]==width*2 && se401->height[i]==height*2) {
581 sendheight=se401->height[i];
582 sendwidth=se401->width[i];
583 mode=0x40;
584 }
585 if (se401->width[i]==width*4 && se401->height[i]==height*4) {
586 sendheight=se401->height[i];
587 sendwidth=se401->width[i];
588 mode=0x42;
589 }
590 i++;
591 }
592
593 se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
594 se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
595 se401_set_feature(se401, SE401_OPERATINGMODE, mode);
596
597 if (mode==0x03) {
598 se401->format=FMT_BAYER;
599 } else {
600 se401->format=FMT_JANGGU;
601 }
602
603 return;
604 }
605
606 /*
607 In this function se401_send_pict is called several times,
608 for some reason (depending on the state of the sensor and the phase of
609 the moon :) doing this only in either place doesn't always work...
610 */
611 static int se401_start_stream(struct usb_se401 *se401)
612 {
613 urb_t *urb;
614 int err=0, i;
615 se401->streaming=1;
616
617 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
618 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
619
620 /* Set picture settings */
621 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);/*windowed + pix intg */
622 se401_send_pict(se401);
623
624 se401_send_size(se401, se401->cwidth, se401->cheight);
625
626 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE, 0, NULL, 0);
627
628 /* Do some memory allocation */
629 for (i=0; i<SE401_NUMFRAMES; i++) {
630 se401->frame[i].data=se401->fbuf + i * se401->maxframesize;
631 se401->frame[i].curpix=0;
632 }
633 for (i=0; i<SE401_NUMSBUF; i++) {
634 se401->sbuf[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
635 }
636
637 se401->bayeroffset=0;
638 se401->scratch_next=0;
639 se401->scratch_use=0;
640 se401->scratch_overflow=0;
641 for (i=0; i<SE401_NUMSCRATCH; i++) {
642 se401->scratch[i].data=kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
643 se401->scratch[i].state=BUFFER_UNUSED;
644 }
645
646 for (i=0; i<SE401_NUMSBUF; i++) {
647 urb=usb_alloc_urb(0);
648 if(!urb)
649 return ENOMEM;
650
651 FILL_BULK_URB(urb, se401->dev,
652 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
653 se401->sbuf[i].data, SE401_PACKETSIZE,
654 se401_video_irq,
655 se401);
656 urb->transfer_flags |= USB_QUEUE_BULK;
657
658 se401->urb[i]=urb;
659
660 err=usb_submit_urb(se401->urb[i]);
661 if(err)
662 err("urb burned down");
663 }
664
665 se401->framecount=0;
666
667 return 0;
668 }
669
670 static int se401_stop_stream(struct usb_se401 *se401)
671 {
672 int i;
673
674 if (!se401->streaming || !se401->dev)
675 return 1;
676
677 se401->streaming=0;
678
679 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
680
681 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
682 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
683
684 for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
685 se401->urb[i]->next=NULL;
686 usb_unlink_urb(se401->urb[i]);
687 usb_free_urb(se401->urb[i]);
688 se401->urb[i]=NULL;
689 kfree(se401->sbuf[i].data);
690 }
691 for (i=0; i<SE401_NUMSCRATCH; i++) {
692 kfree(se401->scratch[i].data);
693 se401->scratch[i].data=NULL;
694 }
695
696 return 0;
697 }
698
699 static int se401_set_size(struct usb_se401 *se401, int width, int height)
700 {
701 int wasstreaming=se401->streaming;
702 /* Check to see if we need to change */
703 if (se401->cwidth==width && se401->cheight==height)
704 return 0;
705
706 /* Check for a valid mode */
707 if (!width || !height)
708 return 1;
709 if ((width & 1) || (height & 1))
710 return 1;
711 if (width>se401->width[se401->sizes-1])
712 return 1;
713 if (height>se401->height[se401->sizes-1])
714 return 1;
715
716 /* Stop a current stream and start it again at the new size */
717 if (wasstreaming)
718 se401_stop_stream(se401);
719 se401->cwidth=width;
720 se401->cheight=height;
721 if (wasstreaming)
722 se401_start_stream(se401);
723 return 0;
724 }
725
726
727 /****************************************************************************
728 *
729 * Video Decoding
730 *
731 ***************************************************************************/
732
733 /*
734 This shouldn't really be done in a v4l driver....
735 But it does make the image look a lot more usable.
736 Basicly it lifts the dark pixels more than the light pixels.
737 */
738 static inline void enhance_picture(unsigned char *frame, int len)
739 {
740 while (len--) {
741 *frame++=(((*frame^255)*(*frame^255))/255)^255;
742 }
743 }
744
745 static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
746 {
747 struct se401_frame *frame=&se401->frame[se401->curframe];
748 int linelength=se401->cwidth*3;
749
750 if (frame->curlinepix >= linelength) {
751 frame->curlinepix=0;
752 frame->curline+=linelength;
753 }
754
755 /* First three are absolute, all others relative.
756 * Format is rgb from right to left (mirrorred image),
757 * we flip it to get bgr from left to right. */
758 if (frame->curlinepix < 3) {
759 *(frame->curline-frame->curlinepix)=1+data*4;
760 } else {
761 *(frame->curline-frame->curlinepix)=
762 *(frame->curline-frame->curlinepix+3)+data*4;
763 }
764 frame->curlinepix++;
765 }
766
767 static inline void decode_JangGu_vlc (struct usb_se401 *se401, unsigned char *data, int bit_exp, int packetlength)
768 {
769 int pos=0;
770 int vlc_cod=0;
771 int vlc_size=0;
772 int vlc_data=0;
773 int bit_cur;
774 int bit;
775 data+=4;
776 while (pos < packetlength) {
777 bit_cur=8;
778 while (bit_cur && bit_exp) {
779 bit=((*data)>>(bit_cur-1))&1;
780 if (!vlc_cod) {
781 if (bit) {
782 vlc_size++;
783 } else {
784 if (!vlc_size) {
785 decode_JangGu_integrate(se401, 0);
786 } else {
787 vlc_cod=2;
788 vlc_data=0;
789 }
790 }
791 } else {
792 if (vlc_cod==2) {
793 if (!bit) vlc_data=-(1<<vlc_size)+1;
794 vlc_cod--;
795 }
796 vlc_size--;
797 vlc_data+=bit<<vlc_size;
798 if (!vlc_size) {
799 decode_JangGu_integrate(se401, vlc_data);
800 vlc_cod=0;
801 }
802 }
803 bit_cur--;
804 bit_exp--;
805 }
806 pos++;
807 data++;
808 }
809 }
810
811 static inline void decode_JangGu (struct usb_se401 *se401, struct se401_scratch *buffer)
812 {
813 unsigned char *data=buffer->data;
814 int len=buffer->length;
815 int bit_exp=0, pix_exp=0, frameinfo=0, packetlength=0, size;
816 int datapos=0;
817
818 /* New image? */
819 if (!se401->frame[se401->curframe].curpix) {
820 se401->frame[se401->curframe].curlinepix=0;
821 se401->frame[se401->curframe].curline=
822 se401->frame[se401->curframe].data+
823 se401->cwidth*3-1;
824 if (se401->frame[se401->curframe].grabstate==FRAME_READY)
825 se401->frame[se401->curframe].grabstate=FRAME_GRABBING;
826 se401->vlcdatapos=0;
827 }
828 while (datapos < len) {
829 size=1024-se401->vlcdatapos;
830 if (size+datapos > len)
831 size=len-datapos;
832 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
833 se401->vlcdatapos+=size;
834 packetlength=0;
835 if (se401->vlcdatapos >= 4) {
836 bit_exp=se401->vlcdata[3]+(se401->vlcdata[2]<<8);
837 pix_exp=se401->vlcdata[1]+((se401->vlcdata[0]&0x3f)<<8);
838 frameinfo=se401->vlcdata[0]&0xc0;
839 packetlength=((bit_exp+47)>>4)<<1;
840 if (packetlength > 1024) {
841 se401->vlcdatapos=0;
842 datapos=len;
843 packetlength=0;
844 se401->error++;
845 se401->frame[se401->curframe].curpix=0;
846 }
847 }
848 if (packetlength && se401->vlcdatapos >= packetlength) {
849 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp, packetlength);
850 se401->frame[se401->curframe].curpix+=pix_exp*3;
851 datapos+=size-(se401->vlcdatapos-packetlength);
852 se401->vlcdatapos=0;
853 if (se401->frame[se401->curframe].curpix>=se401->cwidth*se401->cheight*3) {
854 if (se401->frame[se401->curframe].curpix==se401->cwidth*se401->cheight*3) {
855 if (se401->frame[se401->curframe].grabstate==FRAME_GRABBING) {
856 se401->frame[se401->curframe].grabstate=FRAME_DONE;
857 se401->framecount++;
858 se401->readcount++;
859 }
860 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
861 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
862 }
863 } else {
864 se401->error++;
865 }
866 se401->frame[se401->curframe].curpix=0;
867 datapos=len;
868 }
869 } else {
870 datapos+=size;
871 }
872 }
873 }
874
875 static inline void decode_bayer (struct usb_se401 *se401, struct se401_scratch *buffer)
876 {
877 unsigned char *data=buffer->data;
878 int len=buffer->length;
879 int offset=buffer->offset;
880 int datasize=se401->cwidth*se401->cheight;
881 struct se401_frame *frame=&se401->frame[se401->curframe];
882
883 unsigned char *framedata=frame->data, *curline, *nextline;
884 int width=se401->cwidth;
885 int blineoffset=0, bline;
886 int linelength=width*3, i;
887
888
889 if (frame->curpix==0) {
890 if (frame->grabstate==FRAME_READY) {
891 frame->grabstate=FRAME_GRABBING;
892 }
893 frame->curline=framedata+linelength;
894 frame->curlinepix=0;
895 }
896
897 if (offset!=frame->curpix) {
898 /* Regard frame as lost :( */
899 frame->curpix=0;
900 se401->error++;
901 return;
902 }
903
904 /* Check if we have to much data */
905 if (frame->curpix+len > datasize) {
906 len=datasize-frame->curpix;
907 }
908 if (se401->cheight%4)
909 blineoffset=1;
910 bline=frame->curpix/se401->cwidth+blineoffset;
911
912 curline=frame->curline;
913 nextline=curline+linelength;
914 if (nextline >= framedata+datasize*3)
915 nextline=curline;
916 while (len) {
917 if (frame->curlinepix>=width) {
918 frame->curlinepix-=width;
919 bline=frame->curpix/width+blineoffset;
920 curline+=linelength*2;
921 nextline+=linelength*2;
922 if (curline >= framedata+datasize*3) {
923 frame->curlinepix++;
924 curline-=3;
925 nextline-=3;
926 len--;
927 data++;
928 frame->curpix++;
929 }
930 if (nextline >= framedata+datasize*3)
931 nextline=curline;
932 }
933 if ((bline&1)) {
934 if ((frame->curlinepix&1)) {
935 *(curline+2)=*data;
936 *(curline-1)=*data;
937 *(nextline+2)=*data;
938 *(nextline-1)=*data;
939 } else {
940 *(curline+1)=
941 (*(curline+1)+*data)/2;
942 *(curline-2)=
943 (*(curline-2)+*data)/2;
944 *(nextline+1)=*data;
945 *(nextline-2)=*data;
946 }
947 } else {
948 if ((frame->curlinepix&1)) {
949 *(curline+1)=
950 (*(curline+1)+*data)/2;
951 *(curline-2)=
952 (*(curline-2)+*data)/2;
953 *(nextline+1)=*data;
954 *(nextline-2)=*data;
955 } else {
956 *curline=*data;
957 *(curline-3)=*data;
958 *nextline=*data;
959 *(nextline-3)=*data;
960 }
961 }
962 frame->curlinepix++;
963 curline-=3;
964 nextline-=3;
965 len--;
966 data++;
967 frame->curpix++;
968 }
969 frame->curline=curline;
970
971 if (frame->curpix>=datasize) {
972 /* Fix the top line */
973 framedata+=linelength;
974 for (i=0; i<linelength; i++) {
975 *--framedata=*(framedata+linelength);
976 }
977 /* Fix the left side (green is already present) */
978 for (i=0; i<se401->cheight; i++) {
979 *framedata=*(framedata+3);
980 *(framedata+1)=*(framedata+4);
981 *(framedata+2)=*(framedata+5);
982 framedata+=linelength;
983 }
984 frame->curpix=0;
985 frame->grabstate=FRAME_DONE;
986 se401->framecount++;
987 se401->readcount++;
988 if (se401->frame[(se401->curframe+1)&(SE401_NUMFRAMES-1)].grabstate==FRAME_READY) {
989 se401->curframe=(se401->curframe+1) & (SE401_NUMFRAMES-1);
990 }
991 }
992 }
993
994 static int se401_newframe(struct usb_se401 *se401, int framenr)
995 {
996 DECLARE_WAITQUEUE(wait, current);
997 int errors=0;
998
999 while (se401->streaming &&
1000 (se401->frame[framenr].grabstate==FRAME_READY ||
1001 se401->frame[framenr].grabstate==FRAME_GRABBING) ) {
1002 if(!se401->frame[framenr].curpix) {
1003 errors++;
1004 }
1005 wait_interruptible(
1006 se401->scratch[se401->scratch_use].state!=BUFFER_READY,
1007 &se401->wq,
1008 &wait
1009 );
1010 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
1011 se401->nullpackets=0;
1012 info("to many null length packets, restarting capture");
1013 se401_stop_stream(se401);
1014 se401_start_stream(se401);
1015 } else {
1016 if (se401->scratch[se401->scratch_use].state!=BUFFER_READY) {
1017 se401->frame[framenr].grabstate=FRAME_ERROR;
1018 return -EIO;
1019 }
1020 se401->scratch[se401->scratch_use].state=BUFFER_BUSY;
1021 if (se401->format==FMT_JANGGU) {
1022 decode_JangGu(se401, &se401->scratch[se401->scratch_use]);
1023 } else {
1024 decode_bayer(se401, &se401->scratch[se401->scratch_use]);
1025 }
1026 se401->scratch[se401->scratch_use].state=BUFFER_UNUSED;
1027 se401->scratch_use++;
1028 if (se401->scratch_use>=SE401_NUMSCRATCH)
1029 se401->scratch_use=0;
1030 if (errors > SE401_MAX_ERRORS) {
1031 errors=0;
1032 info("to much errors, restarting capture");
1033 se401_stop_stream(se401);
1034 se401_start_stream(se401);
1035 }
1036 }
1037 }
1038
1039 if (se401->frame[framenr].grabstate==FRAME_DONE)
1040 if (se401->enhance)
1041 enhance_picture(se401->frame[framenr].data, se401->cheight*se401->cwidth*3);
1042 return 0;
1043 }
1044
1045
1046 /****************************************************************************
1047 *
1048 * Video4Linux
1049 *
1050 ***************************************************************************/
1051
1052
1053 static int se401_open(struct video_device *dev, int flags)
1054 {
1055 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1056 int err = 0;
1057
1058 /* we are called with the BKL held */
1059 MOD_INC_USE_COUNT;
1060
1061 se401->user=1;
1062 se401->fbuf=rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
1063 if(!se401->fbuf) err=-ENOMEM;
1064
1065 if (err) {
1066 MOD_DEC_USE_COUNT;
1067 se401->user = 0;
1068 }
1069
1070 return err;
1071 }
1072
1073 static void se401_close(struct video_device *dev)
1074 {
1075 /* called with BKL held */
1076 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1077 int i;
1078
1079 for (i=0; i<SE401_NUMFRAMES; i++)
1080 se401->frame[i].grabstate=FRAME_UNUSED;
1081 if (se401->streaming)
1082 se401_stop_stream(se401);
1083
1084 rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
1085 se401->user=0;
1086
1087 if (se401->removed) {
1088 video_unregister_device(&se401->vdev);
1089 kfree(se401->width);
1090 kfree(se401->height);
1091 kfree(se401);
1092 se401 = NULL;
1093 info("device unregistered");
1094 }
1095
1096 MOD_DEC_USE_COUNT;
1097 }
1098
1099 static int se401_init_done(struct video_device *dev)
1100 {
1101 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1102 create_proc_se401_cam((struct usb_se401 *)dev);
1103 #endif
1104
1105 return 0;
1106 }
1107
1108 static long se401_write(struct video_device *dev, const char *buf, unsigned long
1109 count, int noblock)
1110 {
1111 return -EINVAL;
1112 }
1113
1114 static int se401_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
1115 {
1116 struct usb_se401 *se401 = (struct usb_se401 *)vdev;
1117
1118 if (!se401->dev)
1119 return -EIO;
1120
1121 switch (cmd) {
1122 case VIDIOCGCAP:
1123 {
1124 struct video_capability b;
1125 strcpy(b.name, se401->camera_name);
1126 b.type = VID_TYPE_CAPTURE;
1127 b.channels = 1;
1128 b.audios = 0;
1129 b.maxwidth = se401->width[se401->sizes-1];
1130 b.maxheight = se401->height[se401->sizes-1];
1131 b.minwidth = se401->width[0];
1132 b.minheight = se401->height[0];
1133
1134 if (copy_to_user(arg, &b, sizeof(b)))
1135 return -EFAULT;
1136
1137 return 0;
1138 }
1139 case VIDIOCGCHAN:
1140 {
1141 struct video_channel v;
1142
1143 if (copy_from_user(&v, arg, sizeof(v)))
1144 return -EFAULT;
1145 if (v.channel != 0)
1146 return -EINVAL;
1147
1148 v.flags = 0;
1149 v.tuners = 0;
1150 v.type = VIDEO_TYPE_CAMERA;
1151 strcpy(v.name, "Camera");
1152
1153 if (copy_to_user(arg, &v, sizeof(v)))
1154 return -EFAULT;
1155
1156 return 0;
1157 }
1158 case VIDIOCSCHAN:
1159 {
1160 int v;
1161
1162 if (copy_from_user(&v, arg, sizeof(v)))
1163 return -EFAULT;
1164
1165 if (v != 0)
1166 return -EINVAL;
1167
1168 return 0;
1169 }
1170 case VIDIOCGPICT:
1171 {
1172 struct video_picture p;
1173
1174 se401_get_pict(se401, &p);
1175
1176 if (copy_to_user(arg, &p, sizeof(p)))
1177 return -EFAULT;
1178 return 0;
1179 }
1180 case VIDIOCSPICT:
1181 {
1182 struct video_picture p;
1183
1184 if (copy_from_user(&p, arg, sizeof(p)))
1185 return -EFAULT;
1186
1187 if (se401_set_pict(se401, &p))
1188 return -EINVAL;
1189 return 0;
1190 }
1191 case VIDIOCSWIN:
1192 {
1193 struct video_window vw;
1194
1195 if (copy_from_user(&vw, arg, sizeof(vw)))
1196 return -EFAULT;
1197 if (vw.flags)
1198 return -EINVAL;
1199 if (vw.clipcount)
1200 return -EINVAL;
1201 if (se401_set_size(se401, vw.width, vw.height))
1202 return -EINVAL;
1203
1204 return 0;
1205 }
1206 case VIDIOCGWIN:
1207 {
1208 struct video_window vw;
1209
1210 vw.x = 0; /* FIXME */
1211 vw.y = 0;
1212 vw.chromakey = 0;
1213 vw.flags = 0;
1214 vw.clipcount = 0;
1215 vw.width = se401->cwidth;
1216 vw.height = se401->cheight;
1217
1218 if (copy_to_user(arg, &vw, sizeof(vw)))
1219 return -EFAULT;
1220
1221 return 0;
1222 }
1223 case VIDIOCGMBUF:
1224 {
1225 struct video_mbuf vm;
1226 int i;
1227
1228 memset(&vm, 0, sizeof(vm));
1229 vm.size = SE401_NUMFRAMES * se401->maxframesize;
1230 vm.frames = SE401_NUMFRAMES;
1231 for (i=0; i<SE401_NUMFRAMES; i++)
1232 vm.offsets[i] = se401->maxframesize * i;
1233
1234 if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
1235 return -EFAULT;
1236
1237 return 0;
1238 }
1239 case VIDIOCMCAPTURE:
1240 {
1241 struct video_mmap vm;
1242
1243 if (copy_from_user(&vm, arg, sizeof(vm)))
1244 return -EFAULT;
1245 if (vm.format != VIDEO_PALETTE_RGB24)
1246 return -EINVAL;
1247 if (vm.frame >= SE401_NUMFRAMES)
1248 return -EINVAL;
1249 if (se401->frame[vm.frame].grabstate != FRAME_UNUSED)
1250 return -EBUSY;
1251
1252 /* Is this according to the v4l spec??? */
1253 if (se401_set_size(se401, vm.width, vm.height))
1254 return -EINVAL;
1255 se401->frame[vm.frame].grabstate=FRAME_READY;
1256
1257 if (!se401->streaming)
1258 se401_start_stream(se401);
1259
1260 /* Set the picture properties */
1261 if (se401->framecount==0)
1262 se401_send_pict(se401);
1263 /* Calibrate the reset level after a few frames. */
1264 if (se401->framecount%20==1)
1265 se401_auto_resetlevel(se401);
1266
1267 return 0;
1268 }
1269 case VIDIOCSYNC:
1270 {
1271 int frame, ret=0;
1272
1273 if (copy_from_user((void *)&frame, arg, sizeof(int)))
1274 return -EFAULT;
1275
1276 if(frame <0 || frame >= SE401_NUMFRAMES)
1277 return -EINVAL;
1278
1279 ret=se401_newframe(se401, frame);
1280 se401->frame[frame].grabstate=FRAME_UNUSED;
1281 return ret;
1282 }
1283 case VIDIOCGFBUF:
1284 {
1285 struct video_buffer vb;
1286
1287 memset(&vb, 0, sizeof(vb));
1288 vb.base = NULL; /* frame buffer not supported, not used */
1289
1290 if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
1291 return -EFAULT;
1292
1293 return 0;
1294 }
1295 case VIDIOCKEY:
1296 return 0;
1297 case VIDIOCCAPTURE:
1298 return -EINVAL;
1299 case VIDIOCSFBUF:
1300 return -EINVAL;
1301 case VIDIOCGTUNER:
1302 case VIDIOCSTUNER:
1303 return -EINVAL;
1304 case VIDIOCGFREQ:
1305 case VIDIOCSFREQ:
1306 return -EINVAL;
1307 case VIDIOCGAUDIO:
1308 case VIDIOCSAUDIO:
1309 return -EINVAL;
1310 default:
1311 return -ENOIOCTLCMD;
1312 } /* end switch */
1313
1314 return 0;
1315 }
1316
1317 static long se401_read(struct video_device *dev, char *buf, unsigned long count,
1318 int noblock)
1319 {
1320 int realcount=count, ret=0;
1321 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1322
1323
1324 if (se401->dev == NULL)
1325 return -EIO;
1326 if (realcount > se401->cwidth*se401->cheight*3)
1327 realcount=se401->cwidth*se401->cheight*3;
1328
1329 /* Shouldn't happen: */
1330 if (se401->frame[0].grabstate==FRAME_GRABBING)
1331 return -EBUSY;
1332 se401->frame[0].grabstate=FRAME_READY;
1333 se401->frame[1].grabstate=FRAME_UNUSED;
1334 se401->curframe=0;
1335
1336 if (!se401->streaming)
1337 se401_start_stream(se401);
1338
1339 /* Set the picture properties */
1340 if (se401->framecount==0)
1341 se401_send_pict(se401);
1342 /* Calibrate the reset level after a few frames. */
1343 if (se401->framecount%20==1)
1344 se401_auto_resetlevel(se401);
1345
1346 ret=se401_newframe(se401, 0);
1347
1348 se401->frame[0].grabstate=FRAME_UNUSED;
1349 if (ret)
1350 return ret;
1351 if (copy_to_user(buf, se401->frame[0].data, realcount))
1352 return -EFAULT;
1353
1354 return realcount;
1355 }
1356
1357 static int se401_mmap(struct video_device *dev, const char *adr,
1358 unsigned long size)
1359 {
1360 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1361 unsigned long start = (unsigned long)adr;
1362 unsigned long page, pos;
1363
1364 down(&se401->lock);
1365
1366 if (se401->dev == NULL) {
1367 up(&se401->lock);
1368 return -EIO;
1369 }
1370 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))) {
1371 up(&se401->lock);
1372 return -EINVAL;
1373 }
1374 pos = (unsigned long)se401->fbuf;
1375 while (size > 0) {
1376 page = kvirt_to_pa(pos);
1377 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) {
1378 up(&se401->lock);
1379 return -EAGAIN;
1380 }
1381 start += PAGE_SIZE;
1382 pos += PAGE_SIZE;
1383 if (size > PAGE_SIZE)
1384 size -= PAGE_SIZE;
1385 else
1386 size = 0;
1387 }
1388 up(&se401->lock);
1389
1390 return 0;
1391 }
1392
1393 static struct video_device se401_template = {
1394 name: "se401 USB camera",
1395 type: VID_TYPE_CAPTURE,
1396 hardware: VID_HARDWARE_SE401,
1397 open: se401_open,
1398 close: se401_close,
1399 read: se401_read,
1400 write: se401_write,
1401 ioctl: se401_ioctl,
1402 mmap: se401_mmap,
1403 initialize: se401_init_done,
1404 };
1405
1406
1407
1408 /***************************/
1409 static int se401_init(struct usb_se401 *se401)
1410 {
1411 int i=0, rc;
1412 unsigned char cp[0x40];
1413 char temp[200];
1414
1415 /* led on */
1416 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1417
1418 /* get camera descriptor */
1419 rc=se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0, cp, sizeof(cp));
1420 if (cp[1]!=0x41) {
1421 err("Wrong descriptor type");
1422 return 1;
1423 }
1424 sprintf (temp, "ExtraFeatures: %d", cp[3]);
1425
1426 se401->sizes=cp[4]+cp[5]*256;
1427 se401->width=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1428 se401->height=kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1429 for (i=0; i<se401->sizes; i++) {
1430 se401->width[i]=cp[6+i*4+0]+cp[6+i*4+1]*256;
1431 se401->height[i]=cp[6+i*4+2]+cp[6+i*4+3]*256;
1432 }
1433 sprintf (temp, "%s Sizes:", temp);
1434 for (i=0; i<se401->sizes; i++) {
1435 sprintf(temp, "%s %dx%d", temp, se401->width[i], se401->height[i]);
1436 }
1437 info("%s", temp);
1438 se401->maxframesize=se401->width[se401->sizes-1]*se401->height[se401->sizes-1]*3;
1439
1440 rc=se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1441 se401->cwidth=cp[0]+cp[1]*256;
1442 rc=se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1443 se401->cheight=cp[0]+cp[1]*256;
1444
1445 if (!cp[2] && SE401_FORMAT_BAYER) {
1446 err("Bayer format not supported!");
1447 return 1;
1448 }
1449 /* set output mode (BAYER) */
1450 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE, SE401_FORMAT_BAYER, NULL, 0);
1451
1452 rc=se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1453 se401->brightness=cp[0]+cp[1]*256;
1454 /* some default values */
1455 se401->resetlevel=0x2d;
1456 se401->rgain=0x20;
1457 se401->ggain=0x20;
1458 se401->bgain=0x20;
1459 se401_set_exposure(se401, 20000);
1460 se401->palette=VIDEO_PALETTE_RGB24;
1461 se401->enhance=1;
1462 se401->dropped=0;
1463 se401->error=0;
1464 se401->framecount=0;
1465 se401->readcount=0;
1466
1467 /* Start interrupt transfers for snapshot button */
1468 se401->inturb=usb_alloc_urb(0);
1469 if (!se401->inturb) {
1470 info("Allocation of inturb failed");
1471 return 1;
1472 }
1473 FILL_INT_URB(se401->inturb, se401->dev,
1474 usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1475 &se401->button, sizeof(se401->button),
1476 se401_button_irq,
1477 se401,
1478 HZ/10
1479 );
1480 if (usb_submit_urb(se401->inturb)) {
1481 info("int urb burned down");
1482 return 1;
1483 }
1484
1485 /* Flash the led */
1486 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1487 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1488 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1489 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1490
1491 return 0;
1492 }
1493
1494 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)
1495 static void* se401_probe(struct usb_device *dev, unsigned int ifnum)
1496 #else
1497 static void* __devinit se401_probe(struct usb_device *dev, unsigned int ifnum,
1498 const struct usb_device_id *id)
1499 #endif
1500 {
1501 struct usb_interface_descriptor *interface;
1502 struct usb_se401 *se401;
1503 char *camera_name=NULL;
1504
1505 /* We don't handle multi-config cameras */
1506 if (dev->descriptor.bNumConfigurations != 1)
1507 return NULL;
1508
1509 interface = &dev->actconfig->interface[ifnum].altsetting[0];
1510
1511 /* Is it an se401? */
1512 if (dev->descriptor.idVendor == 0x03e8 &&
1513 dev->descriptor.idProduct == 0x0004) {
1514 camera_name="Endpoints/Aox SE401";
1515 } else if (dev->descriptor.idVendor == 0x0471 &&
1516 dev->descriptor.idProduct == 0x030b) {
1517 camera_name="Philips PCVC665K";
1518 } else if (dev->descriptor.idVendor == 0x047d &&
1519 dev->descriptor.idProduct == 0x5001) {
1520 camera_name="Kensington VideoCAM 67014";
1521 } else if (dev->descriptor.idVendor == 0x047d &&
1522 dev->descriptor.idProduct == 0x5002) {
1523 camera_name="Kensington VideoCAM 6701(5/7)";
1524 } else if (dev->descriptor.idVendor == 0x047d &&
1525 dev->descriptor.idProduct == 0x5003) {
1526 camera_name="Kensington VideoCAM 67016";
1527 } else
1528 return NULL;
1529
1530 /* Checking vendor/product should be enough, but what the hell */
1531 if (interface->bInterfaceClass != 0x00)
1532 return NULL;
1533 if (interface->bInterfaceSubClass != 0x00)
1534 return NULL;
1535
1536 /* We found one */
1537 info("SE401 camera found: %s", camera_name);
1538
1539 if ((se401 = kmalloc(sizeof(*se401), GFP_KERNEL)) == NULL) {
1540 err("couldn't kmalloc se401 struct");
1541 return NULL;
1542 }
1543
1544 memset(se401, 0, sizeof(*se401));
1545
1546 se401->dev = dev;
1547 se401->iface = interface->bInterfaceNumber;
1548 se401->camera_name = camera_name;
1549
1550 info("firmware version: %02x", dev->descriptor.bcdDevice & 255);
1551
1552 if (se401_init(se401)) {
1553 kfree(se401);
1554 return NULL;
1555 }
1556
1557 memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1558 memcpy(se401->vdev.name, se401->camera_name, strlen(se401->camera_name));
1559 init_waitqueue_head(&se401->wq);
1560 init_MUTEX(&se401->lock);
1561 wmb();
1562
1563 if (video_register_device(&se401->vdev, VFL_TYPE_GRABBER, video_nr) == -1) {
1564 kfree(se401);
1565 err("video_register_device failed");
1566 return NULL;
1567 }
1568 info("registered new video device: video%d", se401->vdev.minor);
1569
1570 return se401;
1571 }
1572
1573 static void se401_disconnect(struct usb_device *dev, void *ptr)
1574 {
1575 struct usb_se401 *se401 = (struct usb_se401 *) ptr;
1576
1577 lock_kernel();
1578 /* We don't want people trying to open up the device */
1579 if (!se401->user){
1580 video_unregister_device(&se401->vdev);
1581 usb_se401_remove_disconnected(se401);
1582 } else {
1583 se401->removed = 1;
1584 }
1585 unlock_kernel();
1586 }
1587
1588 static inline void usb_se401_remove_disconnected (struct usb_se401 *se401)
1589 {
1590 int i;
1591
1592 se401->dev = NULL;
1593 se401->frame[0].grabstate = FRAME_ERROR;
1594 se401->frame[1].grabstate = FRAME_ERROR;
1595
1596 se401->streaming = 0;
1597
1598 wake_up_interruptible(&se401->wq);
1599
1600 for (i=0; i<SE401_NUMSBUF; i++) if (se401->urb[i]) {
1601 se401->urb[i]->next = NULL;
1602 usb_unlink_urb(se401->urb[i]);
1603 usb_free_urb(se401->urb[i]);
1604 se401->urb[i] = NULL;
1605 kfree(se401->sbuf[i].data);
1606 }
1607 for (i=0; i<SE401_NUMSCRATCH; i++) if (se401->scratch[i].data) {
1608 kfree(se401->scratch[i].data);
1609 }
1610 if (se401->inturb) {
1611 usb_unlink_urb(se401->inturb);
1612 usb_free_urb(se401->inturb);
1613 }
1614 info("%s disconnected", se401->camera_name);
1615
1616 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1617 destroy_proc_se401_cam(se401);
1618 #endif
1619
1620 /* Free the memory */
1621 kfree(se401->width);
1622 kfree(se401->height);
1623 kfree(se401);
1624 }
1625
1626 static struct usb_driver se401_driver = {
1627 name: "se401",
1628 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 3, 0)
1629 id_table: device_table,
1630 #endif
1631 probe: se401_probe,
1632 disconnect: se401_disconnect
1633 };
1634
1635
1636
1637 /****************************************************************************
1638 *
1639 * Module routines
1640 *
1641 ***************************************************************************/
1642
1643 static int __init usb_se401_init(void)
1644 {
1645 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1646 proc_se401_create();
1647 #endif
1648
1649 info("SE401 usb camera driver version %s registering", version);
1650 if (flickerless)
1651 if (flickerless!=50 && flickerless!=60) {
1652 info("Invallid flickerless value, use 0, 50 or 60.");
1653 return -1;
1654 }
1655 if (usb_register(&se401_driver) < 0)
1656 return -1;
1657 return 0;
1658 }
1659
1660 static void __exit usb_se401_exit(void)
1661 {
1662 usb_deregister(&se401_driver);
1663 info("SE401 driver deregistered");
1664
1665 #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
1666 proc_se401_destroy();
1667 #endif
1668 }
1669
1670 module_init(usb_se401_init);
1671 module_exit(usb_se401_exit);
1672