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
;
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();
96 warn("insufficient mem for cam input device");
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
);
110 warn("Failed to register camera's input device, err: %d\n",
112 input_free_device(cam
->input
);
117 static void qcm_unregister_input(struct qcm
*cam
)
120 input_unregister_device(cam
->input
);
125 static void qcm_report_buttonstat(struct qcm
*cam
)
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
)
136 struct uvd
*uvd
= urb
->context
;
139 if (!CAMERA_IS_OPERATIONAL(uvd
))
145 uvd
->stats
.urb_count
++;
148 uvd
->stats
.iso_err_count
++;
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
);
162 err("usb_submit_urb error (%d)", ret
);
165 static int qcm_setup_input_int(struct qcm
*cam
, struct uvd
*uvd
)
168 usb_fill_int_urb(cam
->button_urb
, uvd
->dev
,
169 usb_rcvintpipe(uvd
->dev
, uvd
->video_endp
+ 1),
170 &cam
->button_sts_buf
,
175 errflag
= usb_submit_urb(cam
->button_urb
, GFP_KERNEL
);
177 err ("usb_submit_int ret %d", 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
)
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
)
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
);
213 static int qcm_stv_setw(struct usb_device
*dev
, u16 reg
, u16 val
)
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
);
224 static int qcm_stv_getw(struct usb_device
*dev
, unsigned short reg
,
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
);
236 static int qcm_camera_on(struct uvd
*uvd
)
239 CHECK_RET(ret
, qcm_stv_setb(uvd
->dev
, STV_ISO_ENABLE
, 0x01));
243 static int qcm_camera_off(struct uvd
*uvd
)
246 CHECK_RET(ret
, qcm_stv_setb(uvd
->dev
, STV_ISO_ENABLE
, 0x00));
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
;
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,
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.
279 /* anything less than this is unsaturated */
285 if (val
<= (0xFFFF/8)) {
286 /* anything less than this is black */
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 */
303 valsat
= v
*s
>> 16; /* 0..65534 */
306 unsigned int t
= v
- (valsat
* (32769 - h
) >> 15);
325 unsigned int q
= v
- (valsat
* (32769 + h
) >> 15);
346 static int qcm_sensor_set_gains(struct uvd
*uvd
, u16 hue
,
347 u16 saturation
, u16 value
)
352 /* this code is based on qc-usb-messenger */
353 qcm_hsv2rgb(hue
, saturation
, value
, &r
, &g
, &b
);
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));
381 static int qcm_sensor_set_exposure(struct uvd
*uvd
, int exposure
)
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));
398 static int qcm_sensor_setlevels(struct uvd
*uvd
, int brightness
, int contrast
,
402 /* brightness is exposure, contrast is gain, colour is saturation */
404 qcm_sensor_set_exposure(uvd
, brightness
));
405 CHECK_RET(ret
, qcm_sensor_set_gains(uvd
, hue
, colour
, contrast
));
410 static int qcm_sensor_setsize(struct uvd
*uvd
, u8 size
)
414 CHECK_RET(ret
, qcm_stv_setb(uvd
->dev
, 0x1505, size
));
418 static int qcm_sensor_set_shutter(struct uvd
*uvd
, int whiteness
)
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));
434 static int qcm_sensor_init(struct uvd
*uvd
)
436 struct qcm
*cam
= (struct qcm
*) uvd
->user_data
;
440 for (i
=0; i
< ARRAY_SIZE(regval_table
) ; i
++) {
441 CHECK_RET(ret
, qcm_stv_setb(uvd
->dev
,
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
));
464 static int qcm_set_camera_size(struct uvd
*uvd
)
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
);
477 static int qcm_setup_on_open(struct uvd
*uvd
)
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
));
490 static void qcm_adjust_picture(struct uvd
*uvd
)
493 struct qcm
*cam
= (struct qcm
*) uvd
->user_data
;
495 ret
= qcm_camera_off(uvd
);
497 err("can't turn camera off. abandoning pic adjustment");
501 /* if there's been a change in contrast, hue, or
502 colour then we need to recalculate hsv in order
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
,
513 err("can't set gains. abandoning pic adjustment");
518 if (cam
->brightness
!= uvd
->vpic
.brightness
) {
519 cam
->brightness
= uvd
->vpic
.brightness
;
520 ret
= qcm_sensor_set_exposure(uvd
, cam
->brightness
);
522 err("can't set exposure. abandoning pic adjustment");
527 if (cam
->whiteness
!= uvd
->vpic
.whiteness
) {
528 cam
->whiteness
= uvd
->vpic
.whiteness
;
529 qcm_sensor_set_shutter(uvd
, cam
->whiteness
);
531 err("can't set shutter. abandoning pic adjustment");
536 ret
= qcm_camera_on(uvd
);
538 err("can't reenable camera. pic adjustment failed");
543 static int qcm_process_frame(struct uvd
*uvd
, u8
*cdata
, int framelen
)
551 struct framehdr
*fhdr
;
555 fhdr
= (struct framehdr
*) cdata
;
556 datalen
= be16_to_cpu(fhdr
->len
);
560 if ((fhdr
->id
) == cpu_to_be16(0x8001)) {
561 RingQueue_Enqueue(&uvd
->dp
, marker
, 4);
565 if ((fhdr
->id
& cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
566 RingQueue_Enqueue(&uvd
->dp
, cdata
, datalen
);
567 totaldata
+= datalen
;
575 static int qcm_compress_iso(struct uvd
*uvd
, struct urb
*dataurb
)
579 unsigned char *cdata
;
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
;
590 warn("Data error: packet=%d. len=%d. status=%d.",
592 uvd
->stats
.iso_err_count
++;
598 totlen
+= qcm_process_frame(uvd
, cdata
, n
);
603 static void resubmit_urb(struct uvd
*uvd
, struct urb
*urb
)
608 ret
= usb_submit_urb(urb
, GFP_ATOMIC
);
610 err("usb_submit_urb error (%d)", ret
);
613 static void qcm_isoc_irq(struct urb
*urb
)
616 struct uvd
*uvd
= urb
->context
;
618 if (!CAMERA_IS_OPERATIONAL(uvd
))
624 uvd
->stats
.urb_count
++;
626 if (!urb
->actual_length
) {
627 resubmit_urb(uvd
, urb
);
631 len
= qcm_compress_iso(uvd
, urb
);
632 resubmit_urb(uvd
, urb
);
633 uvd
->stats
.urb_length
= len
;
634 uvd
->stats
.data_count
+= len
;
636 RingQueue_WakeUpInterruptible(&uvd
->dp
);
639 static int qcm_start_data(struct uvd
*uvd
)
641 struct qcm
*cam
= (struct qcm
*) uvd
->user_data
;
647 pktsz
= uvd
->iso_packet_len
;
648 if (!CAMERA_IS_OPERATIONAL(uvd
)) {
649 err("Camera is not operational");
653 err
= usb_set_interface(uvd
->dev
, uvd
->iface
, uvd
->ifaceAltActive
);
655 err("usb_set_interface error");
656 uvd
->last_error
= err
;
660 for (i
=0; i
< USBVIDEO_NUMSBUF
; i
++) {
662 struct urb
*urb
= uvd
->sbuf
[i
].urb
;
665 urb
->pipe
= usb_rcvisocpipe(uvd
->dev
, uvd
->video_endp
);
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
;
680 for (i
=0; i
< USBVIDEO_NUMSBUF
; i
++) {
681 errflag
= usb_submit_urb(uvd
->sbuf
[i
].urb
, GFP_KERNEL
);
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
));
691 static void qcm_stop_data(struct uvd
*uvd
)
693 struct qcm
*cam
= (struct qcm
*) uvd
->user_data
;
697 if ((uvd
== NULL
) || (!uvd
->streaming
) || (uvd
->dev
== NULL
))
700 ret
= qcm_camera_off(uvd
);
702 warn("couldn't turn the cam off.");
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
);
717 err("usb_set_interface() error %d.", j
);
723 static void qcm_process_isoc(struct uvd
*uvd
, struct usbvideo_frame
*frame
)
725 struct qcm
*cam
= (struct qcm
*) uvd
->user_data
;
731 int hor
,ver
,hordel
,verdel
;
732 assert(frame
!= NULL
);
736 hor
= 162; ver
= 124; hordel
= 1; verdel
= 2;
740 hor
= 324; ver
= 248; hordel
= 2; verdel
= 4;
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)) {
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
));
764 RING_QUEUE_DEQUEUE_BYTES(&uvd
->dp
, 1);
768 if (frame
->scanstate
== ScanState_Scanning
)
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) {
794 rgbL0
->r2
= bayL0
->r
;
795 rgbL0
->g2
= bayL1
->g
;
796 rgbL0
->b2
= bayL1
->b
;
802 rgbL1
->r2
= bayL0
->r
;
803 rgbL1
->g2
= bayL1
->g
;
804 rgbL1
->b2
= bayL1
->b
;
813 frame
->seqRead_Length
+= cam
->width
*3*2;
816 /* See if we filled the frame */
817 if (frame
->curline
== cam
->height
) {
818 frame
->frameState
= FrameState_Done_Hold
;
821 uvd
->stats
.frame_num
++;
825 /* taken from konicawc */
826 static int qcm_set_video_mode(struct uvd
*uvd
, struct video_window
*vw
)
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
))
845 if (newsize
> MAX_FRAME_SIZE
) {
846 DEBUG(1, "couldn't find size %d,%d", x
, y
);
850 if (newsize
== cam
->size
) {
851 DEBUG(1, "Nothing to do");
857 if (cam
->size
!= newsize
) {
860 ret
= qcm_set_camera_size(uvd
);
862 err("Couldn't set camera size, err=%d",ret
);
863 /* restore the original size */
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
));
882 static int qcm_configure_video(struct uvd
*uvd
)
885 memset(&uvd
->vpic
, 0, sizeof(uvd
->vpic
));
886 memset(&uvd
->vpic_old
, 0x55, sizeof(uvd
->vpic_old
));
888 uvd
->vpic
.colour
= colour
;
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
));
918 static int qcm_probe(struct usb_interface
*intf
,
919 const struct usb_device_id
*devid
)
923 struct usb_device
*dev
= interface_to_usbdev(intf
);
926 unsigned char video_ep
;
927 struct usb_host_interface
*interface
;
928 struct usb_endpoint_descriptor
*endpoint
;
930 unsigned int ifacenum
, ifacenum_inact
=0;
933 /* we don't support multiconfig cams */
934 if (dev
->descriptor
.bNumConfigurations
!= 1)
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
))
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
);
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 */
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 info(DRIVER_DESC
" " DRIVER_VERSION
);
1085 return usbvideo_register(
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)");
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");