1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51#include <linux/errno.h>
52#include <linux/init.h>
53#include <linux/mm.h>
54#include <linux/module.h>
55#include <linux/poll.h>
56#include <linux/slab.h>
57#include <linux/vmalloc.h>
58#include <linux/wrapper.h>
59#include <asm/io.h>
60
61#include "pwc.h"
62#include "pwc-ioctl.h"
63#include "pwc-uncompress.h"
64
65
66
67
68static struct usb_device_id pwc_device_table [] = {
69 { USB_DEVICE(0x0471, 0x0302) },
70 { USB_DEVICE(0x0471, 0x0303) },
71 { USB_DEVICE(0x0471, 0x0304) },
72 { USB_DEVICE(0x0471, 0x0307) },
73 { USB_DEVICE(0x0471, 0x0308) },
74 { USB_DEVICE(0x0471, 0x030C) },
75 { USB_DEVICE(0x0471, 0x0310) },
76 { USB_DEVICE(0x0471, 0x0311) },
77 { USB_DEVICE(0x0471, 0x0312) },
78 { USB_DEVICE(0x0471, 0x0313) },
79 { USB_DEVICE(0x069A, 0x0001) },
80 { USB_DEVICE(0x046D, 0x08B0) },
81 { USB_DEVICE(0x046D, 0x08B1) },
82 { USB_DEVICE(0x046D, 0x08B2) },
83 { USB_DEVICE(0x046D, 0x08B3) },
84 { USB_DEVICE(0x046D, 0x08B4) },
85 { USB_DEVICE(0x046D, 0x08B5) },
86 { USB_DEVICE(0x046D, 0x08B6) },
87 { USB_DEVICE(0x046D, 0x08B7) },
88 { USB_DEVICE(0x046D, 0x08B8) },
89 { USB_DEVICE(0x055D, 0x9000) },
90 { USB_DEVICE(0x055D, 0x9001) },
91 { USB_DEVICE(0x041E, 0x400C) },
92 { USB_DEVICE(0x041E, 0x4011) },
93 { USB_DEVICE(0x04CC, 0x8116) },
94 { USB_DEVICE(0x0d81, 0x1910) },
95 { USB_DEVICE(0x0d81, 0x1900) },
96 { }
97};
98MODULE_DEVICE_TABLE(usb, pwc_device_table);
99
100static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id);
101static void usb_pwc_disconnect(struct usb_device *udev, void *ptr);
102
103static struct usb_driver pwc_driver =
104{
105 name: "Philips webcam",
106 id_table: pwc_device_table,
107 probe: usb_pwc_probe,
108 disconnect: usb_pwc_disconnect,
109};
110
111#define MAX_DEV_HINTS 20
112#define MAX_ISOC_ERRORS 20
113
114static int default_size = PSZ_QCIF;
115static int default_fps = 10;
116static int default_fbufs = 3;
117static int default_mbufs = 2;
118 int pwc_trace = TRACE_MODULE | TRACE_FLOW | TRACE_PWCX;
119static int power_save = 0;
120static int led_on = 100, led_off = 0;
121 int pwc_preferred_compression = 2;
122static struct {
123 int type;
124 char serial_number[30];
125 int device_node;
126 struct pwc_device *pdev;
127} device_hint[MAX_DEV_HINTS];
128
129
130
131static int pwc_video_open(struct video_device *vdev, int mode);
132static void pwc_video_close(struct video_device *vdev);
133static long pwc_video_read(struct video_device *vdev, char *buf, unsigned long count, int noblock);
134static long pwc_video_write(struct video_device *vdev, const char *buf, unsigned long count, int noblock);
135static unsigned int pwc_video_poll(struct video_device *vdev, struct file *file, poll_table *wait);
136static int pwc_video_ioctl(struct video_device *vdev, unsigned int cmd, void *arg);
137static int pwc_video_mmap(struct video_device *vdev, const char *adr, unsigned long size);
138
139static struct video_device pwc_template = {
140 owner: THIS_MODULE,
141 name: "Philips Webcam",
142 type: VID_TYPE_CAPTURE,
143 hardware: VID_HARDWARE_PWC,
144 open: pwc_video_open,
145 close: pwc_video_close,
146 read: pwc_video_read,
147 write: pwc_video_write,
148 poll: pwc_video_poll,
149 ioctl: pwc_video_ioctl,
150 mmap: pwc_video_mmap,
151 initialize: NULL,
152 minor: 0
153};
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192static inline unsigned long kvirt_to_pa(unsigned long adr)
193{
194 unsigned long kva, ret;
195
196 kva = (unsigned long) page_address(vmalloc_to_page((void *)adr));
197 kva |= adr & (PAGE_SIZE-1);
198 ret = __pa(kva);
199 return ret;
200}
201
202static void * rvmalloc(unsigned long size)
203{
204 void * mem;
205 unsigned long adr;
206
207 size=PAGE_ALIGN(size);
208 mem=vmalloc_32(size);
209 if (mem)
210 {
211 memset(mem, 0, size);
212 adr=(unsigned long) mem;
213 while (size > 0)
214 {
215 mem_map_reserve(vmalloc_to_page((void *)adr));
216 adr+=PAGE_SIZE;
217 size-=PAGE_SIZE;
218 }
219 }
220 return mem;
221}
222
223static void rvfree(void * mem, unsigned long size)
224{
225 unsigned long adr;
226
227 if (mem)
228 {
229 adr=(unsigned long) mem;
230 while ((long) size > 0)
231 {
232 mem_map_unreserve(vmalloc_to_page((void *)adr));
233 adr+=PAGE_SIZE;
234 size-=PAGE_SIZE;
235 }
236 vfree(mem);
237 }
238}
239
240
241
242
243static int pwc_allocate_buffers(struct pwc_device *pdev)
244{
245 int i;
246 void *kbuf;
247
248 Trace(TRACE_MEMORY, ">> pwc_allocate_buffers(pdev = 0x%p)\n", pdev);
249
250 if (pdev == NULL)
251 return -ENXIO;
252
253#ifdef PWC_MAGIC
254 if (pdev->magic != PWC_MAGIC) {
255 Err("allocate_buffers(): magic failed.\n");
256 return -ENXIO;
257 }
258#endif
259
260 for (i = 0; i < MAX_ISO_BUFS; i++) {
261 if (pdev->sbuf[i].data == NULL) {
262 kbuf = kmalloc(ISO_BUFFER_SIZE, GFP_KERNEL);
263 if (kbuf == NULL) {
264 Err("Failed to allocate iso buffer %d.\n", i);
265 return -ENOMEM;
266 }
267 Trace(TRACE_MEMORY, "Allocated iso buffer at %p.\n", kbuf);
268 pdev->sbuf[i].data = kbuf;
269 memset(kbuf, 0, ISO_BUFFER_SIZE);
270 }
271 }
272
273
274 if (pdev->fbuf == NULL) {
275 kbuf = kmalloc(default_fbufs * sizeof(struct pwc_frame_buf), GFP_KERNEL);
276 if (kbuf == NULL) {
277 Err("Failed to allocate frame buffer structure.\n");
278 return -ENOMEM;
279 }
280 Trace(TRACE_MEMORY, "Allocated frame buffer structure at %p.\n", kbuf);
281 pdev->fbuf = kbuf;
282 memset(kbuf, 0, default_fbufs * sizeof(struct pwc_frame_buf));
283 }
284
285 for (i = 0; i < default_fbufs; i++) {
286 if (pdev->fbuf[i].data == NULL) {
287 kbuf = vmalloc(PWC_FRAME_SIZE);
288 if (kbuf == NULL) {
289 Err("Failed to allocate frame buffer %d.\n", i);
290 return -ENOMEM;
291 }
292 Trace(TRACE_MEMORY, "Allocated frame buffer %d at %p.\n", i, kbuf);
293 pdev->fbuf[i].data = kbuf;
294 memset(kbuf, 128, PWC_FRAME_SIZE);
295 }
296 }
297
298
299 kbuf = NULL;
300 if (pdev->decompressor != NULL) {
301 kbuf = kmalloc(pdev->decompressor->table_size, GFP_KERNEL);
302 if (kbuf == NULL) {
303 Err("Failed to allocate decompress table.\n");
304 return -ENOMEM;
305 }
306 Trace(TRACE_MEMORY, "Allocated decompress table %p.\n", kbuf);
307 }
308 pdev->decompress_data = kbuf;
309
310
311 kbuf = rvmalloc(default_mbufs * pdev->len_per_image);
312 if (kbuf == NULL) {
313 Err("Failed to allocate image buffer(s).\n");
314 return -ENOMEM;
315 }
316 Trace(TRACE_MEMORY, "Allocated image buffer at %p.\n", kbuf);
317 pdev->image_data = kbuf;
318 for (i = 0; i < default_mbufs; i++)
319 pdev->image_ptr[i] = kbuf + i * pdev->len_per_image;
320 for (; i < MAX_IMAGES; i++)
321 pdev->image_ptr[i] = NULL;
322
323 kbuf = NULL;
324
325 Trace(TRACE_MEMORY, "<< pwc_allocate_buffers()\n");
326 return 0;
327}
328
329static void pwc_free_buffers(struct pwc_device *pdev)
330{
331 int i;
332
333 Trace(TRACE_MEMORY, "Entering free_buffers(%p).\n", pdev);
334
335 if (pdev == NULL)
336 return;
337#ifdef PWC_MAGIC
338 if (pdev->magic != PWC_MAGIC) {
339 Err("free_buffers(): magic failed.\n");
340 return;
341 }
342#endif
343
344
345 for (i = 0; i < MAX_ISO_BUFS; i++)
346 if (pdev->sbuf[i].data != NULL) {
347 Trace(TRACE_MEMORY, "Freeing ISO buffer at %p.\n", pdev->sbuf[i].data);
348 kfree(pdev->sbuf[i].data);
349 pdev->sbuf[i].data = NULL;
350 }
351
352
353 if (pdev->fbuf != NULL) {
354 for (i = 0; i < default_fbufs; i++) {
355 if (pdev->fbuf[i].data != NULL) {
356 Trace(TRACE_MEMORY, "Freeing frame buffer %d at %p.\n", i, pdev->fbuf[i].data);
357 vfree(pdev->fbuf[i].data);
358 pdev->fbuf[i].data = NULL;
359 }
360 }
361 kfree(pdev->fbuf);
362 pdev->fbuf = NULL;
363 }
364
365
366 if (pdev->decompress_data != NULL) {
367 Trace(TRACE_MEMORY, "Freeing decompression buffer at %p.\n", pdev->decompress_data);
368 kfree(pdev->decompress_data);
369 pdev->decompress_data = NULL;
370 }
371 pdev->decompressor = NULL;
372
373
374 if (pdev->image_data != NULL) {
375 Trace(TRACE_MEMORY, "Freeing image buffer at %p.\n", pdev->image_data);
376 rvfree(pdev->image_data, default_mbufs * pdev->len_per_image);
377 }
378 pdev->image_data = NULL;
379
380 Trace(TRACE_MEMORY, "Leaving free_buffers().\n");
381}
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440static inline int pwc_next_fill_frame(struct pwc_device *pdev)
441{
442 int ret;
443 unsigned long flags;
444
445 ret = 0;
446 spin_lock_irqsave(&pdev->ptrlock, flags);
447 if (pdev->fill_frame != NULL) {
448
449 if (pdev->full_frames == NULL) {
450 pdev->full_frames = pdev->fill_frame;
451 pdev->full_frames_tail = pdev->full_frames;
452 }
453 else {
454 pdev->full_frames_tail->next = pdev->fill_frame;
455 pdev->full_frames_tail = pdev->fill_frame;
456 }
457 }
458 if (pdev->empty_frames != NULL) {
459
460 pdev->fill_frame = pdev->empty_frames;
461 pdev->empty_frames = pdev->empty_frames->next;
462 }
463 else {
464
465#if PWC_DEBUG
466
467 if (pdev->full_frames == NULL) {
468 Err("Neither empty or full frames available!\n");
469 spin_unlock_irqrestore(&pdev->ptrlock, flags);
470 return -EINVAL;
471 }
472#endif
473 pdev->fill_frame = pdev->full_frames;
474 pdev->full_frames = pdev->full_frames->next;
475 ret = 1;
476 }
477 pdev->fill_frame->next = NULL;
478#if PWC_DEBUG
479 Trace(TRACE_SEQUENCE, "Assigning sequence number %d.\n", pdev->sequence);
480 pdev->fill_frame->sequence = pdev->sequence++;
481#endif
482 spin_unlock_irqrestore(&pdev->ptrlock, flags);
483 return ret;
484}
485
486
487
488
489
490
491
492static void pwc_reset_buffers(struct pwc_device *pdev)
493{
494 int i;
495 unsigned long flags;
496
497 spin_lock_irqsave(&pdev->ptrlock, flags);
498 pdev->full_frames = NULL;
499 pdev->full_frames_tail = NULL;
500 for (i = 0; i < default_fbufs; i++) {
501 pdev->fbuf[i].filled = 0;
502 if (i > 0)
503 pdev->fbuf[i].next = &pdev->fbuf[i - 1];
504 else
505 pdev->fbuf->next = NULL;
506 }
507 pdev->empty_frames = &pdev->fbuf[default_fbufs - 1];
508 pdev->empty_frames_tail = pdev->fbuf;
509 pdev->read_frame = NULL;
510 pdev->fill_frame = pdev->empty_frames;
511 pdev->empty_frames = pdev->empty_frames->next;
512
513 pdev->image_read_pos = 0;
514 pdev->fill_image = 0;
515 spin_unlock_irqrestore(&pdev->ptrlock, flags);
516}
517
518
519
520
521
522static int pwc_handle_frame(struct pwc_device *pdev)
523{
524 int ret = 0;
525 unsigned long flags;
526
527 spin_lock_irqsave(&pdev->ptrlock, flags);
528
529
530 if (pdev->read_frame != NULL) {
531
532 Err("Huh? Read frame still in use?\n");
533 }
534 else {
535 if (pdev->full_frames == NULL) {
536 Err("Woops. No frames ready.\n");
537 }
538 else {
539 pdev->read_frame = pdev->full_frames;
540 pdev->full_frames = pdev->full_frames->next;
541 pdev->read_frame->next = NULL;
542 }
543
544 if (pdev->read_frame != NULL) {
545#if PWC_DEBUG
546 Trace(TRACE_SEQUENCE, "Decompressing frame %d\n", pdev->read_frame->sequence);
547#endif
548
549
550
551
552 spin_unlock_irqrestore(&pdev->ptrlock, flags);
553 ret = pwc_decompress(pdev);
554 spin_lock_irqsave(&pdev->ptrlock, flags);
555
556
557 if (pdev->empty_frames == NULL) {
558 pdev->empty_frames = pdev->read_frame;
559 pdev->empty_frames_tail = pdev->empty_frames;
560 }
561 else {
562 pdev->empty_frames_tail->next = pdev->read_frame;
563 pdev->empty_frames_tail = pdev->read_frame;
564 }
565 pdev->read_frame = NULL;
566 }
567 }
568 spin_unlock_irqrestore(&pdev->ptrlock, flags);
569 return ret;
570}
571
572
573
574
575static inline void pwc_next_image(struct pwc_device *pdev)
576{
577 pdev->image_used[pdev->fill_image] = 0;
578 pdev->fill_image = (pdev->fill_image + 1) % default_mbufs;
579}
580
581
582
583
584
585
586static void pwc_isoc_handler(struct urb *urb)
587{
588 struct pwc_device *pdev;
589 int i, fst, flen;
590 int awake;
591 struct pwc_frame_buf *fbuf;
592 unsigned char *fillptr = 0, *iso_buf = 0;
593
594 awake = 0;
595 pdev = (struct pwc_device *)urb->context;
596 if (pdev == NULL) {
597 Err("isoc_handler() called with NULL device?!\n");
598 return;
599 }
600#ifdef PWC_MAGIC
601 if (pdev->magic != PWC_MAGIC) {
602 Err("isoc_handler() called with bad magic!\n");
603 return;
604 }
605#endif
606 if (urb->status == -ENOENT || urb->status == -ECONNRESET) {
607 Trace(TRACE_OPEN, "pwc_isoc_handler(): URB (%p) unlinked %ssynchronuously.\n", urb, urb->status == -ENOENT ? "" : "a");
608 return;
609 }
610 if (urb->status != -EINPROGRESS && urb->status != 0) {
611 const char *errmsg;
612
613 errmsg = "Unknown";
614 switch(urb->status) {
615 case -ENOSR: errmsg = "Buffer error (overrun)"; break;
616 case -EPIPE: errmsg = "Stalled (device not responding)"; break;
617 case -EOVERFLOW: errmsg = "Babble (bad cable?)"; break;
618 case -EPROTO: errmsg = "Bit-stuff error (bad cable?)"; break;
619 case -EILSEQ: errmsg = "CRC/Timeout (could be anything)"; break;
620 case -ETIMEDOUT: errmsg = "NAK (device does not respond)"; break;
621 }
622 Trace(TRACE_FLOW, "pwc_isoc_handler() called with status %d [%s].\n", urb->status, errmsg);
623
624
625
626 if (++pdev->visoc_errors > MAX_ISOC_ERRORS)
627 {
628 Info("Too many ISOC errors, bailing out.\n");
629 pdev->error_status = EIO;
630 awake = 1;
631 }
632 else
633 return;
634 }
635
636 fbuf = pdev->fill_frame;
637 if (fbuf == NULL) {
638 Err("pwc_isoc_handler without valid fill frame.\n");
639 awake = 1;
640 }
641 else {
642 fillptr = fbuf->data + fbuf->filled;
643 }
644
645 if (awake) {
646 wake_up_interruptible(&pdev->frameq);
647 return;
648 }
649
650
651 pdev->visoc_errors = 0;
652
653
654
655
656
657
658 for (i = 0; i < urb->number_of_packets; i++) {
659 fst = urb->iso_frame_desc[i].status;
660 flen = urb->iso_frame_desc[i].actual_length;
661 iso_buf = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
662 if (fst == 0) {
663 if (flen > 0) {
664 if (pdev->vsync > 0) {
665 pdev->vsync = 2;
666
667
668 if (flen + fbuf->filled > pdev->frame_size) {
669 Trace(TRACE_FLOW, "Frame buffer overflow (flen = %d, frame_size = %d).\n", flen, pdev->frame_size);
670 pdev->vsync = 0;
671 pdev->vframes_error++;
672 }
673 else {
674 memmove(fillptr, iso_buf, flen);
675 fillptr += flen;
676 }
677 }
678 fbuf->filled += flen;
679 }
680
681 if (flen < pdev->vlast_packet_size) {
682
683
684
685
686 if (pdev->vsync == 2) {
687
688
689
690
691 if (pdev->type == 730) {
692 unsigned char *ptr = (unsigned char *)fbuf->data;
693
694 if (ptr[1] == 1 && ptr[0] & 0x10) {
695#if PWC_DEBUG
696 Debug("Hyundai CMOS sensor bug. Dropping frame %d.\n", fbuf->sequence);
697#endif
698 pdev->drop_frames += 2;
699 pdev->vframes_error++;
700 }
701 if ((ptr[0] ^ pdev->vmirror) & 0x01) {
702 if (ptr[0] & 0x01)
703 Info("Snapshot button pressed.\n");
704 else
705 Info("Snapshot button released.\n");
706 }
707 if ((ptr[0] ^ pdev->vmirror) & 0x02) {
708 if (ptr[0] & 0x02)
709 Info("Image is mirrored.\n");
710 else
711 Info("Image is normal.\n");
712 }
713 pdev->vmirror = ptr[0] & 0x03;
714
715
716
717
718
719
720
721
722
723 if (fbuf->filled == 4)
724 pdev->drop_frames++;
725 }
726
727
728
729
730 if (pdev->drop_frames > 0)
731 pdev->drop_frames--;
732 else {
733
734 if (fbuf->filled < pdev->frame_size) {
735 Trace(TRACE_FLOW, "Frame buffer underflow (%d bytes); discarded.\n", fbuf->filled);
736 pdev->vframes_error++;
737 }
738 else {
739
740 awake = 1;
741
742
743
744
745
746 if (pwc_next_fill_frame(pdev)) {
747 pdev->vframes_dumped++;
748 if ((pdev->vframe_count > FRAME_LOWMARK) && (pwc_trace & TRACE_FLOW)) {
749 if (pdev->vframes_dumped < 20)
750 Trace(TRACE_FLOW, "Dumping frame %d.\n", pdev->vframe_count);
751 if (pdev->vframes_dumped == 20)
752 Trace(TRACE_FLOW, "Dumping frame %d (last message).\n", pdev->vframe_count);
753 }
754 }
755 fbuf = pdev->fill_frame;
756 }
757 }
758 pdev->vframe_count++;
759 }
760 fbuf->filled = 0;
761 fillptr = fbuf->data;
762 pdev->vsync = 1;
763 }
764 pdev->vlast_packet_size = flen;
765 }
766#if PWC_DEBUG
767
768 else {
769 static int iso_error = 0;
770 iso_error++;
771 if (iso_error < 20)
772 Trace(TRACE_FLOW, "Iso frame %d of USB has error %d\n", i, fst);
773 }
774#endif
775 }
776 if (awake)
777 wake_up_interruptible(&pdev->frameq);
778}
779
780
781static int pwc_isoc_init(struct pwc_device *pdev)
782{
783 struct usb_device *udev;
784 struct urb *urb;
785 int i, j, ret;
786
787 struct usb_interface_descriptor *idesc;
788
789 if (pdev == NULL)
790 return -EFAULT;
791 if (pdev->iso_init)
792 return 0;
793 pdev->vsync = 0;
794 udev = pdev->udev;
795
796
797 if (!udev->actconfig)
798 return -EFAULT;
799 idesc = &udev->actconfig->interface[0].altsetting[pdev->valternate];
800 if (!idesc)
801 return -EFAULT;
802
803
804 pdev->vmax_packet_size = -1;
805 for (i = 0; i < idesc->bNumEndpoints; i++)
806 if ((idesc->endpoint[i].bEndpointAddress & 0xF) == pdev->vendpoint) {
807 pdev->vmax_packet_size = idesc->endpoint[i].wMaxPacketSize;
808 break;
809 }
810
811 if (pdev->vmax_packet_size < 0 || pdev->vmax_packet_size > ISO_MAX_FRAME_SIZE) {
812 Err("Failed to find packet size for video endpoint in current alternate setting.\n");
813 return -ENFILE;
814 }
815
816
817 ret = 0;
818 Trace(TRACE_OPEN, "Setting alternate interface %d\n", pdev->valternate);
819 ret = usb_set_interface(pdev->udev, 0, pdev->valternate);
820 if (ret < 0)
821 return ret;
822
823 for (i = 0; i < MAX_ISO_BUFS; i++) {
824 urb = usb_alloc_urb(ISO_FRAMES_PER_DESC);
825 if (urb == NULL) {
826 Err("Failed to allocate urb %d\n", i);
827 ret = -ENOMEM;
828 break;
829 }
830 pdev->sbuf[i].urb = urb;
831 Trace(TRACE_MEMORY, "Allocated URB at 0x%p\n", urb);
832 }
833 if (ret) {
834
835 while (i >= 0) {
836 if (pdev->sbuf[i].urb != NULL)
837 usb_free_urb(pdev->sbuf[i].urb);
838 pdev->sbuf[i].urb = NULL;
839 i--;
840 }
841 return ret;
842 }
843
844
845 for (i = 0; i < MAX_ISO_BUFS; i++) {
846 urb = pdev->sbuf[i].urb;
847
848 urb->next = pdev->sbuf[(i + 1) % MAX_ISO_BUFS].urb;
849 urb->dev = udev;
850 urb->pipe = usb_rcvisocpipe(udev, pdev->vendpoint);
851 urb->transfer_flags = USB_ISO_ASAP;
852 urb->transfer_buffer = pdev->sbuf[i].data;
853 urb->transfer_buffer_length = ISO_BUFFER_SIZE;
854 urb->complete = pwc_isoc_handler;
855 urb->context = pdev;
856 urb->start_frame = 0;
857 urb->number_of_packets = ISO_FRAMES_PER_DESC;
858 for (j = 0; j < ISO_FRAMES_PER_DESC; j++) {
859 urb->iso_frame_desc[j].offset = j * ISO_MAX_FRAME_SIZE;
860 urb->iso_frame_desc[j].length = pdev->vmax_packet_size;
861 }
862 }
863
864
865 for (i = 0; i < MAX_ISO_BUFS; i++) {
866 ret = usb_submit_urb(pdev->sbuf[i].urb);
867 if (ret)
868 Err("isoc_init() submit_urb %d failed with error %d\n", i, ret);
869 else
870 Trace(TRACE_OPEN, "URB 0x%p submitted.\n", pdev->sbuf[i].urb);
871 }
872
873
874 pdev->iso_init = 1;
875 Trace(TRACE_OPEN, "<< pwc_isoc_init()\n");
876 return 0;
877}
878
879static void pwc_isoc_cleanup(struct pwc_device *pdev)
880{
881 int i;
882
883 Trace(TRACE_OPEN, ">> pwc_isoc_cleanup()\n");
884 if (pdev == NULL)
885 return;
886
887
888 for (i = 0; i < MAX_ISO_BUFS; i++) {
889 struct urb *urb;
890
891 urb = pdev->sbuf[i].urb;
892 if (urb != 0) {
893 if (pdev->iso_init) {
894 Trace(TRACE_MEMORY, "Unlinking URB %p\n", urb);
895 usb_unlink_urb(urb);
896 }
897 Trace(TRACE_MEMORY, "Freeing URB\n");
898 usb_free_urb(urb);
899 pdev->sbuf[i].urb = NULL;
900 }
901 }
902
903
904
905
906 if (pdev->error_status && pdev->error_status != EPIPE) {
907 Trace(TRACE_OPEN, "Setting alternate interface 0.\n");
908 usb_set_interface(pdev->udev, 0, 0);
909 }
910
911 pdev->iso_init = 0;
912 Trace(TRACE_OPEN, "<< pwc_isoc_cleanup()\n");
913}
914
915int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
916{
917 int ret;
918
919 pwc_isoc_cleanup(pdev);
920
921 pwc_reset_buffers(pdev);
922
923 ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
924 if (ret)
925 ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
926 if (!ret)
927 if (pwc_isoc_init(pdev) < 0)
928 Info("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
929 pdev->drop_frames++;
930 return ret;
931}
932
933
934
935
936
937static int pwc_video_open(struct video_device *vdev, int mode)
938{
939 int i;
940 struct pwc_device *pdev;
941
942 Trace(TRACE_OPEN, ">> video_open called(vdev = 0x%p).\n", vdev);
943
944 if (vdev == NULL)
945 BUG();
946 pdev = (struct pwc_device *)vdev->priv;
947 if (pdev == NULL)
948 BUG();
949 if (pdev->vopen)
950 return -EBUSY;
951
952 down(&pdev->modlock);
953 if (!pdev->usb_init) {
954 Trace(TRACE_OPEN, "Doing first time initialization.\n");
955 pdev->usb_init = 1;
956
957 {
958
959 const char *sensor_type = NULL;
960
961 i = pwc_get_cmos_sensor(pdev);
962 switch(i) {
963 case -1: ; break;
964 case 0x00: sensor_type = "Hyundai CMOS sensor"; break;
965 case 0x20: sensor_type = "Sony CCD sensor + TDA8787"; break;
966 case 0x2E: sensor_type = "Sony CCD sensor + Exas 98L59"; break;
967 case 0x2F: sensor_type = "Sony CCD sensor + ADI 9804"; break;
968 case 0x30: sensor_type = "Sharp CCD sensor + TDA8787"; break;
969 case 0x3E: sensor_type = "Sharp CCD sensor + Exas 98L59"; break;
970 case 0x3F: sensor_type = "Sharp CCD sensor + ADI 9804"; break;
971 case 0x40: sensor_type = "UPA 1021 sensor"; break;
972 case 0x100: sensor_type = "VGA sensor"; break;
973 case 0x101: sensor_type = "PAL MR sensor"; break;
974 default: sensor_type = "unknown type of sensor"; break;
975 }
976 if (sensor_type != NULL)
977 Info("This %s camera is equipped with a %s (%d).\n", pdev->vdev.name, sensor_type, i);
978 }
979 }
980
981
982 if (power_save) {
983 i = pwc_camera_power(pdev, 1);
984 if (i < 0)
985 Info("Failed to restore power to the camera! (%d)\n", i);
986 }
987
988 if (pwc_set_leds(pdev, led_on, led_off) < 0)
989 Info("Failed to set LED on/off time.\n");
990
991
992 pdev->decompressor = pwc_find_decompressor(pdev->type);
993#if PWC_DEBUG
994 Debug("Found decompressor for %d at 0x%p\n", pdev->type, pdev->decompressor);
995#endif
996
997
998 i = pwc_allocate_buffers(pdev);
999 if (i < 0) {
1000 Trace(TRACE_OPEN, "Failed to allocate buffer memory.\n");
1001 up(&pdev->modlock);
1002 return i;
1003 }
1004
1005
1006 pwc_reset_buffers(pdev);
1007 for (i = 0; i < default_mbufs; i++)
1008 pdev->image_used[i] = 0;
1009 pdev->vframe_count = 0;
1010 pdev->vframes_dumped = 0;
1011 pdev->vframes_error = 0;
1012 pdev->visoc_errors = 0;
1013 pdev->error_status = 0;
1014#if PWC_DEBUG
1015 pdev->sequence = 0;
1016#endif
1017
1018
1019 pdev->vsnapshot = 0;
1020
1021
1022
1023
1024
1025 i = pwc_set_video_mode(pdev, pwc_image_sizes[pdev->vsize].x, pwc_image_sizes[pdev->vsize].y, pdev->vframes, pdev->vcompression, 0);
1026 if (i) {
1027 Trace(TRACE_OPEN, "First attempt at set_video_mode failed.\n");
1028 if (pdev->type == 730 || pdev->type == 740 || pdev->type == 750)
1029 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QSIF].x, pwc_image_sizes[PSZ_QSIF].y, 10, pdev->vcompression, 0);
1030 else
1031 i = pwc_set_video_mode(pdev, pwc_image_sizes[PSZ_QCIF].x, pwc_image_sizes[PSZ_QCIF].y, 10, pdev->vcompression, 0);
1032 }
1033 if (i) {
1034 Trace(TRACE_OPEN, "Second attempt at set_video_mode failed.\n");
1035 up(&pdev->modlock);
1036 return i;
1037 }
1038
1039 i = pwc_isoc_init(pdev);
1040 if (i) {
1041 Trace(TRACE_OPEN, "Failed to init ISOC stuff = %d.\n", i);
1042 up(&pdev->modlock);
1043 return i;
1044 }
1045
1046 pdev->vopen++;
1047
1048
1049
1050
1051 if (pdev->decompressor != NULL)
1052 pdev->decompressor->lock();
1053 up(&pdev->modlock);
1054 Trace(TRACE_OPEN, "<< video_open() returns 0.\n");
1055 return 0;
1056}
1057
1058
1059static void pwc_video_close(struct video_device *vdev)
1060{
1061 struct pwc_device *pdev;
1062 int i;
1063
1064 Trace(TRACE_OPEN, ">> video_close called(vdev = 0x%p).\n", vdev);
1065
1066 pdev = (struct pwc_device *)vdev->priv;
1067 if (pdev->vopen == 0)
1068 Info("video_close() called on closed device?\n");
1069
1070
1071
1072
1073
1074 if (pdev->vframe_count > 20)
1075 Info("Closing video device: %d frames received, dumped %d frames, %d frames with errors.\n", pdev->vframe_count, pdev->vframes_dumped, pdev->vframes_error);
1076
1077 if (pdev->decompressor != NULL) {
1078 pdev->decompressor->exit();
1079 pdev->decompressor->unlock();
1080 pdev->decompressor = NULL;
1081 }
1082
1083 pwc_isoc_cleanup(pdev);
1084 pwc_free_buffers(pdev);
1085
1086
1087 if (pdev->error_status != EPIPE) {
1088 if (pwc_set_leds(pdev, 0, 0) < 0)
1089 Info("Failed to set LED on/off time.\n");
1090 if (power_save) {
1091 i = pwc_camera_power(pdev, 0);
1092 if (i < 0)
1093 Err("Failed to power down camera (%d)\n", i);
1094 }
1095 }
1096 pdev->vopen = 0;
1097 Trace(TRACE_OPEN, "<< video_close()\n");
1098}
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112static long pwc_video_read(struct video_device *vdev, char *buf, unsigned long count, int noblock)
1113{
1114 struct pwc_device *pdev;
1115 DECLARE_WAITQUEUE(wait, current);
1116
1117 Trace(TRACE_READ, "video_read(0x%p, %p, %ld, %d) called.\n", vdev, buf, count, noblock);
1118 if (vdev == NULL)
1119 return -EFAULT;
1120 pdev = vdev->priv;
1121 if (pdev == NULL)
1122 return -EFAULT;
1123 if (pdev->error_status)
1124 return -pdev->error_status;
1125
1126
1127 if (pdev->image_read_pos == 0) {
1128
1129 add_wait_queue(&pdev->frameq, &wait);
1130 while (pdev->full_frames == NULL) {
1131
1132 if (pdev->error_status) {
1133 remove_wait_queue(&pdev->frameq, &wait);
1134 set_current_state(TASK_RUNNING);
1135 return -pdev->error_status ;
1136 }
1137 if (noblock) {
1138 remove_wait_queue(&pdev->frameq, &wait);
1139 set_current_state(TASK_RUNNING);
1140 return -EWOULDBLOCK;
1141 }
1142 if (signal_pending(current)) {
1143 remove_wait_queue(&pdev->frameq, &wait);
1144 set_current_state(TASK_RUNNING);
1145 return -ERESTARTSYS;
1146 }
1147 schedule();
1148 set_current_state(TASK_INTERRUPTIBLE);
1149 }
1150 remove_wait_queue(&pdev->frameq, &wait);
1151 set_current_state(TASK_RUNNING);
1152
1153
1154 if (pwc_handle_frame(pdev))
1155 return -EFAULT;
1156 }
1157
1158 Trace(TRACE_READ, "Copying data to user space.\n");
1159
1160 if (count + pdev->image_read_pos > pdev->view.size)
1161 count = pdev->view.size - pdev->image_read_pos;
1162 if (copy_to_user(buf, pdev->image_ptr[pdev->fill_image] + pdev->image_read_pos, count))
1163 return -EFAULT;
1164 pdev->image_read_pos += count;
1165 if (pdev->image_read_pos >= pdev->view.size) {
1166 pdev->image_read_pos = 0;
1167 pwc_next_image(pdev);
1168 }
1169 return count;
1170}
1171
1172
1173static long pwc_video_write(struct video_device *vdev, const char *buf, unsigned long count, int noblock)
1174{
1175 return -EINVAL;
1176}
1177
1178static unsigned int pwc_video_poll(struct video_device *vdev, struct file *file, poll_table *wait)
1179{
1180 struct pwc_device *pdev;
1181
1182 if (vdev == NULL)
1183 return -EFAULT;
1184 pdev = vdev->priv;
1185 if (pdev == NULL)
1186 return -EFAULT;
1187
1188 poll_wait(file, &pdev->frameq, wait);
1189 if (pdev->error_status)
1190 return POLLERR;
1191 if (pdev->full_frames != NULL)
1192 return (POLLIN | POLLRDNORM);
1193
1194 return 0;
1195}
1196
1197static int pwc_video_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
1198{
1199 struct pwc_device *pdev;
1200 DECLARE_WAITQUEUE(wait, current);
1201
1202 if (vdev == NULL)
1203 return -EFAULT;
1204 pdev = vdev->priv;
1205 if (pdev == NULL)
1206 return -EFAULT;
1207
1208 switch (cmd) {
1209
1210 case VIDIOCGCAP:
1211 {
1212 struct video_capability caps;
1213
1214 strcpy(caps.name, vdev->name);
1215 caps.type = VID_TYPE_CAPTURE;
1216 caps.channels = 1;
1217 caps.audios = 1;
1218 caps.minwidth = pdev->view_min.x;
1219 caps.minheight = pdev->view_min.y;
1220 caps.maxwidth = pdev->view_max.x;
1221 caps.maxheight = pdev->view_max.y;
1222 if (copy_to_user(arg, &caps, sizeof(caps)))
1223 return -EFAULT;
1224 break;
1225 }
1226
1227
1228 case VIDIOCGCHAN:
1229 {
1230 struct video_channel v;
1231
1232 if (copy_from_user(&v, arg, sizeof(v)))
1233 return -EFAULT;
1234 if (v.channel != 0)
1235 return -EINVAL;
1236
1237 v.flags = 0;
1238 v.tuners = 0;
1239 v.type = VIDEO_TYPE_CAMERA;
1240 strcpy(v.name, "Webcam");
1241
1242 if (copy_to_user(arg, &v, sizeof(v)))
1243 return -EFAULT;
1244
1245 return 0;
1246 }
1247
1248 case VIDIOCSCHAN:
1249 {
1250
1251
1252
1253
1254 struct video_channel v;
1255
1256 if (copy_from_user(&v, arg, sizeof(v)))
1257 return -EFAULT;
1258
1259 if (v.channel != 0)
1260 return -EINVAL;
1261
1262 return 0;
1263 }
1264
1265
1266
1267 case VIDIOCGPICT:
1268 {
1269 struct video_picture p;
1270 int val;
1271
1272 p.colour = 0x8000;
1273 p.hue = 0x8000;
1274 val = pwc_get_brightness(pdev);
1275 if (val >= 0)
1276 p.brightness = val;
1277 else
1278 p.brightness = 0xffff;
1279 val = pwc_get_contrast(pdev);
1280 if (val >= 0)
1281 p.contrast = val;
1282 else
1283 p.contrast = 0xffff;
1284
1285 val = pwc_get_gamma(pdev);
1286 if (val >= 0)
1287 p.whiteness = val;
1288 else
1289 p.whiteness = 0xffff;
1290 val = pwc_get_saturation(pdev);
1291 if (val >= 0)
1292 p.colour = val;
1293 else
1294 p.colour = 0xffff;
1295 p.depth = 24;
1296 p.palette = VIDEO_PALETTE_YUV420P;
1297 p.hue = 0xFFFF;
1298
1299 if (copy_to_user(arg, &p, sizeof(p)))
1300 return -EFAULT;
1301 break;
1302 }
1303
1304 case VIDIOCSPICT:
1305 {
1306 struct video_picture p;
1307
1308 if (copy_from_user(&p, arg, sizeof(p)))
1309 return -EFAULT;
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319 pwc_set_brightness(pdev, p.brightness);
1320 pwc_set_contrast(pdev, p.contrast);
1321 pwc_set_gamma(pdev, p.whiteness);
1322 pwc_set_saturation(pdev, p.colour);
1323 if (p.palette && p.palette != VIDEO_PALETTE_YUV420P) {
1324 return -EINVAL;
1325 }
1326 break;
1327 }
1328
1329
1330 case VIDIOCGWIN:
1331 {
1332 struct video_window vw;
1333
1334 vw.x = 0;
1335 vw.y = 0;
1336 vw.width = pdev->view.x;
1337 vw.height = pdev->view.y;
1338 vw.chromakey = 0;
1339 vw.flags = (pdev->vframes << PWC_FPS_SHIFT) |
1340 (pdev->vsnapshot ? PWC_FPS_SNAPSHOT : 0);
1341
1342 if (copy_to_user(arg, &vw, sizeof(vw)))
1343 return -EFAULT;
1344 break;
1345 }
1346
1347 case VIDIOCSWIN:
1348 {
1349 struct video_window vw;
1350 int fps, snapshot, ret;
1351
1352 if (copy_from_user(&vw, arg, sizeof(vw)))
1353 return -EFAULT;
1354
1355 fps = (vw.flags & PWC_FPS_FRMASK) >> PWC_FPS_SHIFT;
1356 snapshot = vw.flags & PWC_FPS_SNAPSHOT;
1357 if (fps == 0)
1358 fps = pdev->vframes;
1359 if (pdev->view.x == vw.width && pdev->view.y && fps == pdev->vframes && snapshot == pdev->vsnapshot)
1360 return 0;
1361 ret = pwc_try_video_mode(pdev, vw.width, vw.height, fps, pdev->vcompression, snapshot);
1362 if (ret)
1363 return ret;
1364 break;
1365 }
1366
1367
1368 case VIDIOCGFBUF:
1369 {
1370 struct video_buffer vb;
1371
1372 vb.base = NULL;
1373 vb.height = 0;
1374 vb.width = 0;
1375 vb.depth = 0;
1376 vb.bytesperline = 0;
1377
1378 if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
1379 return -EFAULT;
1380 break;
1381 }
1382
1383
1384 case VIDIOCGMBUF:
1385 {
1386
1387 struct video_mbuf vm;
1388 int i;
1389
1390 memset(&vm, 0, sizeof(vm));
1391 vm.size = default_mbufs * pdev->len_per_image;
1392 vm.frames = default_mbufs;
1393 for (i = 0; i < default_mbufs; i++)
1394 vm.offsets[i] = i * pdev->len_per_image;
1395
1396 if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
1397 return -EFAULT;
1398 break;
1399 }
1400
1401 case VIDIOCMCAPTURE:
1402 {
1403
1404 struct video_mmap vm;
1405
1406 if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm)))
1407 return -EFAULT;
1408 Trace(TRACE_READ, "VIDIOCMCAPTURE: %dx%d, frame %d, format %d\n", vm.width, vm.height, vm.frame, vm.format);
1409 if (vm.frame < 0 || vm.frame >= default_mbufs)
1410 return -EINVAL;
1411
1412
1413
1414
1415
1416
1417 if (vm.format && vm.format != VIDEO_PALETTE_YUV420P)
1418 return -EINVAL;
1419
1420 if ((vm.width != pdev->view.x || vm.height != pdev->view.y) &&
1421 (vm.width >= pdev->view_min.x && vm.height >= pdev->view_min.y)) {
1422 int ret;
1423
1424 Trace(TRACE_OPEN, "VIDIOCMCAPTURE: changing size to please xawtv :-(.\n");
1425 ret = pwc_try_video_mode(pdev, vm.width, vm.height, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
1426 if (ret)
1427 return ret;
1428 }
1429
1430
1431 if (pdev->image_used[vm.frame])
1432 return -EBUSY;
1433 pdev->image_used[vm.frame] = 1;
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443 Trace(TRACE_READ, "VIDIOCMCAPTURE done.\n");
1444 break;
1445 }
1446
1447 case VIDIOCSYNC:
1448 {
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463 int mbuf, ret;
1464
1465 if (copy_from_user((void *)&mbuf, arg, sizeof(int)))
1466 return -EFAULT;
1467
1468 Trace(TRACE_READ, "VIDIOCSYNC called (%d).\n", mbuf);
1469
1470
1471 if (mbuf < 0 || mbuf >= default_mbufs)
1472 return -EINVAL;
1473
1474 if (pdev->image_used[mbuf] == 0)
1475 return -EINVAL;
1476
1477
1478
1479
1480
1481
1482
1483
1484 add_wait_queue(&pdev->frameq, &wait);
1485 while (pdev->full_frames == NULL) {
1486 if (pdev->error_status) {
1487 remove_wait_queue(&pdev->frameq, &wait);
1488 set_current_state(TASK_RUNNING);
1489 return -pdev->error_status;
1490 }
1491 if (signal_pending(current)) {
1492 remove_wait_queue(&pdev->frameq, &wait);
1493 set_current_state(TASK_RUNNING);
1494 return -ERESTARTSYS;
1495 }
1496 schedule();
1497 set_current_state(TASK_INTERRUPTIBLE);
1498 }
1499 remove_wait_queue(&pdev->frameq, &wait);
1500 set_current_state(TASK_RUNNING);
1501
1502
1503
1504
1505
1506
1507
1508 Trace(TRACE_READ, "VIDIOCSYNC: frame ready.\n");
1509 pdev->fill_image = mbuf;
1510
1511 ret = pwc_handle_frame(pdev);
1512 pdev->image_used[mbuf] = 0;
1513 if (ret)
1514 return -EFAULT;
1515 break;
1516 }
1517
1518 case VIDIOCGAUDIO:
1519 {
1520 struct video_audio v;
1521
1522 strcpy(v.name, "Microphone");
1523 v.audio = -1;
1524 v.flags = 0;
1525 v.mode = VIDEO_SOUND_MONO;
1526 v.volume = 0;
1527 v.bass = 0;
1528 v.treble = 0;
1529 v.balance = 0x8000;
1530 v.step = 1;
1531
1532 if (copy_to_user(arg, &v, sizeof(v)))
1533 return -EFAULT;
1534 break;
1535 }
1536
1537 case VIDIOCSAUDIO:
1538 {
1539 struct video_audio v;
1540
1541 if (copy_from_user(&v, arg, sizeof(v)))
1542 return -EFAULT;
1543
1544 break;
1545 }
1546
1547 case VIDIOCGUNIT:
1548 {
1549 struct video_unit vu;
1550
1551 vu.video = pdev->vdev.minor & 0x3F;
1552 vu.audio = -1;
1553 vu.vbi = -1;
1554 vu.radio = -1;
1555 vu.teletext = -1;
1556 if (copy_to_user(arg, &vu, sizeof(vu)))
1557 return -EFAULT;
1558 break;
1559 }
1560 default:
1561 return pwc_ioctl(pdev, cmd, arg);
1562 }
1563 return 0;
1564}
1565
1566static int pwc_video_mmap(struct video_device *vdev, const char *adr, unsigned long size)
1567{
1568 struct pwc_device *pdev;
1569 unsigned long start = (unsigned long)adr;
1570 unsigned long page, pos;
1571
1572 Trace(TRACE_MEMORY, "mmap(0x%p, 0x%p, %lu) called.\n", vdev, adr, size);
1573 pdev = vdev->priv;
1574
1575 pos = (unsigned long)pdev->image_data;
1576 while (size > 0) {
1577 page = kvirt_to_pa(pos);
1578 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
1579 return -EAGAIN;
1580
1581 start += PAGE_SIZE;
1582 pos += PAGE_SIZE;
1583 if (size > PAGE_SIZE)
1584 size -= PAGE_SIZE;
1585 else
1586 size = 0;
1587 }
1588
1589 return 0;
1590}
1591
1592
1593
1594
1595
1596
1597
1598
1599static void *usb_pwc_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
1600{
1601 struct pwc_device *pdev = NULL;
1602 int vendor_id, product_id, type_id;
1603 int i, hint;
1604 int video_nr = -1;
1605 char serial_number[30], *name;
1606
1607
1608 Trace(TRACE_PROBE, "probe() called [%04X %04X], if %d\n", udev->descriptor.idVendor, udev->descriptor.idProduct, ifnum);
1609
1610
1611
1612
1613
1614 if (ifnum > 0)
1615 return NULL;
1616
1617 vendor_id = udev->descriptor.idVendor;
1618 product_id = udev->descriptor.idProduct;
1619
1620 if (vendor_id == 0x0471) {
1621 switch (product_id) {
1622 case 0x0302:
1623 Info("Philips PCA645VC USB webcam detected.\n");
1624 name = "Philips 645 webcam";
1625 type_id = 645;
1626 break;
1627 case 0x0303:
1628 Info("Philips PCA646VC USB webcam detected.\n");
1629 name = "Philips 646 webcam";
1630 type_id = 646;
1631 break;
1632 case 0x0304:
1633 Info("Askey VC010 type 2 USB webcam detected.\n");
1634 name = "Askey VC010 webcam";
1635 type_id = 646;
1636 break;
1637 case 0x0307:
1638 Info("Philips PCVC675K (Vesta) USB webcam detected.\n");
1639 name = "Philips 675 webcam";
1640 type_id = 675;
1641 break;
1642 case 0x0308:
1643 Info("Philips PCVC680K (Vesta Pro) USB webcam detected.\n");
1644 name = "Philips 680 webcam";
1645 type_id = 680;
1646 break;
1647 case 0x030C:
1648 Info("Philips PCVC690K (Vesta Pro Scan) USB webcam detected.\n");
1649 name = "Philips 690 webcam";
1650 type_id = 690;
1651 break;
1652 case 0x0310:
1653 Info("Philips PCVC730K (ToUCam Fun) USB webcam detected.\n");
1654 name = "Philips 730 webcam";
1655 type_id = 730;
1656 break;
1657 case 0x0311:
1658 Info("Philips PCVC740K (ToUCam Pro) USB webcam detected.\n");
1659 name = "Philips 740 webcam";
1660 type_id = 740;
1661 break;
1662 case 0x0312:
1663 Info("Philips PCVC750K (ToUCam Pro Scan) USB webcam detected.\n");
1664 name = "Philips 750 webcam";
1665 type_id = 750;
1666 break;
1667 case 0x0313:
1668 Info("Philips PCVC720K/40 (ToUCam XS) USB webcam detected.\n");
1669 name = "Philips 720 webcam";
1670 type_id = 720;
1671 break;
1672 default:
1673 return NULL;
1674 break;
1675 }
1676 }
1677 else if (vendor_id == 0x069A) {
1678 switch(product_id) {
1679 case 0x0001:
1680 Info("Askey VC010 type 1 USB webcam detected.\n");
1681 name = "Askey VC010 webcam";
1682 type_id = 645;
1683 break;
1684 default:
1685 return NULL;
1686 break;
1687 }
1688 }
1689 else if (vendor_id == 0x046d) {
1690 switch(product_id) {
1691 case 0x08b0:
1692 Info("Logitech QuickCam Pro 3000 USB webcam detected.\n");
1693 name = "Logitech QuickCam Pro 3000";
1694 type_id = 740;
1695 break;
1696 case 0x08b1:
1697 Info("Logitech QuickCam for Notebook Pro USB webcam detected.\n");
1698 name = "Logitech QuickCam Notebook Pro";
1699 type_id = 740;
1700 break;
1701 case 0x08b2:
1702 Info("Logitech QuickCam 4000 Pro USB webcam detected.\n");
1703 name = "Logitech QuickCam Pro 4000";
1704 type_id = 740;
1705 break;
1706 case 0x08b3:
1707 Info("Logitech QuickCam Zoom USB webcam detected.\n");
1708 name = "Logitech QuickCam Zoom";
1709 type_id = 740;
1710 break;
1711 case 0x08b4:
1712 case 0x08b5:
1713 case 0x08b6:
1714 case 0x08b7:
1715 case 0x08b8:
1716 Info("Logitech QuickCam detected (reserved ID).\n");
1717 name = "Logitech QuickCam (res.)";
1718 type_id = 730;
1719 break;
1720 default:
1721 return NULL;
1722 break;
1723 }
1724 }
1725 else if (vendor_id == 0x055d) {
1726
1727
1728
1729
1730 switch(product_id) {
1731 case 0x9000:
1732 Info("Samsung MPC-C10 USB webcam detected.\n");
1733 name = "Samsung MPC-C10";
1734 type_id = 675;
1735 break;
1736 case 0x9001:
1737 Info("Samsung MPC-C30 USB webcam detected.\n");
1738 name = "Samsung MPC-C30";
1739 type_id = 675;
1740 break;
1741 default:
1742 return NULL;
1743 break;
1744 }
1745 }
1746 else if (vendor_id == 0x041e) {
1747 switch(product_id) {
1748 case 0x400c:
1749 Info("Creative Labs Webcam 5 detected.\n");
1750 name = "Creative Labs Webcam 5";
1751 type_id = 730;
1752 break;
1753 case 0x4011:
1754 Info("Creative Labs Webcam Pro Ex detected.\n");
1755 name = "Creative Labs Webcam Pro Ex";
1756 type_id = 740;
1757 break;
1758 default:
1759 return NULL;
1760 break;
1761 }
1762 }
1763 else if (vendor_id == 0x04cc) {
1764 switch(product_id) {
1765 case 0x8116:
1766 Info("Sotec Afina Eye USB webcam detected.\n");
1767 name = "Sotec Afina Eye";
1768 type_id = 730;
1769 break;
1770 default:
1771 return NULL;
1772 break;
1773 }
1774 }
1775 else if (vendor_id == 0x0d81) {
1776 switch(product_id) {
1777 case 0x1900:
1778 Info("Visionite VCS-UC300 USB webcam detected.\n");
1779 name = "Visionite VCS-UC300";
1780 type_id = 740;
1781 break;
1782 case 0x1910:
1783 Info("Visionite VCS-UM100 USB webcam detected.\n");
1784 name = "Visionite VCS-UM100";
1785 type_id = 730;
1786 break;
1787 default:
1788 return NULL;
1789 break;
1790 }
1791 }
1792 else
1793 return NULL;
1794
1795 memset(serial_number, 0, 30);
1796 usb_string(udev, udev->descriptor.iSerialNumber, serial_number, 29);
1797 Trace(TRACE_PROBE, "Device serial number is %s\n", serial_number);
1798
1799 if (udev->descriptor.bNumConfigurations > 1)
1800 Info("Warning: more than 1 configuration available.\n");
1801
1802
1803 pdev = kmalloc(sizeof(struct pwc_device), GFP_KERNEL);
1804 if (pdev == NULL) {
1805 Err("Oops, could not allocate memory for pwc_device.\n");
1806 return NULL;
1807 }
1808 memset(pdev, 0, sizeof(struct pwc_device));
1809 pdev->type = type_id;
1810 pwc_construct(pdev);
1811 pdev->vsize = default_size;
1812 pdev->vframes = default_fps;
1813
1814 init_MUTEX(&pdev->modlock);
1815 pdev->ptrlock = SPIN_LOCK_UNLOCKED;
1816
1817 pdev->udev = udev;
1818 init_waitqueue_head(&pdev->frameq);
1819 pdev->vcompression = pwc_preferred_compression;
1820
1821 memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template));
1822 strcpy(pdev->vdev.name, name);
1823 SET_MODULE_OWNER(&pdev->vdev);
1824 pdev->vdev.priv = pdev;
1825
1826 pdev->release = udev->descriptor.bcdDevice;
1827 Trace(TRACE_PROBE, "Release: %04x\n", pdev->release);
1828
1829
1830 for (hint = 0; hint < MAX_DEV_HINTS; hint++) {
1831 if (((device_hint[hint].type == -1) || (device_hint[hint].type == pdev->type)) &&
1832 (device_hint[hint].pdev == NULL)) {
1833
1834 if ((device_hint[hint].serial_number[0] == '*') || !strcmp(device_hint[hint].serial_number, serial_number)) {
1835
1836 video_nr = device_hint[hint].device_node;
1837 Trace(TRACE_PROBE, "Found hint, will try to register as /dev/video%d\n", video_nr);
1838 break;
1839 }
1840 }
1841 }
1842
1843 i = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr);
1844 if (i < 0) {
1845 Err("Failed to register as video device (%d).\n", i);
1846 kfree(pdev);
1847 return NULL;
1848 }
1849 else {
1850 Info("Registered as /dev/video%d.\n", pdev->vdev.minor & 0x3F);
1851 }
1852
1853 if (hint < MAX_DEV_HINTS)
1854 device_hint[hint].pdev = pdev;
1855
1856 Trace(TRACE_PROBE, "probe() function returning struct at 0x%p.\n", pdev);
1857 return pdev;
1858}
1859
1860
1861static void usb_pwc_disconnect(struct usb_device *udev, void *ptr)
1862{
1863 struct pwc_device *pdev;
1864 int hint;
1865
1866 lock_kernel();
1867 pdev = (struct pwc_device *)ptr;
1868 if (pdev == NULL) {
1869 Err("pwc_disconnect() Called without private pointer.\n");
1870 unlock_kernel();
1871 return;
1872 }
1873 if (pdev->udev == NULL) {
1874 Err("pwc_disconnect() already called for %p\n", pdev);
1875 unlock_kernel();
1876 return;
1877 }
1878 if (pdev->udev != udev) {
1879 Err("pwc_disconnect() Woops: pointer mismatch udev/pdev.\n");
1880 unlock_kernel();
1881 return;
1882 }
1883#ifdef PWC_MAGIC
1884 if (pdev->magic != PWC_MAGIC) {
1885 Err("pwc_disconnect() Magic number failed. Consult your scrolls and try again.\n");
1886 unlock_kernel();
1887 return;
1888 }
1889#endif
1890
1891
1892 if (pdev->vopen) {
1893 Info("Disconnected while webcam is in use!\n");
1894 pdev->error_status = EPIPE;
1895 }
1896
1897
1898 wake_up_interruptible(&pdev->frameq);
1899
1900 while (pdev->vopen)
1901 schedule();
1902
1903 Trace(TRACE_PROBE, "Unregistering video device in disconnect().\n");
1904 video_unregister_device(&pdev->vdev);
1905
1906
1907 kfree(pdev);
1908
1909
1910 for (hint = 0; hint < MAX_DEV_HINTS; hint++)
1911 if (device_hint[hint].pdev == pdev)
1912 device_hint[hint].pdev = NULL;
1913
1914 unlock_kernel();
1915}
1916
1917
1918
1919static int pwc_atoi(const char *s)
1920{
1921 int k = 0;
1922
1923 k = 0;
1924 while (*s != '\0' && *s >= '0' && *s <= '9') {
1925 k = 10 * k + (*s - '0');
1926 s++;
1927 }
1928 return k;
1929}
1930
1931
1932
1933
1934
1935
1936static char *size = NULL;
1937static int fps = 0;
1938static int fbufs = 0;
1939static int mbufs = 0;
1940static int trace = -1;
1941static int compression = -1;
1942static int leds[2] = { -1, -1 };
1943static char *dev_hint[MAX_DEV_HINTS] = { };
1944
1945MODULE_PARM(size, "s");
1946MODULE_PARM_DESC(size, "Initial image size. One of sqcif, qsif, qcif, sif, cif, vga");
1947MODULE_PARM(fps, "i");
1948MODULE_PARM_DESC(fps, "Initial frames per second. Varies with model, useful range 5-30");
1949MODULE_PARM(fbufs, "i");
1950MODULE_PARM_DESC(fbufs, "Number of internal frame buffers to reserve");
1951MODULE_PARM(mbufs, "i");
1952MODULE_PARM_DESC(mbufs, "Number of external (mmap()ed) image buffers");
1953MODULE_PARM(trace, "i");
1954MODULE_PARM_DESC(trace, "For debugging purposes");
1955MODULE_PARM(power_save, "i");
1956MODULE_PARM_DESC(power_save, "Turn power save feature in camera on or off");
1957MODULE_PARM(compression, "i");
1958MODULE_PARM_DESC(compression, "Preferred compression quality. Range 0 (uncompressed) to 3 (high compression)");
1959MODULE_PARM(leds, "2i");
1960MODULE_PARM_DESC(leds, "LED on,off time in milliseconds");
1961MODULE_PARM(dev_hint, "0-20s");
1962MODULE_PARM_DESC(dev_hint, "Device node hints");
1963
1964MODULE_DESCRIPTION("Philips USB & OEM webcam driver");
1965MODULE_AUTHOR("Nemosoft Unv. <nemosoft@smcc.demon.nl>");
1966MODULE_LICENSE("GPL");
1967
1968static int __init usb_pwc_init(void)
1969{
1970 int i, sz;
1971 char *sizenames[PSZ_MAX] = { "sqcif", "qsif", "qcif", "sif", "cif", "vga" };
1972
1973 Info("Philips PCA645/646 + PCVC675/680/690 + PCVC730/740/750 webcam module version " PWC_VERSION " loaded.\n");
1974 Info("Also supports the Askey VC010, various Logitech Quickcams, Samsung MPC-C10 and MPC-C30,\n");
1975 Info("the Creative WebCam 5, SOTEC Afina Eye and Visionite VCS-UC300 and VCS-UM100.\n");
1976
1977 if (fps) {
1978 if (fps < 4 || fps > 30) {
1979 Err("Framerate out of bounds (4-30).\n");
1980 return -EINVAL;
1981 }
1982 default_fps = fps;
1983 Info("Default framerate set to %d.\n", default_fps);
1984 }
1985
1986 if (size) {
1987
1988 for (sz = 0; sz < PSZ_MAX; sz++) {
1989 if (!strcmp(sizenames[sz], size)) {
1990 default_size = sz;
1991 break;
1992 }
1993 }
1994 if (sz == PSZ_MAX) {
1995 Err("Size not recognized; try size=[sqcif | qsif | qcif | sif | cif | vga].\n");
1996 return -EINVAL;
1997 }
1998 Info("Default image size set to %s [%dx%d].\n", sizenames[default_size], pwc_image_sizes[default_size].x, pwc_image_sizes[default_size].y);
1999 }
2000 if (mbufs) {
2001 if (mbufs < 1 || mbufs > MAX_IMAGES) {
2002 Err("Illegal number of mmap() buffers; use a number between 1 and %d.\n", MAX_IMAGES);
2003 return -EINVAL;
2004 }
2005 default_mbufs = mbufs;
2006 Info("Number of image buffers set to %d.\n", default_mbufs);
2007 }
2008 if (fbufs) {
2009 if (fbufs < 2 || fbufs > MAX_FRAMES) {
2010 Err("Illegal number of frame buffers; use a number between 2 and %d.\n", MAX_FRAMES);
2011 return -EINVAL;
2012 }
2013 default_fbufs = fbufs;
2014 Info("Number of frame buffers set to %d.\n", default_fbufs);
2015 }
2016 if (trace >= 0) {
2017 Info("Trace options: 0x%04x\n", trace);
2018 pwc_trace = trace;
2019 }
2020 if (compression >= 0) {
2021 if (compression > 3) {
2022 Err("Invalid compression setting; use a number between 0 (uncompressed) and 3 (high).\n");
2023 return -EINVAL;
2024 }
2025 pwc_preferred_compression = compression;
2026 Info("Preferred compression set to %d.\n", pwc_preferred_compression);
2027 }
2028 if (power_save)
2029 Info("Enabling power save on open/close.\n");
2030 if (leds[0] >= 0)
2031 led_on = leds[0];
2032 if (leds[1] >= 0)
2033 led_off = leds[1];
2034
2035
2036
2037
2038
2039
2040
2041
2042 for (i = 0; i < MAX_DEV_HINTS; i++) {
2043 char *s, *colon, *dot;
2044
2045
2046 device_hint[i].pdev = NULL;
2047 s = dev_hint[i];
2048 if (s != NULL && *s != '\0') {
2049 device_hint[i].type = -1;
2050 strcpy(device_hint[i].serial_number, "*");
2051
2052
2053 colon = dot = s;
2054 while (*colon != '\0' && *colon != ':')
2055 colon++;
2056 while (*dot != '\0' && *dot != '.')
2057 dot++;
2058
2059 if (*dot != '\0' && dot > colon) {
2060 Err("Malformed camera hint: the colon must be after the dot.\n");
2061 return -EINVAL;
2062 }
2063
2064 if (*colon == '\0') {
2065
2066 if (*dot != '\0') {
2067 Err("Malformed camera hint: no colon + device node given.\n");
2068 return -EINVAL;
2069 }
2070 else {
2071
2072 device_hint[i].device_node = pwc_atoi(s);
2073 }
2074 }
2075 else {
2076
2077 device_hint[i].type = pwc_atoi(s);
2078 device_hint[i].device_node = pwc_atoi(colon + 1);
2079 if (*dot != '\0') {
2080
2081 int k;
2082
2083 dot++;
2084 k = 0;
2085 while (*dot != ':' && k < 29) {
2086 device_hint[i].serial_number[k++] = *dot;
2087 dot++;
2088 }
2089 device_hint[i].serial_number[k] = '\0';
2090 }
2091 }
2092#if PWC_DEBUG
2093 Debug("device_hint[%d]:\n", i);
2094 Debug(" type : %d\n", device_hint[i].type);
2095 Debug(" serial# : %s\n", device_hint[i].serial_number);
2096 Debug(" node : %d\n", device_hint[i].device_node);
2097#endif
2098 }
2099 else
2100 device_hint[i].type = 0;
2101 }
2102
2103 Trace(TRACE_PROBE, "Registering driver at address 0x%p.\n", &pwc_driver);
2104 return usb_register(&pwc_driver);
2105}
2106
2107static void __exit usb_pwc_exit(void)
2108{
2109 Trace(TRACE_MODULE, "Deregistering driver.\n");
2110 usb_deregister(&pwc_driver);
2111 Info("Philips webcam module removed.\n");
2112}
2113
2114module_init(usb_pwc_init);
2115module_exit(usb_pwc_exit);
2116
2117