Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / drivers / media / video / usbvideo / quickcam_messenger.c
bloba2acba0bcc47586163bd4d82dffa91340354251b
1 /*
2 * Driver for Logitech Quickcam Messenger usb video camera
3 * Copyright (C) Jaya Kumar
5 * This work was sponsored by CIS(M) Sdn Bhd.
6 * History:
7 * 05/08/2006 - Jaya Kumar
8 * I wrote this based on the konicawc by Simon Evans.
9 * -
10 * Full credit for reverse engineering and creating an initial
11 * working linux driver for the VV6422 goes to the qce-ga project by
12 * Tuukka Toivonen, Jochen Hoenicke, Peter McConnell,
13 * Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as
14 * others.
15 * ---
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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>
38 #include "usbvideo.h"
39 #include "quickcam_messenger.h"
42 * Version Information
45 #ifdef CONFIG_USB_DEBUG
46 static int debug;
47 #define DEBUG(n, format, arg...) \
48 if (n <= debug) { \
49 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \
51 #else
52 #define DEBUG(n, arg...)
53 static const int debug = 0;
54 #endif
56 #define DRIVER_VERSION "v0.01"
57 #define DRIVER_DESC "Logitech Quickcam Messenger USB"
59 #define USB_LOGITECH_VENDOR_ID 0x046D
60 #define USB_QCM_PRODUCT_ID 0x08F0
62 #define MAX_CAMERAS 1
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
70 static int size = SIZE_320X240;
71 static int colour = MAX_COLOUR;
72 static int hue = MAX_HUE;
73 static int brightness = MAX_BRIGHTNESS;
74 static int contrast = MAX_CONTRAST;
75 static int whiteness = MAX_WHITENESS;
77 static struct usbvideo *cams;
79 static struct usb_device_id qcm_table [] = {
80 { USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
81 { }
83 MODULE_DEVICE_TABLE(usb, qcm_table);
85 #ifdef CONFIG_INPUT
86 static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
88 struct input_dev *input_dev;
89 int error;
91 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
92 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
94 cam->input = input_dev = input_allocate_device();
95 if (!input_dev) {
96 warn("insufficient mem for cam input device");
97 return;
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;
105 input_dev->evbit[0] = BIT_MASK(EV_KEY);
106 input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
108 error = input_register_device(cam->input);
109 if (error) {
110 warn("Failed to register camera's input device, err: %d\n",
111 error);
112 input_free_device(cam->input);
113 cam->input = NULL;
117 static void qcm_unregister_input(struct qcm *cam)
119 if (cam->input) {
120 input_unregister_device(cam->input);
121 cam->input = NULL;
125 static void qcm_report_buttonstat(struct qcm *cam)
127 if (cam->input) {
128 input_report_key(cam->input, BTN_0, cam->button_sts);
129 input_sync(cam->input);
133 static void qcm_int_irq(struct urb *urb)
135 int ret;
136 struct uvd *uvd = urb->context;
137 struct qcm *cam;
139 if (!CAMERA_IS_OPERATIONAL(uvd))
140 return;
142 if (!uvd->streaming)
143 return;
145 uvd->stats.urb_count++;
147 if (urb->status < 0)
148 uvd->stats.iso_err_count++;
149 else {
150 if (urb->actual_length > 0 ) {
151 cam = (struct qcm *) uvd->user_data;
152 if (cam->button_sts_buf == 0x88)
153 cam->button_sts = 0x0;
154 else if (cam->button_sts_buf == 0x80)
155 cam->button_sts = 0x1;
156 qcm_report_buttonstat(cam);
160 ret = usb_submit_urb(urb, GFP_ATOMIC);
161 if (ret < 0)
162 err("usb_submit_urb error (%d)", ret);
165 static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
167 int errflag;
168 usb_fill_int_urb(cam->button_urb, uvd->dev,
169 usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
170 &cam->button_sts_buf,
172 qcm_int_irq,
173 uvd, 16);
175 errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
176 if (errflag)
177 err ("usb_submit_int ret %d", errflag);
178 return errflag;
181 static void qcm_stop_int_data(struct qcm *cam)
183 usb_kill_urb(cam->button_urb);
186 static int qcm_alloc_int_urb(struct qcm *cam)
188 cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
190 if (!cam->button_urb)
191 return -ENOMEM;
193 return 0;
196 static void qcm_free_int(struct qcm *cam)
198 usb_free_urb(cam->button_urb);
200 #endif /* CONFIG_INPUT */
202 static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
204 int ret;
206 /* we'll wait up to 3 slices but no more */
207 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
208 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
209 reg, 0, &val, 1, 3*HZ);
210 return ret;
213 static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val)
215 int ret;
217 /* we'll wait up to 3 slices but no more */
218 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
219 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
220 reg, 0, &val, 2, 3*HZ);
221 return ret;
224 static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
225 __le16 *val)
227 int ret;
229 /* we'll wait up to 3 slices but no more */
230 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
231 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
232 reg, 0, val, 2, 3*HZ);
233 return ret;
236 static int qcm_camera_on(struct uvd *uvd)
238 int ret;
239 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
240 return 0;
243 static int qcm_camera_off(struct uvd *uvd)
245 int ret;
246 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
247 return 0;
250 static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
252 unsigned int segment, valsat;
253 signed int h = (signed int) hue;
254 unsigned int s = (sat - 32768) * 2; /* rescale */
255 unsigned int v = val;
256 unsigned int p;
259 the registers controlling gain are 8 bit of which
260 we affect only the last 4 bits with our gain.
261 we know that if saturation is 0, (unsaturated) then
262 we're grayscale (center axis of the colour cone) so
263 we set rgb=value. we use a formula obtained from
264 wikipedia to map the cone to the RGB plane. it's
265 as follows for the human value case of h=0..360,
266 s=0..1, v=0..1
267 h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
268 q = v(1 - f*s) , t = v(1 - (1-f)s)
269 h_i==0 => r=v , g=t, b=p
270 h_i==1 => r=q , g=v, b=p
271 h_i==2 => r=p , g=v, b=t
272 h_i==3 => r=p , g=q, b=v
273 h_i==4 => r=t , g=p, b=v
274 h_i==5 => r=v , g=p, b=q
275 the bottom side (the point) and the stuff just up
276 of that is black so we simplify those two cases.
278 if (sat < 32768) {
279 /* anything less than this is unsaturated */
280 *r = val;
281 *g = val;
282 *b = val;
283 return;
285 if (val <= (0xFFFF/8)) {
286 /* anything less than this is black */
287 *r = 0;
288 *g = 0;
289 *b = 0;
290 return;
293 /* the rest of this code is copying tukkat's
294 implementation of the hsv2rgb conversion as taken
295 from qc-usb-messenger code. the 10923 is 0xFFFF/6
296 to divide the cone into 6 sectors. */
298 segment = (h + 10923) & 0xFFFF;
299 segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */
300 hue -= segment * 21845; /* -10923..10923 */
301 h = hue;
302 h *= 3;
303 valsat = v*s >> 16; /* 0..65534 */
304 p = v - valsat;
305 if (h >= 0) {
306 unsigned int t = v - (valsat * (32769 - h) >> 15);
307 switch (segment) {
308 case 0: /* R-> */
309 *r = v;
310 *g = t;
311 *b = p;
312 break;
313 case 1: /* G-> */
314 *r = p;
315 *g = v;
316 *b = t;
317 break;
318 case 2: /* B-> */
319 *r = t;
320 *g = p;
321 *b = v;
322 break;
324 } else {
325 unsigned int q = v - (valsat * (32769 + h) >> 15);
326 switch (segment) {
327 case 0: /* ->R */
328 *r = v;
329 *g = p;
330 *b = q;
331 break;
332 case 1: /* ->G */
333 *r = q;
334 *g = v;
335 *b = p;
336 break;
337 case 2: /* ->B */
338 *r = p;
339 *g = q;
340 *b = v;
341 break;
346 static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
347 u16 saturation, u16 value)
349 int ret;
350 u16 r=0,g=0,b=0;
352 /* this code is based on qc-usb-messenger */
353 qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
355 r >>= 12;
356 g >>= 12;
357 b >>= 12;
359 /* min val is 8 */
360 r = max((u16) 8, r);
361 g = max((u16) 8, g);
362 b = max((u16) 8, b);
364 r |= 0x30;
365 g |= 0x30;
366 b |= 0x30;
368 /* set the r,g,b gain registers */
369 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
370 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
371 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
373 /* doing as qc-usb did */
374 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
375 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
376 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
378 return 0;
381 static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
383 int ret;
384 int formedval;
386 /* calculation was from qc-usb-messenger driver */
387 formedval = ( exposure >> 12 );
389 /* max value for formedval is 14 */
390 formedval = min(formedval, 14);
392 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
393 0x143A, 0xF0 | formedval));
394 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
395 return 0;
398 static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
399 int hue, int colour)
401 int ret;
402 /* brightness is exposure, contrast is gain, colour is saturation */
403 CHECK_RET(ret,
404 qcm_sensor_set_exposure(uvd, brightness));
405 CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
407 return 0;
410 static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
412 int ret;
414 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
415 return 0;
418 static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
420 int ret;
421 /* some rescaling as done by the qc-usb-messenger code */
422 if (whiteness > 0xC000)
423 whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
425 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
426 (whiteness >> 8) & 0xFF));
427 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
428 (whiteness >> 16) & 0x03));
429 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
431 return 0;
434 static int qcm_sensor_init(struct uvd *uvd)
436 struct qcm *cam = (struct qcm *) uvd->user_data;
437 int ret;
438 int i;
440 for (i=0; i < ARRAY_SIZE(regval_table) ; i++) {
441 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
442 regval_table[i].reg,
443 regval_table[i].val));
446 CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
447 cpu_to_le16(ISOC_PACKET_SIZE)));
448 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
449 CHECK_RET(ret, ret = qcm_stv_setb(uvd->dev, 0x143f, 0x01));
451 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
453 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
455 CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
456 uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
458 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
459 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
461 return 0;
464 static int qcm_set_camera_size(struct uvd *uvd)
466 int ret;
467 struct qcm *cam = (struct qcm *) uvd->user_data;
469 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
470 cam->width = camera_sizes[cam->size].width;
471 cam->height = camera_sizes[cam->size].height;
472 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
474 return 0;
477 static int qcm_setup_on_open(struct uvd *uvd)
479 int ret;
481 CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
482 uvd->vpic.colour, uvd->vpic.contrast));
483 CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
484 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
485 CHECK_RET(ret, qcm_set_camera_size(uvd));
486 CHECK_RET(ret, qcm_camera_on(uvd));
487 return 0;
490 static void qcm_adjust_picture(struct uvd *uvd)
492 int ret;
493 struct qcm *cam = (struct qcm *) uvd->user_data;
495 ret = qcm_camera_off(uvd);
496 if (ret) {
497 err("can't turn camera off. abandoning pic adjustment");
498 return;
501 /* if there's been a change in contrast, hue, or
502 colour then we need to recalculate hsv in order
503 to update gains */
504 if ((cam->contrast != uvd->vpic.contrast) ||
505 (cam->hue != uvd->vpic.hue) ||
506 (cam->colour != uvd->vpic.colour)) {
507 cam->contrast = uvd->vpic.contrast;
508 cam->hue = uvd->vpic.hue;
509 cam->colour = uvd->vpic.colour;
510 ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
511 cam->contrast);
512 if (ret) {
513 err("can't set gains. abandoning pic adjustment");
514 return;
518 if (cam->brightness != uvd->vpic.brightness) {
519 cam->brightness = uvd->vpic.brightness;
520 ret = qcm_sensor_set_exposure(uvd, cam->brightness);
521 if (ret) {
522 err("can't set exposure. abandoning pic adjustment");
523 return;
527 if (cam->whiteness != uvd->vpic.whiteness) {
528 cam->whiteness = uvd->vpic.whiteness;
529 qcm_sensor_set_shutter(uvd, cam->whiteness);
530 if (ret) {
531 err("can't set shutter. abandoning pic adjustment");
532 return;
536 ret = qcm_camera_on(uvd);
537 if (ret) {
538 err("can't reenable camera. pic adjustment failed");
539 return;
543 static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
545 int datalen;
546 int totaldata;
547 struct framehdr {
548 __be16 id;
549 __be16 len;
551 struct framehdr *fhdr;
553 totaldata = 0;
554 while (framelen) {
555 fhdr = (struct framehdr *) cdata;
556 datalen = be16_to_cpu(fhdr->len);
557 framelen -= 4;
558 cdata += 4;
560 if ((fhdr->id) == cpu_to_be16(0x8001)) {
561 RingQueue_Enqueue(&uvd->dp, marker, 4);
562 totaldata += 4;
563 continue;
565 if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
566 RingQueue_Enqueue(&uvd->dp, cdata, datalen);
567 totaldata += datalen;
569 framelen -= datalen;
570 cdata += datalen;
572 return totaldata;
575 static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
577 int totlen;
578 int i;
579 unsigned char *cdata;
581 totlen=0;
582 for (i = 0; i < dataurb->number_of_packets; i++) {
583 int n = dataurb->iso_frame_desc[i].actual_length;
584 int st = dataurb->iso_frame_desc[i].status;
586 cdata = dataurb->transfer_buffer +
587 dataurb->iso_frame_desc[i].offset;
589 if (st < 0) {
590 warn("Data error: packet=%d. len=%d. status=%d.",
591 i, n, st);
592 uvd->stats.iso_err_count++;
593 continue;
595 if (!n)
596 continue;
598 totlen += qcm_process_frame(uvd, cdata, n);
600 return totlen;
603 static void resubmit_urb(struct uvd *uvd, struct urb *urb)
605 int ret;
607 urb->dev = uvd->dev;
608 ret = usb_submit_urb(urb, GFP_ATOMIC);
609 if (ret)
610 err("usb_submit_urb error (%d)", ret);
613 static void qcm_isoc_irq(struct urb *urb)
615 int len;
616 struct uvd *uvd = urb->context;
618 if (!CAMERA_IS_OPERATIONAL(uvd))
619 return;
621 if (!uvd->streaming)
622 return;
624 uvd->stats.urb_count++;
626 if (!urb->actual_length) {
627 resubmit_urb(uvd, urb);
628 return;
631 len = qcm_compress_iso(uvd, urb);
632 resubmit_urb(uvd, urb);
633 uvd->stats.urb_length = len;
634 uvd->stats.data_count += len;
635 if (len)
636 RingQueue_WakeUpInterruptible(&uvd->dp);
639 static int qcm_start_data(struct uvd *uvd)
641 struct qcm *cam = (struct qcm *) uvd->user_data;
642 int i;
643 int errflag;
644 int pktsz;
645 int err;
647 pktsz = uvd->iso_packet_len;
648 if (!CAMERA_IS_OPERATIONAL(uvd)) {
649 err("Camera is not operational");
650 return -EFAULT;
653 err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
654 if (err < 0) {
655 err("usb_set_interface error");
656 uvd->last_error = err;
657 return -EBUSY;
660 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
661 int j, k;
662 struct urb *urb = uvd->sbuf[i].urb;
663 urb->dev = uvd->dev;
664 urb->context = uvd;
665 urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
666 urb->interval = 1;
667 urb->transfer_flags = URB_ISO_ASAP;
668 urb->transfer_buffer = uvd->sbuf[i].data;
669 urb->complete = qcm_isoc_irq;
670 urb->number_of_packets = FRAMES_PER_DESC;
671 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
672 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
673 urb->iso_frame_desc[j].offset = k;
674 urb->iso_frame_desc[j].length = pktsz;
678 uvd->streaming = 1;
679 uvd->curframe = -1;
680 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
681 errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
682 if (errflag)
683 err ("usb_submit_isoc(%d) ret %d", i, errflag);
686 CHECK_RET(err, qcm_setup_input_int(cam, uvd));
687 CHECK_RET(err, qcm_camera_on(uvd));
688 return 0;
691 static void qcm_stop_data(struct uvd *uvd)
693 struct qcm *cam = (struct qcm *) uvd->user_data;
694 int i, j;
695 int ret;
697 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
698 return;
700 ret = qcm_camera_off(uvd);
701 if (ret)
702 warn("couldn't turn the cam off.");
704 uvd->streaming = 0;
706 /* Unschedule all of the iso td's */
707 for (i=0; i < USBVIDEO_NUMSBUF; i++)
708 usb_kill_urb(uvd->sbuf[i].urb);
710 qcm_stop_int_data(cam);
712 if (!uvd->remove_pending) {
713 /* Set packet size to 0 */
714 j = usb_set_interface(uvd->dev, uvd->iface,
715 uvd->ifaceAltInactive);
716 if (j < 0) {
717 err("usb_set_interface() error %d.", j);
718 uvd->last_error = j;
723 static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
725 struct qcm *cam = (struct qcm *) uvd->user_data;
726 int x;
727 struct rgb *rgbL0;
728 struct rgb *rgbL1;
729 struct bayL0 *bayL0;
730 struct bayL1 *bayL1;
731 int hor,ver,hordel,verdel;
732 assert(frame != NULL);
734 switch (cam->size) {
735 case SIZE_160X120:
736 hor = 162; ver = 124; hordel = 1; verdel = 2;
737 break;
738 case SIZE_320X240:
739 default:
740 hor = 324; ver = 248; hordel = 2; verdel = 4;
741 break;
744 if (frame->scanstate == ScanState_Scanning) {
745 while (RingQueue_GetLength(&uvd->dp) >=
746 4 + (hor*verdel + hordel)) {
747 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
748 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
749 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
750 (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
751 frame->curline = 0;
752 frame->scanstate = ScanState_Lines;
753 frame->frameState = FrameState_Grabbing;
754 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
756 * if we're starting, we need to discard the first
757 * 4 lines of y bayer data
758 * and the first 2 gr elements of x bayer data
760 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
761 (hor*verdel + hordel));
762 break;
764 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
768 if (frame->scanstate == ScanState_Scanning)
769 return;
771 /* now we can start processing bayer data so long as we have at least
772 * 2 lines worth of data. this is the simplest demosaicing method that
773 * I could think of. I use each 2x2 bayer element without interpolation
774 * to generate 4 rgb pixels.
776 while ( frame->curline < cam->height &&
777 (RingQueue_GetLength(&uvd->dp) >= hor*2)) {
778 /* get 2 lines of bayer for demosaicing
779 * into 2 lines of RGB */
780 RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
781 bayL0 = (struct bayL0 *) cam->scratch;
782 bayL1 = (struct bayL1 *) (cam->scratch + hor);
783 /* frame->curline is the rgb y line */
784 rgbL0 = (struct rgb *)
785 ( frame->data + (cam->width*3*frame->curline));
786 /* w/2 because we're already doing 2 pixels */
787 rgbL1 = rgbL0 + (cam->width/2);
789 for (x=0; x < cam->width; x+=2) {
790 rgbL0->r = bayL0->r;
791 rgbL0->g = bayL0->g;
792 rgbL0->b = bayL1->b;
794 rgbL0->r2 = bayL0->r;
795 rgbL0->g2 = bayL1->g;
796 rgbL0->b2 = bayL1->b;
798 rgbL1->r = bayL0->r;
799 rgbL1->g = bayL1->g;
800 rgbL1->b = bayL1->b;
802 rgbL1->r2 = bayL0->r;
803 rgbL1->g2 = bayL1->g;
804 rgbL1->b2 = bayL1->b;
806 rgbL0++;
807 rgbL1++;
809 bayL0++;
810 bayL1++;
813 frame->seqRead_Length += cam->width*3*2;
814 frame->curline += 2;
816 /* See if we filled the frame */
817 if (frame->curline == cam->height) {
818 frame->frameState = FrameState_Done_Hold;
819 frame->curline = 0;
820 uvd->curframe = -1;
821 uvd->stats.frame_num++;
825 /* taken from konicawc */
826 static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
828 int ret;
829 int newsize;
830 int oldsize;
831 int x = vw->width;
832 int y = vw->height;
833 struct qcm *cam = (struct qcm *) uvd->user_data;
835 if (x > 0 && y > 0) {
836 DEBUG(2, "trying to find size %d,%d", x, y);
837 for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
838 if ((camera_sizes[newsize].width == x) &&
839 (camera_sizes[newsize].height == y))
840 break;
842 } else
843 newsize = cam->size;
845 if (newsize > MAX_FRAME_SIZE) {
846 DEBUG(1, "couldn't find size %d,%d", x, y);
847 return -EINVAL;
850 if (newsize == cam->size) {
851 DEBUG(1, "Nothing to do");
852 return 0;
855 qcm_stop_data(uvd);
857 if (cam->size != newsize) {
858 oldsize = cam->size;
859 cam->size = newsize;
860 ret = qcm_set_camera_size(uvd);
861 if (ret) {
862 err("Couldn't set camera size, err=%d",ret);
863 /* restore the original size */
864 cam->size = oldsize;
865 return ret;
869 /* Flush the input queue and clear any current frame in progress */
871 RingQueue_Flush(&uvd->dp);
872 if (uvd->curframe != -1) {
873 uvd->frame[uvd->curframe].curline = 0;
874 uvd->frame[uvd->curframe].seqRead_Length = 0;
875 uvd->frame[uvd->curframe].seqRead_Index = 0;
878 CHECK_RET(ret, qcm_start_data(uvd));
879 return 0;
882 static int qcm_configure_video(struct uvd *uvd)
884 int ret;
885 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
886 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
888 uvd->vpic.colour = colour;
889 uvd->vpic.hue = hue;
890 uvd->vpic.brightness = brightness;
891 uvd->vpic.contrast = contrast;
892 uvd->vpic.whiteness = whiteness;
893 uvd->vpic.depth = 24;
894 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
896 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
897 strcpy(uvd->vcap.name, "QCM USB Camera");
898 uvd->vcap.type = VID_TYPE_CAPTURE;
899 uvd->vcap.channels = 1;
900 uvd->vcap.audios = 0;
902 uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
903 uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
904 uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
905 uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
907 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
908 uvd->vchan.flags = 0 ;
909 uvd->vchan.tuners = 0;
910 uvd->vchan.channel = 0;
911 uvd->vchan.type = VIDEO_TYPE_CAMERA;
912 strcpy(uvd->vchan.name, "Camera");
914 CHECK_RET(ret, qcm_sensor_init(uvd));
915 return 0;
918 static int qcm_probe(struct usb_interface *intf,
919 const struct usb_device_id *devid)
921 int err;
922 struct uvd *uvd;
923 struct usb_device *dev = interface_to_usbdev(intf);
924 struct qcm *cam;
925 size_t buffer_size;
926 unsigned char video_ep;
927 struct usb_host_interface *interface;
928 struct usb_endpoint_descriptor *endpoint;
929 int i,j;
930 unsigned int ifacenum, ifacenum_inact=0;
931 __le16 sensor_id;
933 /* we don't support multiconfig cams */
934 if (dev->descriptor.bNumConfigurations != 1)
935 return -ENODEV;
937 /* first check for the video interface and not
938 * the audio interface */
939 interface = &intf->cur_altsetting[0];
940 if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
941 || (interface->desc.bInterfaceSubClass !=
942 USB_CLASS_VENDOR_SPEC))
943 return -ENODEV;
946 walk through each endpoint in each setting in the interface
947 stop when we find the one that's an isochronous IN endpoint.
949 for (i=0; i < intf->num_altsetting; i++) {
950 interface = &intf->cur_altsetting[i];
951 ifacenum = interface->desc.bAlternateSetting;
952 /* walk the end points */
953 for (j=0; j < interface->desc.bNumEndpoints; j++) {
954 endpoint = &interface->endpoint[j].desc;
956 if ((endpoint->bEndpointAddress &
957 USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
958 continue; /* not input then not good */
960 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
961 if (!buffer_size) {
962 ifacenum_inact = ifacenum;
963 continue; /* 0 pkt size is not what we want */
966 if ((endpoint->bmAttributes &
967 USB_ENDPOINT_XFERTYPE_MASK) ==
968 USB_ENDPOINT_XFER_ISOC) {
969 video_ep = endpoint->bEndpointAddress;
970 /* break out of the search */
971 goto good_videoep;
975 /* failed out since nothing useful was found */
976 err("No suitable endpoint was found\n");
977 return -ENODEV;
979 good_videoep:
980 /* disable isochronous stream before doing anything else */
981 err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
982 if (err < 0) {
983 err("Failed to disable sensor stream");
984 return -EIO;
988 Check that this is the same unknown sensor that is known to work. This
989 sensor is suspected to be the ST VV6422C001. I'll check the same value
990 that the qc-usb driver checks. This value is probably not even the
991 sensor ID since it matches the USB dev ID. Oh well. If it doesn't
992 match, it's probably a diff sensor so exit and apologize.
994 err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
995 if (err < 0) {
996 err("Couldn't read sensor values. Err %d\n",err);
997 return err;
999 if (sensor_id != cpu_to_le16(0x08F0)) {
1000 err("Sensor ID %x != %x. Unsupported. Sorry\n",
1001 le16_to_cpu(sensor_id), (0x08F0));
1002 return -ENODEV;
1005 uvd = usbvideo_AllocateDevice(cams);
1006 if (!uvd)
1007 return -ENOMEM;
1009 cam = (struct qcm *) uvd->user_data;
1011 /* buf for doing demosaicing */
1012 cam->scratch = kmalloc(324*2, GFP_KERNEL);
1013 if (!cam->scratch) /* uvd freed in dereg */
1014 return -ENOMEM;
1016 /* yes, if we fail after here, cam->scratch gets freed
1017 by qcm_free_uvd */
1019 err = qcm_alloc_int_urb(cam);
1020 if (err < 0)
1021 return err;
1023 /* yes, if we fail after here, int urb gets freed
1024 by qcm_free_uvd */
1026 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1027 cam->width = camera_sizes[size].width;
1028 cam->height = camera_sizes[size].height;
1029 cam->size = size;
1031 uvd->debug = debug;
1032 uvd->flags = 0;
1033 uvd->dev = dev;
1034 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
1035 uvd->ifaceAltActive = ifacenum;
1036 uvd->ifaceAltInactive = ifacenum_inact;
1037 uvd->video_endp = video_ep;
1038 uvd->iso_packet_len = buffer_size;
1039 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
1040 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
1041 uvd->canvas = VIDEOSIZE(320, 240);
1042 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
1043 err = qcm_configure_video(uvd);
1044 if (err) {
1045 err("failed to configure video settings");
1046 return err;
1049 err = usbvideo_RegisterVideoDevice(uvd);
1050 if (err) { /* the uvd gets freed in Deregister */
1051 err("usbvideo_RegisterVideoDevice() failed.");
1052 return err;
1055 uvd->max_frame_size = (320 * 240 * 3);
1056 qcm_register_input(cam, dev);
1057 usb_set_intfdata(intf, uvd);
1058 return 0;
1061 static void qcm_free_uvd(struct uvd *uvd)
1063 struct qcm *cam = (struct qcm *) uvd->user_data;
1065 kfree(cam->scratch);
1066 qcm_unregister_input(cam);
1067 qcm_free_int(cam);
1070 static struct usbvideo_cb qcm_driver = {
1071 .probe = qcm_probe,
1072 .setupOnOpen = qcm_setup_on_open,
1073 .processData = qcm_process_isoc,
1074 .setVideoMode = qcm_set_video_mode,
1075 .startDataPump = qcm_start_data,
1076 .stopDataPump = qcm_stop_data,
1077 .adjustPicture = qcm_adjust_picture,
1078 .userFree = qcm_free_uvd
1081 static int __init qcm_init(void)
1083 info(DRIVER_DESC " " DRIVER_VERSION);
1085 return usbvideo_register(
1086 &cams,
1087 MAX_CAMERAS,
1088 sizeof(struct qcm),
1089 "QCM",
1090 &qcm_driver,
1091 THIS_MODULE,
1092 qcm_table);
1095 static void __exit qcm_exit(void)
1097 usbvideo_Deregister(&cams);
1100 module_param(size, int, 0);
1101 MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
1102 module_param(colour, int, 0);
1103 MODULE_PARM_DESC(colour, "Initial colour");
1104 module_param(hue, int, 0);
1105 MODULE_PARM_DESC(hue, "Initial hue");
1106 module_param(brightness, int, 0);
1107 MODULE_PARM_DESC(brightness, "Initial brightness");
1108 module_param(contrast, int, 0);
1109 MODULE_PARM_DESC(contrast, "Initial contrast");
1110 module_param(whiteness, int, 0);
1111 MODULE_PARM_DESC(whiteness, "Initial whiteness");
1113 #ifdef CONFIG_USB_DEBUG
1114 module_param(debug, int, S_IRUGO | S_IWUSR);
1115 MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
1116 #endif
1118 module_init(qcm_init);
1119 module_exit(qcm_exit);
1121 MODULE_LICENSE("GPL");
1122 MODULE_AUTHOR("Jaya Kumar");
1123 MODULE_DESCRIPTION("QCM USB Camera");
1124 MODULE_SUPPORTED_DEVICE("QCM USB Camera");