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)
193 usb_free_urb(cam->button_urb);
195 #endif /* CONFIG_INPUT */
197 static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
201 /* we'll wait up to 3 slices but no more */
202 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
203 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
204 reg, 0, &val, 1, 3*HZ);
208 static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val)
212 /* we'll wait up to 3 slices but no more */
213 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
214 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
215 reg, 0, &val, 2, 3*HZ);
219 static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
224 /* we'll wait up to 3 slices but no more */
225 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
226 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
227 reg, 0, val, 2, 3*HZ);
231 static int qcm_camera_on(struct uvd *uvd)
234 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
238 static int qcm_camera_off(struct uvd *uvd)
241 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
245 static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
247 unsigned int segment, valsat;
248 signed int h = (signed int) hue;
249 unsigned int s = (sat - 32768) * 2; /* rescale */
250 unsigned int v = val;
254 the registers controling gain are 8 bit of which
255 we affect only the last 4 bits with our gain.
256 we know that if saturation is 0, (unsaturated) then
257 we're grayscale (center axis of the colour cone) so
258 we set rgb=value. we use a formula obtained from
259 wikipedia to map the cone to the RGB plane. it's
260 as follows for the human value case of h=0..360,
262 h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
263 q = v(1 - f*s) , t = v(1 - (1-f)s)
264 h_i==0 => r=v , g=t, b=p
265 h_i==1 => r=q , g=v, b=p
266 h_i==2 => r=p , g=v, b=t
267 h_i==3 => r=p , g=q, b=v
268 h_i==4 => r=t , g=p, b=v
269 h_i==5 => r=v , g=p, b=q
270 the bottom side (the point) and the stuff just up
271 of that is black so we simplify those two cases.
274 /* anything less than this is unsaturated */
280 if (val <= (0xFFFF/8)) {
281 /* anything less than this is black */
288 /* the rest of this code is copying tukkat's
289 implementation of the hsv2rgb conversion as taken
290 from qc-usb-messenger code. the 10923 is 0xFFFF/6
291 to divide the cone into 6 sectors. */
293 segment = (h + 10923) & 0xFFFF;
294 segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */
295 hue -= segment * 21845; /* -10923..10923 */
298 valsat = v*s >> 16; /* 0..65534 */
301 unsigned int t = v - (valsat * (32769 - h) >> 15);
320 unsigned int q = v - (valsat * (32769 + h) >> 15);
341 static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
342 u16 saturation, u16 value)
347 /* this code is based on qc-usb-messenger */
348 qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
363 /* set the r,g,b gain registers */
364 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
365 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
366 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
368 /* doing as qc-usb did */
369 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
370 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
371 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
376 static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
381 /* calculation was from qc-usb-messenger driver */
382 formedval = ( exposure >> 12 );
384 /* max value for formedval is 14 */
385 formedval = min(formedval, 14);
387 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
388 0x143A, 0xF0 | formedval));
389 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
393 static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
397 /* brightness is exposure, contrast is gain, colour is saturation */
399 qcm_sensor_set_exposure(uvd, brightness));
400 CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
405 static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
409 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
413 static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
416 /* some rescaling as done by the qc-usb-messenger code */
417 if (whiteness > 0xC000)
418 whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
420 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
421 (whiteness >> 8) & 0xFF));
422 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
423 (whiteness >> 16) & 0x03));
424 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
429 static int qcm_sensor_init(struct uvd *uvd)
431 struct qcm *cam = (struct qcm *) uvd->user_data;
435 for (i=0; i < sizeof(regval_table)/sizeof(regval_table[0]) ; i++) {
436 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
438 regval_table[i].val));
441 CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
442 cpu_to_le16(ISOC_PACKET_SIZE)));
443 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
444 CHECK_RET(ret, ret = qcm_stv_setb(uvd->dev, 0x143f, 0x01));
446 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
448 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
450 CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
451 uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
453 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
454 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
459 static int qcm_set_camera_size(struct uvd *uvd)
462 struct qcm *cam = (struct qcm *) uvd->user_data;
464 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
465 cam->width = camera_sizes[cam->size].width;
466 cam->height = camera_sizes[cam->size].height;
467 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
472 static int qcm_setup_on_open(struct uvd *uvd)
476 CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
477 uvd->vpic.colour, uvd->vpic.contrast));
478 CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
479 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
480 CHECK_RET(ret, qcm_set_camera_size(uvd));
481 CHECK_RET(ret, qcm_camera_on(uvd));
485 static void qcm_adjust_picture(struct uvd *uvd)
488 struct qcm *cam = (struct qcm *) uvd->user_data;
490 ret = qcm_camera_off(uvd);
492 err("can't turn camera off. abandoning pic adjustment");
496 /* if there's been a change in contrast, hue, or
497 colour then we need to recalculate hsv in order
499 if ((cam->contrast != uvd->vpic.contrast) ||
500 (cam->hue != uvd->vpic.hue) ||
501 (cam->colour != uvd->vpic.colour)) {
502 cam->contrast = uvd->vpic.contrast;
503 cam->hue = uvd->vpic.hue;
504 cam->colour = uvd->vpic.colour;
505 ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
508 err("can't set gains. abandoning pic adjustment");
513 if (cam->brightness != uvd->vpic.brightness) {
514 cam->brightness = uvd->vpic.brightness;
515 ret = qcm_sensor_set_exposure(uvd, cam->brightness);
517 err("can't set exposure. abandoning pic adjustment");
522 if (cam->whiteness != uvd->vpic.whiteness) {
523 cam->whiteness = uvd->vpic.whiteness;
524 qcm_sensor_set_shutter(uvd, cam->whiteness);
526 err("can't set shutter. abandoning pic adjustment");
531 ret = qcm_camera_on(uvd);
533 err("can't reenable camera. pic adjustment failed");
538 static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
546 struct framehdr *fhdr;
550 fhdr = (struct framehdr *) cdata;
551 datalen = be16_to_cpu(fhdr->len);
555 if ((fhdr->id) == cpu_to_be16(0x8001)) {
556 RingQueue_Enqueue(&uvd->dp, marker, 4);
560 if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
561 RingQueue_Enqueue(&uvd->dp, cdata, datalen);
562 totaldata += datalen;
570 static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
574 unsigned char *cdata;
577 for (i = 0; i < dataurb->number_of_packets; i++) {
578 int n = dataurb->iso_frame_desc[i].actual_length;
579 int st = dataurb->iso_frame_desc[i].status;
581 cdata = dataurb->transfer_buffer +
582 dataurb->iso_frame_desc[i].offset;
585 warn("Data error: packet=%d. len=%d. status=%d.",
587 uvd->stats.iso_err_count++;
593 totlen += qcm_process_frame(uvd, cdata, n);
598 static void resubmit_urb(struct uvd *uvd, struct urb *urb)
603 ret = usb_submit_urb(urb, GFP_ATOMIC);
605 err("usb_submit_urb error (%d)", ret);
608 static void qcm_isoc_irq(struct urb *urb)
611 struct uvd *uvd = urb->context;
613 if (!CAMERA_IS_OPERATIONAL(uvd))
619 uvd->stats.urb_count++;
621 if (!urb->actual_length) {
622 resubmit_urb(uvd, urb);
626 len = qcm_compress_iso(uvd, urb);
627 resubmit_urb(uvd, urb);
628 uvd->stats.urb_length = len;
629 uvd->stats.data_count += len;
631 RingQueue_WakeUpInterruptible(&uvd->dp);
634 static int qcm_start_data(struct uvd *uvd)
636 struct qcm *cam = (struct qcm *) uvd->user_data;
642 pktsz = uvd->iso_packet_len;
643 if (!CAMERA_IS_OPERATIONAL(uvd)) {
644 err("Camera is not operational");
648 err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
650 err("usb_set_interface error");
651 uvd->last_error = err;
655 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
657 struct urb *urb = uvd->sbuf[i].urb;
660 urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
662 urb->transfer_flags = URB_ISO_ASAP;
663 urb->transfer_buffer = uvd->sbuf[i].data;
664 urb->complete = qcm_isoc_irq;
665 urb->number_of_packets = FRAMES_PER_DESC;
666 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
667 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
668 urb->iso_frame_desc[j].offset = k;
669 urb->iso_frame_desc[j].length = pktsz;
675 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
676 errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
678 err ("usb_submit_isoc(%d) ret %d", i, errflag);
681 CHECK_RET(err, qcm_setup_input_int(cam, uvd));
682 CHECK_RET(err, qcm_camera_on(uvd));
686 static void qcm_stop_data(struct uvd *uvd)
688 struct qcm *cam = (struct qcm *) uvd->user_data;
692 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
695 ret = qcm_camera_off(uvd);
697 warn("couldn't turn the cam off.");
701 /* Unschedule all of the iso td's */
702 for (i=0; i < USBVIDEO_NUMSBUF; i++)
703 usb_kill_urb(uvd->sbuf[i].urb);
705 qcm_stop_int_data(cam);
707 if (!uvd->remove_pending) {
708 /* Set packet size to 0 */
709 j = usb_set_interface(uvd->dev, uvd->iface,
710 uvd->ifaceAltInactive);
712 err("usb_set_interface() error %d.", j);
718 static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
720 struct qcm *cam = (struct qcm *) uvd->user_data;
726 int hor,ver,hordel,verdel;
727 assert(frame != NULL);
731 hor = 162; ver = 124; hordel = 1; verdel = 2;
735 hor = 324; ver = 248; hordel = 2; verdel = 4;
739 if (frame->scanstate == ScanState_Scanning) {
740 while (RingQueue_GetLength(&uvd->dp) >=
741 4 + (hor*verdel + hordel)) {
742 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
743 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
744 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
745 (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
747 frame->scanstate = ScanState_Lines;
748 frame->frameState = FrameState_Grabbing;
749 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
751 * if we're starting, we need to discard the first
752 * 4 lines of y bayer data
753 * and the first 2 gr elements of x bayer data
755 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
756 (hor*verdel + hordel));
759 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
763 if (frame->scanstate == ScanState_Scanning)
766 /* now we can start processing bayer data so long as we have at least
767 * 2 lines worth of data. this is the simplest demosaicing method that
768 * I could think of. I use each 2x2 bayer element without interpolation
769 * to generate 4 rgb pixels.
771 while ( frame->curline < cam->height &&
772 (RingQueue_GetLength(&uvd->dp) >= hor*2)) {
773 /* get 2 lines of bayer for demosaicing
774 * into 2 lines of RGB */
775 RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
776 bayL0 = (struct bayL0 *) cam->scratch;
777 bayL1 = (struct bayL1 *) (cam->scratch + hor);
778 /* frame->curline is the rgb y line */
779 rgbL0 = (struct rgb *)
780 ( frame->data + (cam->width*3*frame->curline));
781 /* w/2 because we're already doing 2 pixels */
782 rgbL1 = rgbL0 + (cam->width/2);
784 for (x=0; x < cam->width; x+=2) {
789 rgbL0->r2 = bayL0->r;
790 rgbL0->g2 = bayL1->g;
791 rgbL0->b2 = bayL1->b;
797 rgbL1->r2 = bayL0->r;
798 rgbL1->g2 = bayL1->g;
799 rgbL1->b2 = bayL1->b;
808 frame->seqRead_Length += cam->width*3*2;
811 /* See if we filled the frame */
812 if (frame->curline == cam->height) {
813 frame->frameState = FrameState_Done_Hold;
816 uvd->stats.frame_num++;
820 /* taken from konicawc */
821 static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
828 struct qcm *cam = (struct qcm *) uvd->user_data;
830 if (x > 0 && y > 0) {
831 DEBUG(2, "trying to find size %d,%d", x, y);
832 for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
833 if ((camera_sizes[newsize].width == x) &&
834 (camera_sizes[newsize].height == y))
840 if (newsize > MAX_FRAME_SIZE) {
841 DEBUG(1, "couldn't find size %d,%d", x, y);
845 if (newsize == cam->size) {
846 DEBUG(1, "Nothing to do");
852 if (cam->size != newsize) {
855 ret = qcm_set_camera_size(uvd);
857 err("Couldn't set camera size, err=%d",ret);
858 /* restore the original size */
864 /* Flush the input queue and clear any current frame in progress */
866 RingQueue_Flush(&uvd->dp);
867 if (uvd->curframe != -1) {
868 uvd->frame[uvd->curframe].curline = 0;
869 uvd->frame[uvd->curframe].seqRead_Length = 0;
870 uvd->frame[uvd->curframe].seqRead_Index = 0;
873 CHECK_RET(ret, qcm_start_data(uvd));
877 static int qcm_configure_video(struct uvd *uvd)
880 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
881 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
883 uvd->vpic.colour = colour;
885 uvd->vpic.brightness = brightness;
886 uvd->vpic.contrast = contrast;
887 uvd->vpic.whiteness = whiteness;
888 uvd->vpic.depth = 24;
889 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
891 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
892 strcpy(uvd->vcap.name, "QCM USB Camera");
893 uvd->vcap.type = VID_TYPE_CAPTURE;
894 uvd->vcap.channels = 1;
895 uvd->vcap.audios = 0;
897 uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
898 uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
899 uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
900 uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
902 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
903 uvd->vchan.flags = 0 ;
904 uvd->vchan.tuners = 0;
905 uvd->vchan.channel = 0;
906 uvd->vchan.type = VIDEO_TYPE_CAMERA;
907 strcpy(uvd->vchan.name, "Camera");
909 CHECK_RET(ret, qcm_sensor_init(uvd));
913 static int qcm_probe(struct usb_interface *intf,
914 const struct usb_device_id *devid)
918 struct usb_device *dev = interface_to_usbdev(intf);
921 unsigned char video_ep;
922 struct usb_host_interface *interface;
923 struct usb_endpoint_descriptor *endpoint;
925 unsigned int ifacenum, ifacenum_inact=0;
928 /* we don't support multiconfig cams */
929 if (dev->descriptor.bNumConfigurations != 1)
932 /* first check for the video interface and not
933 * the audio interface */
934 interface = &intf->cur_altsetting[0];
935 if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
936 || (interface->desc.bInterfaceSubClass !=
937 USB_CLASS_VENDOR_SPEC))
941 walk through each endpoint in each setting in the interface
942 stop when we find the one that's an isochronous IN endpoint.
944 for (i=0; i < intf->num_altsetting; i++) {
945 interface = &intf->cur_altsetting[i];
946 ifacenum = interface->desc.bAlternateSetting;
947 /* walk the end points */
948 for (j=0; j < interface->desc.bNumEndpoints; j++) {
949 endpoint = &interface->endpoint[j].desc;
951 if ((endpoint->bEndpointAddress &
952 USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
953 continue; /* not input then not good */
955 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
957 ifacenum_inact = ifacenum;
958 continue; /* 0 pkt size is not what we want */
961 if ((endpoint->bmAttributes &
962 USB_ENDPOINT_XFERTYPE_MASK) ==
963 USB_ENDPOINT_XFER_ISOC) {
964 video_ep = endpoint->bEndpointAddress;
965 /* break out of the search */
970 /* failed out since nothing useful was found */
971 err("No suitable endpoint was found\n");
975 /* disable isochronous stream before doing anything else */
976 err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
978 err("Failed to disable sensor stream");
983 Check that this is the same unknown sensor that is known to work. This
984 sensor is suspected to be the ST VV6422C001. I'll check the same value
985 that the qc-usb driver checks. This value is probably not even the
986 sensor ID since it matches the USB dev ID. Oh well. If it doesn't
987 match, it's probably a diff sensor so exit and apologize.
989 err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
991 err("Couldn't read sensor values. Err %d\n",err);
994 if (sensor_id != cpu_to_le16(0x08F0)) {
995 err("Sensor ID %x != %x. Unsupported. Sorry\n",
996 le16_to_cpu(sensor_id), (0x08F0));
1000 uvd = usbvideo_AllocateDevice(cams);
1004 cam = (struct qcm *) uvd->user_data;
1006 /* buf for doing demosaicing */
1007 cam->scratch = kmalloc(324*2, GFP_KERNEL);
1008 if (!cam->scratch) /* uvd freed in dereg */
1011 /* yes, if we fail after here, cam->scratch gets freed
1014 err = qcm_alloc_int_urb(cam);
1018 /* yes, if we fail after here, int urb gets freed
1021 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1022 cam->width = camera_sizes[size].width;
1023 cam->height = camera_sizes[size].height;
1029 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
1030 uvd->ifaceAltActive = ifacenum;
1031 uvd->ifaceAltInactive = ifacenum_inact;
1032 uvd->video_endp = video_ep;
1033 uvd->iso_packet_len = buffer_size;
1034 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
1035 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
1036 uvd->canvas = VIDEOSIZE(320, 240);
1037 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
1038 err = qcm_configure_video(uvd);
1040 err("failed to configure video settings");
1044 err = usbvideo_RegisterVideoDevice(uvd);
1045 if (err) { /* the uvd gets freed in Deregister */
1046 err("usbvideo_RegisterVideoDevice() failed.");
1050 uvd->max_frame_size = (320 * 240 * 3);
1051 qcm_register_input(cam, dev);
1052 usb_set_intfdata(intf, uvd);
1056 static void qcm_free_uvd(struct uvd *uvd)
1058 struct qcm *cam = (struct qcm *) uvd->user_data;
1060 kfree(cam->scratch);
1061 qcm_unregister_input(cam);
1065 static struct usbvideo_cb qcm_driver = {
1067 .setupOnOpen = qcm_setup_on_open,
1068 .processData = qcm_process_isoc,
1069 .setVideoMode = qcm_set_video_mode,
1070 .startDataPump = qcm_start_data,
1071 .stopDataPump = qcm_stop_data,
1072 .adjustPicture = qcm_adjust_picture,
1073 .userFree = qcm_free_uvd
1076 static int __init qcm_init(void)
1078 info(DRIVER_DESC " " DRIVER_VERSION);
1080 return usbvideo_register(
1090 static void __exit qcm_exit(void)
1092 usbvideo_Deregister(&cams);
1095 module_param(size, int, 0);
1096 MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
1097 module_param(colour, int, 0);
1098 MODULE_PARM_DESC(colour, "Initial colour");
1099 module_param(hue, int, 0);
1100 MODULE_PARM_DESC(hue, "Initial hue");
1101 module_param(brightness, int, 0);
1102 MODULE_PARM_DESC(brightness, "Initial brightness");
1103 module_param(contrast, int, 0);
1104 MODULE_PARM_DESC(contrast, "Initial contrast");
1105 module_param(whiteness, int, 0);
1106 MODULE_PARM_DESC(whiteness, "Initial whiteness");
1108 #ifdef CONFIG_USB_DEBUG
1109 module_param(debug, int, S_IRUGO | S_IWUSR);
1110 MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
1113 module_init(qcm_init);
1114 module_exit(qcm_exit);
1116 MODULE_LICENSE("GPL");
1117 MODULE_AUTHOR("Jaya Kumar");
1118 MODULE_DESCRIPTION("QCM USB Camera");
1119 MODULE_SUPPORTED_DEVICE("QCM USB Camera");