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>
37 #include <linux/slab.h>
40 #include "quickcam_messenger.h"
46 #ifdef CONFIG_USB_DEBUG
48 #define DEBUG(n, format, arg...) \
50 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
53 #define DEBUG(n, arg...)
54 static const int debug;
57 #define DRIVER_VERSION "v0.01"
58 #define DRIVER_DESC "Logitech Quickcam Messenger USB"
60 #define USB_LOGITECH_VENDOR_ID 0x046D
61 #define USB_QCM_PRODUCT_ID 0x08F0
65 #define MAX_COLOUR 32768
67 #define MAX_BRIGHTNESS 32768
68 #define MAX_CONTRAST 32768
69 #define MAX_WHITENESS 32768
71 static int size = SIZE_320X240;
72 static int colour = MAX_COLOUR;
73 static int hue = MAX_HUE;
74 static int brightness = MAX_BRIGHTNESS;
75 static int contrast = MAX_CONTRAST;
76 static int whiteness = MAX_WHITENESS;
78 static struct usbvideo *cams;
80 static struct usb_device_id qcm_table [] = {
81 { USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
84 MODULE_DEVICE_TABLE(usb, qcm_table);
87 static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
89 struct input_dev *input_dev;
92 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
93 strlcat(cam->input_physname, "/input0", sizeof(cam->input_physname));
95 cam->input = input_dev = input_allocate_device();
97 dev_warn(&dev->dev, "insufficient mem for cam input device\n");
101 input_dev->name = "QCM button";
102 input_dev->phys = cam->input_physname;
103 usb_to_input_id(dev, &input_dev->id);
104 input_dev->dev.parent = &dev->dev;
106 input_dev->evbit[0] = BIT_MASK(EV_KEY);
107 input_dev->keybit[BIT_WORD(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
109 error = input_register_device(cam->input);
112 "Failed to register camera's input device, err: %d\n",
114 input_free_device(cam->input);
119 static void qcm_unregister_input(struct qcm *cam)
122 input_unregister_device(cam->input);
127 static void qcm_report_buttonstat(struct qcm *cam)
130 input_report_key(cam->input, KEY_CAMERA, cam->button_sts);
131 input_sync(cam->input);
135 static void qcm_int_irq(struct urb *urb)
138 struct uvd *uvd = urb->context;
141 if (!CAMERA_IS_OPERATIONAL(uvd))
147 uvd->stats.urb_count++;
150 uvd->stats.iso_err_count++;
152 if (urb->actual_length > 0 ) {
153 cam = (struct qcm *) uvd->user_data;
154 if (cam->button_sts_buf == 0x88)
155 cam->button_sts = 0x0;
156 else if (cam->button_sts_buf == 0x80)
157 cam->button_sts = 0x1;
158 qcm_report_buttonstat(cam);
162 ret = usb_submit_urb(urb, GFP_ATOMIC);
164 err("usb_submit_urb error (%d)", ret);
167 static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
170 usb_fill_int_urb(cam->button_urb, uvd->dev,
171 usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
172 &cam->button_sts_buf,
177 errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
179 err ("usb_submit_int ret %d", errflag);
183 static void qcm_stop_int_data(struct qcm *cam)
185 usb_kill_urb(cam->button_urb);
188 static int qcm_alloc_int_urb(struct qcm *cam)
190 cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
192 if (!cam->button_urb)
198 static void qcm_free_int(struct qcm *cam)
200 usb_free_urb(cam->button_urb);
202 #endif /* CONFIG_INPUT */
204 static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
208 /* we'll wait up to 3 slices but no more */
209 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
210 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
211 reg, 0, &val, 1, 3*HZ);
215 static int qcm_stv_setw(struct usb_device *dev, u16 reg, __le16 val)
219 /* we'll wait up to 3 slices but no more */
220 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
221 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
222 reg, 0, &val, 2, 3*HZ);
226 static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
231 /* we'll wait up to 3 slices but no more */
232 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
233 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
234 reg, 0, val, 2, 3*HZ);
238 static int qcm_camera_on(struct uvd *uvd)
241 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
245 static int qcm_camera_off(struct uvd *uvd)
248 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
252 static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
254 unsigned int segment, valsat;
255 signed int h = (signed int) hue;
256 unsigned int s = (sat - 32768) * 2; /* rescale */
257 unsigned int v = val;
261 the registers controlling gain are 8 bit of which
262 we affect only the last 4 bits with our gain.
263 we know that if saturation is 0, (unsaturated) then
264 we're grayscale (center axis of the colour cone) so
265 we set rgb=value. we use a formula obtained from
266 wikipedia to map the cone to the RGB plane. it's
267 as follows for the human value case of h=0..360,
269 h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
270 q = v(1 - f*s) , t = v(1 - (1-f)s)
271 h_i==0 => r=v , g=t, b=p
272 h_i==1 => r=q , g=v, b=p
273 h_i==2 => r=p , g=v, b=t
274 h_i==3 => r=p , g=q, b=v
275 h_i==4 => r=t , g=p, b=v
276 h_i==5 => r=v , g=p, b=q
277 the bottom side (the point) and the stuff just up
278 of that is black so we simplify those two cases.
281 /* anything less than this is unsaturated */
287 if (val <= (0xFFFF/8)) {
288 /* anything less than this is black */
295 /* the rest of this code is copying tukkat's
296 implementation of the hsv2rgb conversion as taken
297 from qc-usb-messenger code. the 10923 is 0xFFFF/6
298 to divide the cone into 6 sectors. */
300 segment = (h + 10923) & 0xFFFF;
301 segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */
302 hue -= segment * 21845; /* -10923..10923 */
305 valsat = v*s >> 16; /* 0..65534 */
308 unsigned int t = v - (valsat * (32769 - h) >> 15);
327 unsigned int q = v - (valsat * (32769 + h) >> 15);
348 static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
349 u16 saturation, u16 value)
354 /* this code is based on qc-usb-messenger */
355 qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
370 /* set the r,g,b gain registers */
371 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
372 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
373 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
375 /* doing as qc-usb did */
376 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
377 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
378 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
383 static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
388 /* calculation was from qc-usb-messenger driver */
389 formedval = ( exposure >> 12 );
391 /* max value for formedval is 14 */
392 formedval = min(formedval, 14);
394 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
395 0x143A, 0xF0 | formedval));
396 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
400 static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
404 /* brightness is exposure, contrast is gain, colour is saturation */
406 qcm_sensor_set_exposure(uvd, brightness));
407 CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
412 static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
416 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
420 static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
423 /* some rescaling as done by the qc-usb-messenger code */
424 if (whiteness > 0xC000)
425 whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
427 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
428 (whiteness >> 8) & 0xFF));
429 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
430 (whiteness >> 16) & 0x03));
431 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
436 static int qcm_sensor_init(struct uvd *uvd)
438 struct qcm *cam = (struct qcm *) uvd->user_data;
442 for (i=0; i < ARRAY_SIZE(regval_table) ; i++) {
443 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
445 regval_table[i].val));
448 CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
449 cpu_to_le16(ISOC_PACKET_SIZE)));
450 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
451 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143f, 0x01));
453 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
455 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
457 CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
458 uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
460 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
461 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
466 static int qcm_set_camera_size(struct uvd *uvd)
469 struct qcm *cam = (struct qcm *) uvd->user_data;
471 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
472 cam->width = camera_sizes[cam->size].width;
473 cam->height = camera_sizes[cam->size].height;
474 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
479 static int qcm_setup_on_open(struct uvd *uvd)
483 CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
484 uvd->vpic.colour, uvd->vpic.contrast));
485 CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
486 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
487 CHECK_RET(ret, qcm_set_camera_size(uvd));
488 CHECK_RET(ret, qcm_camera_on(uvd));
492 static void qcm_adjust_picture(struct uvd *uvd)
495 struct qcm *cam = (struct qcm *) uvd->user_data;
497 ret = qcm_camera_off(uvd);
499 err("can't turn camera off. abandoning pic adjustment");
503 /* if there's been a change in contrast, hue, or
504 colour then we need to recalculate hsv in order
506 if ((cam->contrast != uvd->vpic.contrast) ||
507 (cam->hue != uvd->vpic.hue) ||
508 (cam->colour != uvd->vpic.colour)) {
509 cam->contrast = uvd->vpic.contrast;
510 cam->hue = uvd->vpic.hue;
511 cam->colour = uvd->vpic.colour;
512 ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
515 err("can't set gains. abandoning pic adjustment");
520 if (cam->brightness != uvd->vpic.brightness) {
521 cam->brightness = uvd->vpic.brightness;
522 ret = qcm_sensor_set_exposure(uvd, cam->brightness);
524 err("can't set exposure. abandoning pic adjustment");
529 if (cam->whiteness != uvd->vpic.whiteness) {
530 cam->whiteness = uvd->vpic.whiteness;
531 qcm_sensor_set_shutter(uvd, cam->whiteness);
533 err("can't set shutter. abandoning pic adjustment");
538 ret = qcm_camera_on(uvd);
540 err("can't reenable camera. pic adjustment failed");
545 static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
553 struct framehdr *fhdr;
557 fhdr = (struct framehdr *) cdata;
558 datalen = be16_to_cpu(fhdr->len);
562 if ((fhdr->id) == cpu_to_be16(0x8001)) {
563 RingQueue_Enqueue(&uvd->dp, marker, 4);
567 if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
568 RingQueue_Enqueue(&uvd->dp, cdata, datalen);
569 totaldata += datalen;
577 static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
581 unsigned char *cdata;
584 for (i = 0; i < dataurb->number_of_packets; i++) {
585 int n = dataurb->iso_frame_desc[i].actual_length;
586 int st = dataurb->iso_frame_desc[i].status;
588 cdata = dataurb->transfer_buffer +
589 dataurb->iso_frame_desc[i].offset;
592 dev_warn(&uvd->dev->dev,
593 "Data error: packet=%d. len=%d. status=%d.\n",
595 uvd->stats.iso_err_count++;
601 totlen += qcm_process_frame(uvd, cdata, n);
606 static void resubmit_urb(struct uvd *uvd, struct urb *urb)
611 ret = usb_submit_urb(urb, GFP_ATOMIC);
613 err("usb_submit_urb error (%d)", ret);
616 static void qcm_isoc_irq(struct urb *urb)
619 struct uvd *uvd = urb->context;
621 if (!CAMERA_IS_OPERATIONAL(uvd))
627 uvd->stats.urb_count++;
629 if (!urb->actual_length) {
630 resubmit_urb(uvd, urb);
634 len = qcm_compress_iso(uvd, urb);
635 resubmit_urb(uvd, urb);
636 uvd->stats.urb_length = len;
637 uvd->stats.data_count += len;
639 RingQueue_WakeUpInterruptible(&uvd->dp);
642 static int qcm_start_data(struct uvd *uvd)
644 struct qcm *cam = (struct qcm *) uvd->user_data;
650 pktsz = uvd->iso_packet_len;
651 if (!CAMERA_IS_OPERATIONAL(uvd)) {
652 err("Camera is not operational");
656 err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
658 err("usb_set_interface error");
659 uvd->last_error = err;
663 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
665 struct urb *urb = uvd->sbuf[i].urb;
668 urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
670 urb->transfer_flags = URB_ISO_ASAP;
671 urb->transfer_buffer = uvd->sbuf[i].data;
672 urb->complete = qcm_isoc_irq;
673 urb->number_of_packets = FRAMES_PER_DESC;
674 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
675 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
676 urb->iso_frame_desc[j].offset = k;
677 urb->iso_frame_desc[j].length = pktsz;
683 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
684 errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
686 err ("usb_submit_isoc(%d) ret %d", i, errflag);
689 CHECK_RET(err, qcm_setup_input_int(cam, uvd));
690 CHECK_RET(err, qcm_camera_on(uvd));
694 static void qcm_stop_data(struct uvd *uvd)
696 struct qcm *cam = (struct qcm *) uvd->user_data;
700 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
703 ret = qcm_camera_off(uvd);
705 dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n");
709 /* Unschedule all of the iso td's */
710 for (i=0; i < USBVIDEO_NUMSBUF; i++)
711 usb_kill_urb(uvd->sbuf[i].urb);
713 qcm_stop_int_data(cam);
715 if (!uvd->remove_pending) {
716 /* Set packet size to 0 */
717 j = usb_set_interface(uvd->dev, uvd->iface,
718 uvd->ifaceAltInactive);
720 err("usb_set_interface() error %d.", j);
726 static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
728 struct qcm *cam = (struct qcm *) uvd->user_data;
734 int hor,ver,hordel,verdel;
735 assert(frame != NULL);
739 hor = 162; ver = 124; hordel = 1; verdel = 2;
743 hor = 324; ver = 248; hordel = 2; verdel = 4;
747 if (frame->scanstate == ScanState_Scanning) {
748 while (RingQueue_GetLength(&uvd->dp) >=
749 4 + (hor*verdel + hordel)) {
750 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
751 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
752 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
753 (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
755 frame->scanstate = ScanState_Lines;
756 frame->frameState = FrameState_Grabbing;
757 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
759 * if we're starting, we need to discard the first
760 * 4 lines of y bayer data
761 * and the first 2 gr elements of x bayer data
763 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
764 (hor*verdel + hordel));
767 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
771 if (frame->scanstate == ScanState_Scanning)
774 /* now we can start processing bayer data so long as we have at least
775 * 2 lines worth of data. this is the simplest demosaicing method that
776 * I could think of. I use each 2x2 bayer element without interpolation
777 * to generate 4 rgb pixels.
779 while ( frame->curline < cam->height &&
780 (RingQueue_GetLength(&uvd->dp) >= hor*2)) {
781 /* get 2 lines of bayer for demosaicing
782 * into 2 lines of RGB */
783 RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
784 bayL0 = (struct bayL0 *) cam->scratch;
785 bayL1 = (struct bayL1 *) (cam->scratch + hor);
786 /* frame->curline is the rgb y line */
787 rgbL0 = (struct rgb *)
788 ( frame->data + (cam->width*3*frame->curline));
789 /* w/2 because we're already doing 2 pixels */
790 rgbL1 = rgbL0 + (cam->width/2);
792 for (x=0; x < cam->width; x+=2) {
797 rgbL0->r2 = bayL0->r;
798 rgbL0->g2 = bayL1->g;
799 rgbL0->b2 = bayL1->b;
805 rgbL1->r2 = bayL0->r;
806 rgbL1->g2 = bayL1->g;
807 rgbL1->b2 = bayL1->b;
816 frame->seqRead_Length += cam->width*3*2;
819 /* See if we filled the frame */
820 if (frame->curline == cam->height) {
821 frame->frameState = FrameState_Done_Hold;
824 uvd->stats.frame_num++;
828 /* taken from konicawc */
829 static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
836 struct qcm *cam = (struct qcm *) uvd->user_data;
838 if (x > 0 && y > 0) {
839 DEBUG(2, "trying to find size %d,%d", x, y);
840 for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
841 if ((camera_sizes[newsize].width == x) &&
842 (camera_sizes[newsize].height == y))
848 if (newsize > MAX_FRAME_SIZE) {
849 DEBUG(1, "couldn't find size %d,%d", x, y);
853 if (newsize == cam->size) {
854 DEBUG(1, "Nothing to do");
860 if (cam->size != newsize) {
863 ret = qcm_set_camera_size(uvd);
865 err("Couldn't set camera size, err=%d",ret);
866 /* restore the original size */
872 /* Flush the input queue and clear any current frame in progress */
874 RingQueue_Flush(&uvd->dp);
875 if (uvd->curframe != -1) {
876 uvd->frame[uvd->curframe].curline = 0;
877 uvd->frame[uvd->curframe].seqRead_Length = 0;
878 uvd->frame[uvd->curframe].seqRead_Index = 0;
881 CHECK_RET(ret, qcm_start_data(uvd));
885 static int qcm_configure_video(struct uvd *uvd)
888 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
889 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
891 uvd->vpic.colour = colour;
893 uvd->vpic.brightness = brightness;
894 uvd->vpic.contrast = contrast;
895 uvd->vpic.whiteness = whiteness;
896 uvd->vpic.depth = 24;
897 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
899 memset(&uvd->vcap, 0, sizeof(uvd->vcap));
900 strcpy(uvd->vcap.name, "QCM USB Camera");
901 uvd->vcap.type = VID_TYPE_CAPTURE;
902 uvd->vcap.channels = 1;
903 uvd->vcap.audios = 0;
905 uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
906 uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
907 uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
908 uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
910 memset(&uvd->vchan, 0, sizeof(uvd->vchan));
911 uvd->vchan.flags = 0 ;
912 uvd->vchan.tuners = 0;
913 uvd->vchan.channel = 0;
914 uvd->vchan.type = VIDEO_TYPE_CAMERA;
915 strcpy(uvd->vchan.name, "Camera");
917 CHECK_RET(ret, qcm_sensor_init(uvd));
921 static int qcm_probe(struct usb_interface *intf,
922 const struct usb_device_id *devid)
926 struct usb_device *dev = interface_to_usbdev(intf);
929 unsigned char video_ep;
930 struct usb_host_interface *interface;
931 struct usb_endpoint_descriptor *endpoint;
933 unsigned int ifacenum, ifacenum_inact=0;
936 /* we don't support multiconfig cams */
937 if (dev->descriptor.bNumConfigurations != 1)
940 /* first check for the video interface and not
941 * the audio interface */
942 interface = &intf->cur_altsetting[0];
943 if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
944 || (interface->desc.bInterfaceSubClass !=
945 USB_CLASS_VENDOR_SPEC))
949 walk through each endpoint in each setting in the interface
950 stop when we find the one that's an isochronous IN endpoint.
952 for (i=0; i < intf->num_altsetting; i++) {
953 interface = &intf->cur_altsetting[i];
954 ifacenum = interface->desc.bAlternateSetting;
955 /* walk the end points */
956 for (j=0; j < interface->desc.bNumEndpoints; j++) {
957 endpoint = &interface->endpoint[j].desc;
959 if (usb_endpoint_dir_out(endpoint))
960 continue; /* not input then not good */
962 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
964 ifacenum_inact = ifacenum;
965 continue; /* 0 pkt size is not what we want */
968 if (usb_endpoint_xfer_isoc(endpoint)) {
969 video_ep = endpoint->bEndpointAddress;
970 /* break out of the search */
975 /* failed out since nothing useful was found */
976 err("No suitable endpoint was found\n");
980 /* disable isochronous stream before doing anything else */
981 err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
983 err("Failed to disable sensor stream");
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);
996 err("Couldn't read sensor values. Err %d\n",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));
1005 uvd = usbvideo_AllocateDevice(cams);
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 */
1016 /* yes, if we fail after here, cam->scratch gets freed
1019 err = qcm_alloc_int_urb(cam);
1023 /* yes, if we fail after here, int urb gets freed
1026 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1027 cam->width = camera_sizes[size].width;
1028 cam->height = camera_sizes[size].height;
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);
1045 err("failed to configure video settings");
1049 err = usbvideo_RegisterVideoDevice(uvd);
1050 if (err) { /* the uvd gets freed in Deregister */
1051 err("usbvideo_RegisterVideoDevice() failed.");
1055 uvd->max_frame_size = (320 * 240 * 3);
1056 qcm_register_input(cam, dev);
1057 usb_set_intfdata(intf, uvd);
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);
1070 static struct usbvideo_cb qcm_driver = {
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 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
1086 return usbvideo_register(
1096 static void __exit qcm_exit(void)
1098 usbvideo_Deregister(&cams);
1101 module_param(size, int, 0);
1102 MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
1103 module_param(colour, int, 0);
1104 MODULE_PARM_DESC(colour, "Initial colour");
1105 module_param(hue, int, 0);
1106 MODULE_PARM_DESC(hue, "Initial hue");
1107 module_param(brightness, int, 0);
1108 MODULE_PARM_DESC(brightness, "Initial brightness");
1109 module_param(contrast, int, 0);
1110 MODULE_PARM_DESC(contrast, "Initial contrast");
1111 module_param(whiteness, int, 0);
1112 MODULE_PARM_DESC(whiteness, "Initial whiteness");
1114 #ifdef CONFIG_USB_DEBUG
1115 module_param(debug, int, S_IRUGO | S_IWUSR);
1116 MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
1119 module_init(qcm_init);
1120 module_exit(qcm_exit);
1122 MODULE_LICENSE("GPL");
1123 MODULE_AUTHOR("Jaya Kumar");
1124 MODULE_DESCRIPTION("QCM USB Camera");
1125 MODULE_SUPPORTED_DEVICE("QCM USB Camera");