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#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/input.h>
36#include <linux/usb/input.h>
37
38#include "usbvideo.h"
39#include "quickcam_messenger.h"
40
41
42
43
44
45#ifdef CONFIG_USB_DEBUG
46static int debug;
47#define DEBUG(n, format, arg...) \
48 if (n <= debug) { \
49 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
50 }
51#else
52#define DEBUG(n, arg...)
53static const int debug;
54#endif
55
56#define DRIVER_VERSION "v0.01"
57#define DRIVER_DESC "Logitech Quickcam Messenger USB"
58
59#define USB_LOGITECH_VENDOR_ID 0x046D
60#define USB_QCM_PRODUCT_ID 0x08F0
61
62#define MAX_CAMERAS 1
63
64#define MAX_COLOUR 32768
65#define MAX_HUE 32768
66#define MAX_BRIGHTNESS 32768
67#define MAX_CONTRAST 32768
68#define MAX_WHITENESS 32768
69
70static int size = SIZE_320X240;
71static int colour = MAX_COLOUR;
72static int hue = MAX_HUE;
73static int brightness = MAX_BRIGHTNESS;
74static int contrast = MAX_CONTRAST;
75static int whiteness = MAX_WHITENESS;
76
77static struct usbvideo *cams;
78
79static struct usb_device_id qcm_table [] = {
80 { USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
81 { }
82};
83MODULE_DEVICE_TABLE(usb, qcm_table);
84
85#ifdef CONFIG_INPUT
86static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
87{
88 struct input_dev *input_dev;
89 int error;
90
91 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
92 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
93
94 cam->input = input_dev = input_allocate_device();
95 if (!input_dev) {
96 dev_warn(&dev->dev, "insufficient mem for cam input device\n");
97 return;
98 }
99
100 input_dev->name = "QCM button";
101 input_dev->phys = cam->input_physname;
102 usb_to_input_id(dev, &input_dev->id);
103 input_dev->dev.parent = &dev->dev;
104
105 input_dev->evbit[0] = BIT_MASK(EV_KEY);
106 input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
107
108 error = input_register_device(cam->input);
109 if (error) {
110 dev_warn(&dev->dev,
111 "Failed to register camera's input device, err: %d\n",
112 error);
113 input_free_device(cam->input);
114 cam->input = NULL;
115 }
116}
117
118static void qcm_unregister_input(struct qcm *cam)
119{
120 if (cam->input) {
121 input_unregister_device(cam->input);
122 cam->input = NULL;
123 }
124}
125
126static void qcm_report_buttonstat(struct qcm *cam)
127{
128 if (cam->input) {
129 input_report_key(cam->input, KEY_CAMERA, cam->button_sts);
130 input_sync(cam->input);
131 }
132}
133
134static void qcm_int_irq(struct urb *urb)
135{
136 int ret;
137 struct uvd *uvd = urb->context;
138 struct qcm *cam;
139
140 if (!CAMERA_IS_OPERATIONAL(uvd))
141 return;
142
143 if (!uvd->streaming)
144 return;
145
146 uvd->stats.urb_count++;
147
148 if (urb->status < 0)
149 uvd->stats.iso_err_count++;
150 else {
151 if (urb->actual_length > 0 ) {
152 cam = (struct qcm *) uvd->user_data;
153 if (cam->button_sts_buf == 0x88)
154 cam->button_sts = 0x0;
155 else if (cam->button_sts_buf == 0x80)
156 cam->button_sts = 0x1;
157 qcm_report_buttonstat(cam);
158 }
159 }
160
161 ret = usb_submit_urb(urb, GFP_ATOMIC);
162 if (ret < 0)
163 err("usb_submit_urb error (%d)", ret);
164}
165
166static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
167{
168 int errflag;
169 usb_fill_int_urb(cam->button_urb, uvd->dev,
170 usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
171 &cam->button_sts_buf,
172 1,
173 qcm_int_irq,
174 uvd, 16);
175
176 errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
177 if (errflag)
178 err ("usb_submit_int ret %d", errflag);
179 return errflag;
180}
181
182static void qcm_stop_int_data(struct qcm *cam)
183{
184 usb_kill_urb(cam->button_urb);
185}
186
187static int qcm_alloc_int_urb(struct qcm *cam)
188{
189 cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
190
191 if (!cam->button_urb)
192 return -ENOMEM;
193
194 return 0;
195}
196
197static void qcm_free_int(struct qcm *cam)
198{
199 usb_free_urb(cam->button_urb);
200}
201#endif
202
203static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
204{
205 int ret;
206
207
208 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
209 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
210 reg, 0, &val, 1, 3*HZ);
211 return ret;
212}
213
214static int qcm_stv_setw(struct usb_device *dev, u16 reg, __le16 val)
215{
216 int ret;
217
218
219 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
220 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
221 reg, 0, &val, 2, 3*HZ);
222 return ret;
223}
224
225static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
226 __le16 *val)
227{
228 int ret;
229
230
231 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
232 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
233 reg, 0, val, 2, 3*HZ);
234 return ret;
235}
236
237static int qcm_camera_on(struct uvd *uvd)
238{
239 int ret;
240 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
241 return 0;
242}
243
244static int qcm_camera_off(struct uvd *uvd)
245{
246 int ret;
247 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
248 return 0;
249}
250
251static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
252{
253 unsigned int segment, valsat;
254 signed int h = (signed int) hue;
255 unsigned int s = (sat - 32768) * 2;
256 unsigned int v = val;
257 unsigned int p;
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279 if (sat < 32768) {
280
281 *r = val;
282 *g = val;
283 *b = val;
284 return;
285 }
286 if (val <= (0xFFFF/8)) {
287
288 *r = 0;
289 *g = 0;
290 *b = 0;
291 return;
292 }
293
294
295
296
297
298
299 segment = (h + 10923) & 0xFFFF;
300 segment = segment*3 >> 16;
301 hue -= segment * 21845;
302 h = hue;
303 h *= 3;
304 valsat = v*s >> 16;
305 p = v - valsat;
306 if (h >= 0) {
307 unsigned int t = v - (valsat * (32769 - h) >> 15);
308 switch (segment) {
309 case 0:
310 *r = v;
311 *g = t;
312 *b = p;
313 break;
314 case 1:
315 *r = p;
316 *g = v;
317 *b = t;
318 break;
319 case 2:
320 *r = t;
321 *g = p;
322 *b = v;
323 break;
324 }
325 } else {
326 unsigned int q = v - (valsat * (32769 + h) >> 15);
327 switch (segment) {
328 case 0:
329 *r = v;
330 *g = p;
331 *b = q;
332 break;
333 case 1:
334 *r = q;
335 *g = v;
336 *b = p;
337 break;
338 case 2:
339 *r = p;
340 *g = q;
341 *b = v;
342 break;
343 }
344 }
345}
346
347static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
348 u16 saturation, u16 value)
349{
350 int ret;
351 u16 r=0,g=0,b=0;
352
353
354 qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
355
356 r >>= 12;
357 g >>= 12;
358 b >>= 12;
359
360
361 r = max((u16) 8, r);
362 g = max((u16) 8, g);
363 b = max((u16) 8, b);
364
365 r |= 0x30;
366 g |= 0x30;
367 b |= 0x30;
368
369
370 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
371 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
372 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
373
374
375 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
376 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
377 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
378
379 return 0;
380}
381
382static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
383{
384 int ret;
385 int formedval;
386
387
388 formedval = ( exposure >> 12 );
389
390
391 formedval = min(formedval, 14);
392
393 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
394 0x143A, 0xF0 | formedval));
395 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
396 return 0;
397}
398
399static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
400 int hue, int colour)
401{
402 int ret;
403
404 CHECK_RET(ret,
405 qcm_sensor_set_exposure(uvd, brightness));
406 CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
407
408 return 0;
409}
410
411static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
412{
413 int ret;
414
415 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
416 return 0;
417}
418
419static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
420{
421 int ret;
422
423 if (whiteness > 0xC000)
424 whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
425
426 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
427 (whiteness >> 8) & 0xFF));
428 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
429 (whiteness >> 16) & 0x03));
430 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
431
432 return 0;
433}
434
435static int qcm_sensor_init(struct uvd *uvd)
436{
437 struct qcm *cam = (struct qcm *) uvd->user_data;
438 int ret;
439 int i;
440
441 for (i=0; i < ARRAY_SIZE(regval_table) ; i++) {
442 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
443 regval_table[i].reg,
444 regval_table[i].val));
445 }
446
447 CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
448 cpu_to_le16(ISOC_PACKET_SIZE)));
449 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
450 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143f, 0x01));
451
452 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
453
454 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
455
456 CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
457 uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
458
459 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
460 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
461
462 return 0;
463}
464
465static int qcm_set_camera_size(struct uvd *uvd)
466{
467 int ret;
468 struct qcm *cam = (struct qcm *) uvd->user_data;
469
470 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
471 cam->width = camera_sizes[cam->size].width;
472 cam->height = camera_sizes[cam->size].height;
473 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
474
475 return 0;
476}
477
478static int qcm_setup_on_open(struct uvd *uvd)
479{
480 int ret;
481
482 CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
483 uvd->vpic.colour, uvd->vpic.contrast));
484 CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
485 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
486 CHECK_RET(ret, qcm_set_camera_size(uvd));
487 CHECK_RET(ret, qcm_camera_on(uvd));
488 return 0;
489}
490
491static void qcm_adjust_picture(struct uvd *uvd)
492{
493 int ret;
494 struct qcm *cam = (struct qcm *) uvd->user_data;
495
496 ret = qcm_camera_off(uvd);
497 if (ret) {
498 err("can't turn camera off. abandoning pic adjustment");
499 return;
500 }
501
502
503
504
505 if ((cam->contrast != uvd->vpic.contrast) ||
506 (cam->hue != uvd->vpic.hue) ||
507 (cam->colour != uvd->vpic.colour)) {
508 cam->contrast = uvd->vpic.contrast;
509 cam->hue = uvd->vpic.hue;
510 cam->colour = uvd->vpic.colour;
511 ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
512 cam->contrast);
513 if (ret) {
514 err("can't set gains. abandoning pic adjustment");
515 return;
516 }
517 }
518
519 if (cam->brightness != uvd->vpic.brightness) {
520 cam->brightness = uvd->vpic.brightness;
521 ret = qcm_sensor_set_exposure(uvd, cam->brightness);
522 if (ret) {
523 err("can't set exposure. abandoning pic adjustment");
524 return;
525 }
526 }
527
528 if (cam->whiteness != uvd->vpic.whiteness) {
529 cam->whiteness = uvd->vpic.whiteness;
530 qcm_sensor_set_shutter(uvd, cam->whiteness);
531 if (ret) {
532 err("can't set shutter. abandoning pic adjustment");
533 return;
534 }
535 }
536
537 ret = qcm_camera_on(uvd);
538 if (ret) {
539 err("can't reenable camera. pic adjustment failed");
540 return;
541 }
542}
543
544static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
545{
546 int datalen;
547 int totaldata;
548 struct framehdr {
549 __be16 id;
550 __be16 len;
551 };
552 struct framehdr *fhdr;
553
554 totaldata = 0;
555 while (framelen) {
556 fhdr = (struct framehdr *) cdata;
557 datalen = be16_to_cpu(fhdr->len);
558 framelen -= 4;
559 cdata += 4;
560
561 if ((fhdr->id) == cpu_to_be16(0x8001)) {
562 RingQueue_Enqueue(&uvd->dp, marker, 4);
563 totaldata += 4;
564 continue;
565 }
566 if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
567 RingQueue_Enqueue(&uvd->dp, cdata, datalen);
568 totaldata += datalen;
569 }
570 framelen -= datalen;
571 cdata += datalen;
572 }
573 return totaldata;
574}
575
576static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
577{
578 int totlen;
579 int i;
580 unsigned char *cdata;
581
582 totlen=0;
583 for (i = 0; i < dataurb->number_of_packets; i++) {
584 int n = dataurb->iso_frame_desc[i].actual_length;
585 int st = dataurb->iso_frame_desc[i].status;
586
587 cdata = dataurb->transfer_buffer +
588 dataurb->iso_frame_desc[i].offset;
589
590 if (st < 0) {
591 dev_warn(&uvd->dev->dev,
592 "Data error: packet=%d. len=%d. status=%d.\n",
593 i, n, st);
594 uvd->stats.iso_err_count++;
595 continue;
596 }
597 if (!n)
598 continue;
599
600 totlen += qcm_process_frame(uvd, cdata, n);
601 }
602 return totlen;
603}
604
605static void resubmit_urb(struct uvd *uvd, struct urb *urb)
606{
607 int ret;
608
609 urb->dev = uvd->dev;
610 ret = usb_submit_urb(urb, GFP_ATOMIC);
611 if (ret)
612 err("usb_submit_urb error (%d)", ret);
613}
614
615static void qcm_isoc_irq(struct urb *urb)
616{
617 int len;
618 struct uvd *uvd = urb->context;
619
620 if (!CAMERA_IS_OPERATIONAL(uvd))
621 return;
622
623 if (!uvd->streaming)
624 return;
625
626 uvd->stats.urb_count++;
627
628 if (!urb->actual_length) {
629 resubmit_urb(uvd, urb);
630 return;
631 }
632
633 len = qcm_compress_iso(uvd, urb);
634 resubmit_urb(uvd, urb);
635 uvd->stats.urb_length = len;
636 uvd->stats.data_count += len;
637 if (len)
638 RingQueue_WakeUpInterruptible(&uvd->dp);
639}
640
641static int qcm_start_data(struct uvd *uvd)
642{
643 struct qcm *cam = (struct qcm *) uvd->user_data;
644 int i;
645 int errflag;
646 int pktsz;
647 int err;
648
649 pktsz = uvd->iso_packet_len;
650 if (!CAMERA_IS_OPERATIONAL(uvd)) {
651 err("Camera is not operational");
652 return -EFAULT;
653 }
654
655 err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
656 if (err < 0) {
657 err("usb_set_interface error");
658 uvd->last_error = err;
659 return -EBUSY;
660 }
661
662 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
663 int j, k;
664 struct urb *urb = uvd->sbuf[i].urb;
665 urb->dev = uvd->dev;
666 urb->context = uvd;
667 urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
668 urb->interval = 1;
669 urb->transfer_flags = URB_ISO_ASAP;
670 urb->transfer_buffer = uvd->sbuf[i].data;
671 urb->complete = qcm_isoc_irq;
672 urb->number_of_packets = FRAMES_PER_DESC;
673 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
674 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
675 urb->iso_frame_desc[j].offset = k;
676 urb->iso_frame_desc[j].length = pktsz;
677 }
678 }
679
680 uvd->streaming = 1;
681 uvd->curframe = -1;
682 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
683 errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
684 if (errflag)
685 err ("usb_submit_isoc(%d) ret %d", i, errflag);
686 }
687
688 CHECK_RET(err, qcm_setup_input_int(cam, uvd));
689 CHECK_RET(err, qcm_camera_on(uvd));
690 return 0;
691}
692
693static void qcm_stop_data(struct uvd *uvd)
694{
695 struct qcm *cam = (struct qcm *) uvd->user_data;
696 int i, j;
697 int ret;
698
699 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
700 return;
701
702 ret = qcm_camera_off(uvd);
703 if (ret)
704 dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n");
705
706 uvd->streaming = 0;
707
708
709 for (i=0; i < USBVIDEO_NUMSBUF; i++)
710 usb_kill_urb(uvd->sbuf[i].urb);
711
712 qcm_stop_int_data(cam);
713
714 if (!uvd->remove_pending) {
715
716 j = usb_set_interface(uvd->dev, uvd->iface,
717 uvd->ifaceAltInactive);
718 if (j < 0) {
719 err("usb_set_interface() error %d.", j);
720 uvd->last_error = j;
721 }
722 }
723}
724
725static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
726{
727 struct qcm *cam = (struct qcm *) uvd->user_data;
728 int x;
729 struct rgb *rgbL0;
730 struct rgb *rgbL1;
731 struct bayL0 *bayL0;
732 struct bayL1 *bayL1;
733 int hor,ver,hordel,verdel;
734 assert(frame != NULL);
735
736 switch (cam->size) {
737 case SIZE_160X120:
738 hor = 162; ver = 124; hordel = 1; verdel = 2;
739 break;
740 case SIZE_320X240:
741 default:
742 hor = 324; ver = 248; hordel = 2; verdel = 4;
743 break;
744 }
745
746 if (frame->scanstate == ScanState_Scanning) {
747 while (RingQueue_GetLength(&uvd->dp) >=
748 4 + (hor*verdel + hordel)) {
749 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
750 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
751 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
752 (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
753 frame->curline = 0;
754 frame->scanstate = ScanState_Lines;
755 frame->frameState = FrameState_Grabbing;
756 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
757
758
759
760
761
762 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
763 (hor*verdel + hordel));
764 break;
765 }
766 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
767 }
768 }
769
770 if (frame->scanstate == ScanState_Scanning)
771 return;
772
773
774
775
776
777
778 while ( frame->curline < cam->height &&
779 (RingQueue_GetLength(&uvd->dp) >= hor*2)) {
780
781
782 RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
783 bayL0 = (struct bayL0 *) cam->scratch;
784 bayL1 = (struct bayL1 *) (cam->scratch + hor);
785
786 rgbL0 = (struct rgb *)
787 ( frame->data + (cam->width*3*frame->curline));
788
789 rgbL1 = rgbL0 + (cam->width/2);
790
791 for (x=0; x < cam->width; x+=2) {
792 rgbL0->r = bayL0->r;
793 rgbL0->g = bayL0->g;
794 rgbL0->b = bayL1->b;
795
796 rgbL0->r2 = bayL0->r;
797 rgbL0->g2 = bayL1->g;
798 rgbL0->b2 = bayL1->b;
799
800 rgbL1->r = bayL0->r;
801 rgbL1->g = bayL1->g;
802 rgbL1->b = bayL1->b;
803
804 rgbL1->r2 = bayL0->r;
805 rgbL1->g2 = bayL1->g;
806 rgbL1->b2 = bayL1->b;
807
808 rgbL0++;
809 rgbL1++;
810
811 bayL0++;
812 bayL1++;
813 }
814
815 frame->seqRead_Length += cam->width*3*2;
816 frame->curline += 2;
817 }
818
819 if (frame->curline == cam->height) {
820 frame->frameState = FrameState_Done_Hold;
821 frame->curline = 0;
822 uvd->curframe = -1;
823 uvd->stats.frame_num++;
824 }
825}
826
827
828static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
829{
830 int ret;
831 int newsize;
832 int oldsize;
833 int x = vw->width;
834 int y = vw->height;
835 struct qcm *cam = (struct qcm *) uvd->user_data;
836
837 if (x > 0 && y > 0) {
838 DEBUG(2, "trying to find size %d,%d", x, y);
839 for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
840 if ((camera_sizes[newsize].width == x) &&
841 (camera_sizes[newsize].height == y))
842 break;
843 }
844 } else
845 newsize = cam->size;
846
847 if (newsize > MAX_FRAME_SIZE) {
848 DEBUG(1, "couldn't find size %d,%d", x, y);
849 return -EINVAL;
850 }
851
852 if (newsize == cam->size) {
853 DEBUG(1, "Nothing to do");
854 return 0;
855 }
856
857 qcm_stop_data(uvd);
858
859 if (cam->size != newsize) {
860 oldsize = cam->size;
861 cam->size = newsize;
862 ret = qcm_set_camera_size(uvd);
863 if (ret) {
864 err("Couldn't set camera size, err=%d",ret);
865
866 cam->size = oldsize;
867 return ret;
868 }
869 }
870
871
872
873 RingQueue_Flush(&uvd->dp);
874 if (uvd->curframe != -1) {
875 uvd->frame[uvd->curframe].curline = 0;
876 uvd->frame[uvd->curframe].seqRead_Length = 0;
877 uvd->frame[uvd->curframe].seqRead_Index = 0;
878 }
879
880 CHECK_RET(ret, qcm_start_data(uvd));
881 return 0;
882}
883
884static int qcm_configure_video(struct uvd *uvd)
885{
886 int ret;
887 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
888 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
889
890 uvd->vpic.colour = colour;
891 uvd->vpic.hue = hue;
892 uvd->vpic.brightness = brightness;
893 uvd->vpic.contrast = contrast;
894 uvd->vpic.whiteness = whiteness;
895 uvd->vpic.depth = 24;
896 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
897
898 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
899 strcpy(uvd->vcap.name, "QCM USB Camera");
900 uvd->vcap.type = VID_TYPE_CAPTURE;
901 uvd->vcap.channels = 1;
902 uvd->vcap.audios = 0;
903
904 uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
905 uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
906 uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
907 uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
908
909 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
910 uvd->vchan.flags = 0 ;
911 uvd->vchan.tuners = 0;
912 uvd->vchan.channel = 0;
913 uvd->vchan.type = VIDEO_TYPE_CAMERA;
914 strcpy(uvd->vchan.name, "Camera");
915
916 CHECK_RET(ret, qcm_sensor_init(uvd));
917 return 0;
918}
919
920static int qcm_probe(struct usb_interface *intf,
921 const struct usb_device_id *devid)
922{
923 int err;
924 struct uvd *uvd;
925 struct usb_device *dev = interface_to_usbdev(intf);
926 struct qcm *cam;
927 size_t buffer_size;
928 unsigned char video_ep;
929 struct usb_host_interface *interface;
930 struct usb_endpoint_descriptor *endpoint;
931 int i,j;
932 unsigned int ifacenum, ifacenum_inact=0;
933 __le16 sensor_id;
934
935
936 if (dev->descriptor.bNumConfigurations != 1)
937 return -ENODEV;
938
939
940
941 interface = &intf->cur_altsetting[0];
942 if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
943 || (interface->desc.bInterfaceSubClass !=
944 USB_CLASS_VENDOR_SPEC))
945 return -ENODEV;
946
947
948
949
950
951 for (i=0; i < intf->num_altsetting; i++) {
952 interface = &intf->cur_altsetting[i];
953 ifacenum = interface->desc.bAlternateSetting;
954
955 for (j=0; j < interface->desc.bNumEndpoints; j++) {
956 endpoint = &interface->endpoint[j].desc;
957
958 if (usb_endpoint_dir_out(endpoint))
959 continue;
960
961 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
962 if (!buffer_size) {
963 ifacenum_inact = ifacenum;
964 continue;
965 }
966
967 if (usb_endpoint_xfer_isoc(endpoint)) {
968 video_ep = endpoint->bEndpointAddress;
969
970 goto good_videoep;
971 }
972 }
973 }
974
975 err("No suitable endpoint was found\n");
976 return -ENODEV;
977
978good_videoep:
979
980 err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
981 if (err < 0) {
982 err("Failed to disable sensor stream");
983 return -EIO;
984 }
985
986
987
988
989
990
991
992
993 err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
994 if (err < 0) {
995 err("Couldn't read sensor values. Err %d\n",err);
996 return err;
997 }
998 if (sensor_id != cpu_to_le16(0x08F0)) {
999 err("Sensor ID %x != %x. Unsupported. Sorry\n",
1000 le16_to_cpu(sensor_id), (0x08F0));
1001 return -ENODEV;
1002 }
1003
1004 uvd = usbvideo_AllocateDevice(cams);
1005 if (!uvd)
1006 return -ENOMEM;
1007
1008 cam = (struct qcm *) uvd->user_data;
1009
1010
1011 cam->scratch = kmalloc(324*2, GFP_KERNEL);
1012 if (!cam->scratch)
1013 return -ENOMEM;
1014
1015
1016
1017
1018 err = qcm_alloc_int_urb(cam);
1019 if (err < 0)
1020 return err;
1021
1022
1023
1024
1025 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1026 cam->width = camera_sizes[size].width;
1027 cam->height = camera_sizes[size].height;
1028 cam->size = size;
1029
1030 uvd->debug = debug;
1031 uvd->flags = 0;
1032 uvd->dev = dev;
1033 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
1034 uvd->ifaceAltActive = ifacenum;
1035 uvd->ifaceAltInactive = ifacenum_inact;
1036 uvd->video_endp = video_ep;
1037 uvd->iso_packet_len = buffer_size;
1038 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
1039 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
1040 uvd->canvas = VIDEOSIZE(320, 240);
1041 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
1042 err = qcm_configure_video(uvd);
1043 if (err) {
1044 err("failed to configure video settings");
1045 return err;
1046 }
1047
1048 err = usbvideo_RegisterVideoDevice(uvd);
1049 if (err) {
1050 err("usbvideo_RegisterVideoDevice() failed.");
1051 return err;
1052 }
1053
1054 uvd->max_frame_size = (320 * 240 * 3);
1055 qcm_register_input(cam, dev);
1056 usb_set_intfdata(intf, uvd);
1057 return 0;
1058}
1059
1060static void qcm_free_uvd(struct uvd *uvd)
1061{
1062 struct qcm *cam = (struct qcm *) uvd->user_data;
1063
1064 kfree(cam->scratch);
1065 qcm_unregister_input(cam);
1066 qcm_free_int(cam);
1067}
1068
1069static struct usbvideo_cb qcm_driver = {
1070 .probe = qcm_probe,
1071 .setupOnOpen = qcm_setup_on_open,
1072 .processData = qcm_process_isoc,
1073 .setVideoMode = qcm_set_video_mode,
1074 .startDataPump = qcm_start_data,
1075 .stopDataPump = qcm_stop_data,
1076 .adjustPicture = qcm_adjust_picture,
1077 .userFree = qcm_free_uvd
1078};
1079
1080static int __init qcm_init(void)
1081{
1082 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
1083 DRIVER_DESC "\n");
1084
1085 return usbvideo_register(
1086 &cams,
1087 MAX_CAMERAS,
1088 sizeof(struct qcm),
1089 "QCM",
1090 &qcm_driver,
1091 THIS_MODULE,
1092 qcm_table);
1093}
1094
1095static void __exit qcm_exit(void)
1096{
1097 usbvideo_Deregister(&cams);
1098}
1099
1100module_param(size, int, 0);
1101MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
1102module_param(colour, int, 0);
1103MODULE_PARM_DESC(colour, "Initial colour");
1104module_param(hue, int, 0);
1105MODULE_PARM_DESC(hue, "Initial hue");
1106module_param(brightness, int, 0);
1107MODULE_PARM_DESC(brightness, "Initial brightness");
1108module_param(contrast, int, 0);
1109MODULE_PARM_DESC(contrast, "Initial contrast");
1110module_param(whiteness, int, 0);
1111MODULE_PARM_DESC(whiteness, "Initial whiteness");
1112
1113#ifdef CONFIG_USB_DEBUG
1114module_param(debug, int, S_IRUGO | S_IWUSR);
1115MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
1116#endif
1117
1118module_init(qcm_init);
1119module_exit(qcm_exit);
1120
1121MODULE_LICENSE("GPL");
1122MODULE_AUTHOR("Jaya Kumar");
1123MODULE_DESCRIPTION("QCM USB Camera");
1124MODULE_SUPPORTED_DEVICE("QCM USB Camera");
1125