2 * Driver for Logitech Quickcam Messenger usb video camera
3 * Copyright (C) Jaya Kumar
5 * This work was sponsored by CIS(M) Sdn Bhd.
7 * 05/08/2006 - Jaya Kumar
8 * I wrote this based on the konicawc by Simon Evans.
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
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>
39 #include "quickcam_messenger.h"
45 #ifdef CONFIG_USB_DEBUG
47 #define DEBUG(n, format, arg...) \
49 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \
52 #define DEBUG(n, arg...)
53 static const int debug = 0;
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
64 #define MAX_COLOUR 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) },
83 MODULE_DEVICE_TABLE(usb, qcm_table);
86 static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
88 struct input_dev *input_dev;
90 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
91 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
93 cam->input = input_dev = input_allocate_device();
95 warn("insufficient mem for cam input device");
99 input_dev->name = "QCM button";
100 input_dev->phys = cam->input_physname;
101 usb_to_input_id(dev, &input_dev->id);
102 input_dev->cdev.dev = &dev->dev;
104 input_dev->evbit[0] = BIT(EV_KEY);
105 input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
107 input_dev->private = cam;
109 input_register_device(cam->input);
112 static void qcm_unregister_input(struct qcm *cam)
115 input_unregister_device(cam->input);
120 static void qcm_report_buttonstat(struct qcm *cam)
123 input_report_key(cam->input, BTN_0, cam->button_sts);
124 input_sync(cam->input);
128 static void qcm_int_irq(struct urb *urb)
131 struct uvd *uvd = urb->context;
134 if (!CAMERA_IS_OPERATIONAL(uvd))
140 uvd->stats.urb_count++;
143 uvd->stats.iso_err_count++;
145 if (urb->actual_length > 0 ) {
146 cam = (struct qcm *) uvd->user_data;
147 if (cam->button_sts_buf == 0x88)
148 cam->button_sts = 0x0;
149 else if (cam->button_sts_buf == 0x80)
150 cam->button_sts = 0x1;
151 qcm_report_buttonstat(cam);
155 ret = usb_submit_urb(urb, GFP_ATOMIC);
157 err("usb_submit_urb error (%d)", ret);
160 static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
163 usb_fill_int_urb(cam->button_urb, uvd->dev,
164 usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
165 &cam->button_sts_buf,
170 errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
172 err ("usb_submit_int ret %d", errflag);
176 static void qcm_stop_int_data(struct qcm *cam)
178 usb_kill_urb(cam->button_urb);
181 static int qcm_alloc_int_urb(struct qcm *cam)
183 cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
185 if (!cam->button_urb)
191 static void qcm_free_int(struct qcm *cam)
194 usb_free_urb(cam->button_urb);
196 #endif /* CONFIG_INPUT */
198 static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
202 /* we'll wait up to 3 slices but no more */
203 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
204 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
205 reg, 0, &val, 1, 3*HZ);
209 static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val)
213 /* we'll wait up to 3 slices but no more */
214 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
215 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
216 reg, 0, &val, 2, 3*HZ);
220 static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
225 /* we'll wait up to 3 slices but no more */
226 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
227 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
228 reg, 0, val, 2, 3*HZ);
232 static int qcm_camera_on(struct uvd *uvd)
235 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
239 static int qcm_camera_off(struct uvd *uvd)
242 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
246 static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
248 unsigned int segment, valsat;
249 signed int h = (signed int) hue;
250 unsigned int s = (sat - 32768) * 2; /* rescale */
251 unsigned int v = val;
255 the registers controling gain are 8 bit of which
256 we affect only the last 4 bits with our gain.
257 we know that if saturation is 0, (unsaturated) then
258 we're grayscale (center axis of the colour cone) so
259 we set rgb=value. we use a formula obtained from
260 wikipedia to map the cone to the RGB plane. it's
261 as follows for the human value case of h=0..360,
263 h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
264 q = v(1 - f*s) , t = v(1 - (1-f)s)
265 h_i==0 => r=v , g=t, b=p
266 h_i==1 => r=q , g=v, b=p
267 h_i==2 => r=p , g=v, b=t
268 h_i==3 => r=p , g=q, b=v
269 h_i==4 => r=t , g=p, b=v
270 h_i==5 => r=v , g=p, b=q
271 the bottom side (the point) and the stuff just up
272 of that is black so we simplify those two cases.
275 /* anything less than this is unsaturated */
281 if (val <= (0xFFFF/8)) {
282 /* anything less than this is black */
289 /* the rest of this code is copying tukkat's
290 implementation of the hsv2rgb conversion as taken
291 from qc-usb-messenger code. the 10923 is 0xFFFF/6
292 to divide the cone into 6 sectors. */
294 segment = (h + 10923) & 0xFFFF;
295 segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */
296 hue -= segment * 21845; /* -10923..10923 */
299 valsat = v*s >> 16; /* 0..65534 */
302 unsigned int t = v - (valsat * (32769 - h) >> 15);
321 unsigned int q = v - (valsat * (32769 + h) >> 15);
342 static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
343 u16 saturation, u16 value)
348 /* this code is based on qc-usb-messenger */
349 qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
364 /* set the r,g,b gain registers */
365 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
366 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
367 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
369 /* doing as qc-usb did */
370 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
371 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
372 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
377 static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
382 /* calculation was from qc-usb-messenger driver */
383 formedval = ( exposure >> 12 );
385 /* max value for formedval is 14 */
386 formedval = min(formedval, 14);
388 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
389 0x143A, 0xF0 | formedval));
390 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
394 static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
398 /* brightness is exposure, contrast is gain, colour is saturation */
400 qcm_sensor_set_exposure(uvd, brightness));
401 CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
406 static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
410 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
414 static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
417 /* some rescaling as done by the qc-usb-messenger code */
418 if (whiteness > 0xC000)
419 whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
421 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
422 (whiteness >> 8) & 0xFF));
423 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
424 (whiteness >> 16) & 0x03));
425 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
430 static int qcm_sensor_init(struct uvd *uvd)
432 struct qcm *cam = (struct qcm *) uvd->user_data;
436 for (i=0; i < sizeof(regval_table)/sizeof(regval_table[0]) ; i++) {
437 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
439 regval_table[i].val));
442 CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
443 cpu_to_le16(ISOC_PACKET_SIZE)));
444 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
445 CHECK_RET(ret, ret = qcm_stv_setb(uvd->dev, 0x143f, 0x01));
447 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
449 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
451 CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
452 uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
454 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
455 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
460 static int qcm_set_camera_size(struct uvd *uvd)
463 struct qcm *cam = (struct qcm *) uvd->user_data;
465 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
466 cam->width = camera_sizes[cam->size].width;
467 cam->height = camera_sizes[cam->size].height;
468 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
473 static int qcm_setup_on_open(struct uvd *uvd)
477 CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
478 uvd->vpic.colour, uvd->vpic.contrast));
479 CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
480 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
481 CHECK_RET(ret, qcm_set_camera_size(uvd));
482 CHECK_RET(ret, qcm_camera_on(uvd));
486 static void qcm_adjust_picture(struct uvd *uvd)
489 struct qcm *cam = (struct qcm *) uvd->user_data;
491 ret = qcm_camera_off(uvd);
493 err("can't turn camera off. abandoning pic adjustment");
497 /* if there's been a change in contrast, hue, or
498 colour then we need to recalculate hsv in order
500 if ((cam->contrast != uvd->vpic.contrast) ||
501 (cam->hue != uvd->vpic.hue) ||
502 (cam->colour != uvd->vpic.colour)) {
503 cam->contrast = uvd->vpic.contrast;
504 cam->hue = uvd->vpic.hue;
505 cam->colour = uvd->vpic.colour;
506 ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
509 err("can't set gains. abandoning pic adjustment");
514 if (cam->brightness != uvd->vpic.brightness) {
515 cam->brightness = uvd->vpic.brightness;
516 ret = qcm_sensor_set_exposure(uvd, cam->brightness);
518 err("can't set exposure. abandoning pic adjustment");
523 if (cam->whiteness != uvd->vpic.whiteness) {
524 cam->whiteness = uvd->vpic.whiteness;
525 qcm_sensor_set_shutter(uvd, cam->whiteness);
527 err("can't set shutter. abandoning pic adjustment");
532 ret = qcm_camera_on(uvd);
534 err("can't reenable camera. pic adjustment failed");
539 static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
547 struct framehdr *fhdr;
551 fhdr = (struct framehdr *) cdata;
552 datalen = be16_to_cpu(fhdr->len);
556 if ((fhdr->id) == cpu_to_be16(0x8001)) {
557 RingQueue_Enqueue(&uvd->dp, marker, 4);
561 if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
562 RingQueue_Enqueue(&uvd->dp, cdata, datalen);
563 totaldata += datalen;
571 static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
575 unsigned char *cdata;
578 for (i = 0; i < dataurb->number_of_packets; i++) {
579 int n = dataurb->iso_frame_desc[i].actual_length;
580 int st = dataurb->iso_frame_desc[i].status;
582 cdata = dataurb->transfer_buffer +
583 dataurb->iso_frame_desc[i].offset;
586 warn("Data error: packet=%d. len=%d. status=%d.",
588 uvd->stats.iso_err_count++;
594 totlen += qcm_process_frame(uvd, cdata, n);
599 static void resubmit_urb(struct uvd *uvd, struct urb *urb)
604 ret = usb_submit_urb(urb, GFP_ATOMIC);
606 err("usb_submit_urb error (%d)", ret);
609 static void qcm_isoc_irq(struct urb *urb)
612 struct uvd *uvd = urb->context;
614 if (!CAMERA_IS_OPERATIONAL(uvd))
620 uvd->stats.urb_count++;
622 if (!urb->actual_length) {
623 resubmit_urb(uvd, urb);
627 len = qcm_compress_iso(uvd, urb);
628 resubmit_urb(uvd, urb);
629 uvd->stats.urb_length = len;
630 uvd->stats.data_count += len;
632 RingQueue_WakeUpInterruptible(&uvd->dp);
635 static int qcm_start_data(struct uvd *uvd)
637 struct qcm *cam = (struct qcm *) uvd->user_data;
643 pktsz = uvd->iso_packet_len;
644 if (!CAMERA_IS_OPERATIONAL(uvd)) {
645 err("Camera is not operational");
649 err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
651 err("usb_set_interface error");
652 uvd->last_error = err;
656 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
658 struct urb *urb = uvd->sbuf[i].urb;
661 urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
663 urb->transfer_flags = URB_ISO_ASAP;
664 urb->transfer_buffer = uvd->sbuf[i].data;
665 urb->complete = qcm_isoc_irq;
666 urb->number_of_packets = FRAMES_PER_DESC;
667 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
668 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
669 urb->iso_frame_desc[j].offset = k;
670 urb->iso_frame_desc[j].length = pktsz;
676 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
677 errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
679 err ("usb_submit_isoc(%d) ret %d", i, errflag);
682 CHECK_RET(err, qcm_setup_input_int(cam, uvd));
683 CHECK_RET(err, qcm_camera_on(uvd));
687 static void qcm_stop_data(struct uvd *uvd)
689 struct qcm *cam = (struct qcm *) uvd->user_data;
693 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
696 ret = qcm_camera_off(uvd);
698 warn("couldn't turn the cam off.");
702 /* Unschedule all of the iso td's */
703 for (i=0; i < USBVIDEO_NUMSBUF; i++)
704 usb_kill_urb(uvd->sbuf[i].urb);
706 qcm_stop_int_data(cam);
708 if (!uvd->remove_pending) {
709 /* Set packet size to 0 */
710 j = usb_set_interface(uvd->dev, uvd->iface,
711 uvd->ifaceAltInactive);
713 err("usb_set_interface() error %d.", j);
719 static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
721 struct qcm *cam = (struct qcm *) uvd->user_data;
727 int hor,ver,hordel,verdel;
728 assert(frame != NULL);
732 hor = 162; ver = 124; hordel = 1; verdel = 2;
736 hor = 324; ver = 248; hordel = 2; verdel = 4;
740 if (frame->scanstate == ScanState_Scanning) {
741 while (RingQueue_GetLength(&uvd->dp) >=
742 4 + (hor*verdel + hordel)) {
743 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
744 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
745 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
746 (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
748 frame->scanstate = ScanState_Lines;
749 frame->frameState = FrameState_Grabbing;
750 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
752 * if we're starting, we need to discard the first
753 * 4 lines of y bayer data
754 * and the first 2 gr elements of x bayer data
756 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
757 (hor*verdel + hordel));
760 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
764 if (frame->scanstate == ScanState_Scanning)
767 /* now we can start processing bayer data so long as we have at least
768 * 2 lines worth of data. this is the simplest demosaicing method that
769 * I could think of. I use each 2x2 bayer element without interpolation
770 * to generate 4 rgb pixels.
772 while ( frame->curline < cam->height &&
773 (RingQueue_GetLength(&uvd->dp) >= hor*2)) {
774 /* get 2 lines of bayer for demosaicing
775 * into 2 lines of RGB */
776 RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
777 bayL0 = (struct bayL0 *) cam->scratch;
778 bayL1 = (struct bayL1 *) (cam->scratch + hor);
779 /* frame->curline is the rgb y line */
780 rgbL0 = (struct rgb *)
781 ( frame->data + (cam->width*3*frame->curline));
782 /* w/2 because we're already doing 2 pixels */
783 rgbL1 = rgbL0 + (cam->width/2);
785 for (x=0; x < cam->width; x+=2) {
790 rgbL0->r2 = bayL0->r;
791 rgbL0->g2 = bayL1->g;
792 rgbL0->b2 = bayL1->b;
798 rgbL1->r2 = bayL0->r;
799 rgbL1->g2 = bayL1->g;
800 rgbL1->b2 = bayL1->b;
809 frame->seqRead_Length += cam->width*3*2;
812 /* See if we filled the frame */
813 if (frame->curline == cam->height) {
814 frame->frameState = FrameState_Done_Hold;
817 uvd->stats.frame_num++;
821 /* taken from konicawc */
822 static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
829 struct qcm *cam = (struct qcm *) uvd->user_data;
831 if (x > 0 && y > 0) {
832 DEBUG(2, "trying to find size %d,%d", x, y);
833 for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
834 if ((camera_sizes[newsize].width == x) &&
835 (camera_sizes[newsize].height == y))
841 if (newsize > MAX_FRAME_SIZE) {
842 DEBUG(1, "couldn't find size %d,%d", x, y);
846 if (newsize == cam->size) {
847 DEBUG(1, "Nothing to do");
853 if (cam->size != newsize) {
856 ret = qcm_set_camera_size(uvd);
858 err("Couldn't set camera size, err=%d",ret);
859 /* restore the original size */
865 /* Flush the input queue and clear any current frame in progress */
867 RingQueue_Flush(&uvd->dp);
868 if (uvd->curframe != -1) {
869 uvd->frame[uvd->curframe].curline = 0;
870 uvd->frame[uvd->curframe].seqRead_Length = 0;
871 uvd->frame[uvd->curframe].seqRead_Index = 0;
874 CHECK_RET(ret, qcm_start_data(uvd));
878 static int qcm_configure_video(struct uvd *uvd)
881 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
882 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
884 uvd->vpic.colour = colour;
886 uvd->vpic.brightness = brightness;
887 uvd->vpic.contrast = contrast;
888 uvd->vpic.whiteness = whiteness;
889 uvd->vpic.depth = 24;
890 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
892 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
893 strcpy(uvd->vcap.name, "QCM USB Camera");
894 uvd->vcap.type = VID_TYPE_CAPTURE;
895 uvd->vcap.channels = 1;
896 uvd->vcap.audios = 0;
898 uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
899 uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
900 uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
901 uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
903 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
904 uvd->vchan.flags = 0 ;
905 uvd->vchan.tuners = 0;
906 uvd->vchan.channel = 0;
907 uvd->vchan.type = VIDEO_TYPE_CAMERA;
908 strcpy(uvd->vchan.name, "Camera");
910 CHECK_RET(ret, qcm_sensor_init(uvd));
914 static int qcm_probe(struct usb_interface *intf,
915 const struct usb_device_id *devid)
919 struct usb_device *dev = interface_to_usbdev(intf);
922 unsigned char video_ep;
923 struct usb_host_interface *interface;
924 struct usb_endpoint_descriptor *endpoint;
926 unsigned int ifacenum, ifacenum_inact=0;
929 /* we don't support multiconfig cams */
930 if (dev->descriptor.bNumConfigurations != 1)
933 /* first check for the video interface and not
934 * the audio interface */
935 interface = &intf->cur_altsetting[0];
936 if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
937 || (interface->desc.bInterfaceSubClass !=
938 USB_CLASS_VENDOR_SPEC))
942 walk through each endpoint in each setting in the interface
943 stop when we find the one that's an isochronous IN endpoint.
945 for (i=0; i < intf->num_altsetting; i++) {
946 interface = &intf->cur_altsetting[i];
947 ifacenum = interface->desc.bAlternateSetting;
948 /* walk the end points */
949 for (j=0; j < interface->desc.bNumEndpoints; j++) {
950 endpoint = &interface->endpoint[j].desc;
952 if ((endpoint->bEndpointAddress &
953 USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
954 continue; /* not input then not good */
956 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
958 ifacenum_inact = ifacenum;
959 continue; /* 0 pkt size is not what we want */
962 if ((endpoint->bmAttributes &
963 USB_ENDPOINT_XFERTYPE_MASK) ==
964 USB_ENDPOINT_XFER_ISOC) {
965 video_ep = endpoint->bEndpointAddress;
966 /* break out of the search */
971 /* failed out since nothing useful was found */
972 err("No suitable endpoint was found\n");
976 /* disable isochronous stream before doing anything else */
977 err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
979 err("Failed to disable sensor stream");
984 Check that this is the same unknown sensor that is known to work. This
985 sensor is suspected to be the ST VV6422C001. I'll check the same value
986 that the qc-usb driver checks. This value is probably not even the
987 sensor ID since it matches the USB dev ID. Oh well. If it doesn't
988 match, it's probably a diff sensor so exit and apologize.
990 err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
992 err("Couldn't read sensor values. Err %d\n",err);
995 if (sensor_id != cpu_to_le16(0x08F0)) {
996 err("Sensor ID %x != %x. Unsupported. Sorry\n",
997 le16_to_cpu(sensor_id), (0x08F0));
1001 uvd = usbvideo_AllocateDevice(cams);
1005 cam = (struct qcm *) uvd->user_data;
1007 /* buf for doing demosaicing */
1008 cam->scratch = kmalloc(324*2, GFP_KERNEL);
1009 if (!cam->scratch) /* uvd freed in dereg */
1012 /* yes, if we fail after here, cam->scratch gets freed
1015 err = qcm_alloc_int_urb(cam);
1019 /* yes, if we fail after here, int urb gets freed
1022 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1023 cam->width = camera_sizes[size].width;
1024 cam->height = camera_sizes[size].height;
1030 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
1031 uvd->ifaceAltActive = ifacenum;
1032 uvd->ifaceAltInactive = ifacenum_inact;
1033 uvd->video_endp = video_ep;
1034 uvd->iso_packet_len = buffer_size;
1035 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
1036 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
1037 uvd->canvas = VIDEOSIZE(320, 240);
1038 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
1039 err = qcm_configure_video(uvd);
1041 err("failed to configure video settings");
1045 err = usbvideo_RegisterVideoDevice(uvd);
1046 if (err) { /* the uvd gets freed in Deregister */
1047 err("usbvideo_RegisterVideoDevice() failed.");
1051 uvd->max_frame_size = (320 * 240 * 3);
1052 qcm_register_input(cam, dev);
1053 usb_set_intfdata(intf, uvd);
1057 static void qcm_free_uvd(struct uvd *uvd)
1059 struct qcm *cam = (struct qcm *) uvd->user_data;
1061 kfree(cam->scratch);
1062 qcm_unregister_input(cam);
1066 static struct usbvideo_cb qcm_driver = {
1068 .setupOnOpen = qcm_setup_on_open,
1069 .processData = qcm_process_isoc,
1070 .setVideoMode = qcm_set_video_mode,
1071 .startDataPump = qcm_start_data,
1072 .stopDataPump = qcm_stop_data,
1073 .adjustPicture = qcm_adjust_picture,
1074 .userFree = qcm_free_uvd
1077 static int __init qcm_init(void)
1079 info(DRIVER_DESC " " DRIVER_VERSION);
1081 return usbvideo_register(
1091 static void __exit qcm_exit(void)
1093 usbvideo_Deregister(&cams);
1096 module_param(size, int, 0);
1097 MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
1098 module_param(colour, int, 0);
1099 MODULE_PARM_DESC(colour, "Initial colour");
1100 module_param(hue, int, 0);
1101 MODULE_PARM_DESC(hue, "Initial hue");
1102 module_param(brightness, int, 0);
1103 MODULE_PARM_DESC(brightness, "Initial brightness");
1104 module_param(contrast, int, 0);
1105 MODULE_PARM_DESC(contrast, "Initial contrast");
1106 module_param(whiteness, int, 0);
1107 MODULE_PARM_DESC(whiteness, "Initial whiteness");
1109 #ifdef CONFIG_USB_DEBUG
1110 module_param(debug, int, S_IRUGO | S_IWUSR);
1111 MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
1114 module_init(qcm_init);
1115 module_exit(qcm_exit);
1117 MODULE_LICENSE("GPL");
1118 MODULE_AUTHOR("Jaya Kumar");
1119 MODULE_DESCRIPTION("QCM USB Camera");
1120 MODULE_SUPPORTED_DEVICE("QCM USB Camera");