]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/media/video/usbvideo/quickcam_messenger.c
V4L/DVB (9116): USB: remove info() macro from usb media drivers
[mirror_ubuntu-bionic-kernel.git] / drivers / media / video / usbvideo / quickcam_messenger.c
1 /*
2 * Driver for Logitech Quickcam Messenger usb video camera
3 * Copyright (C) Jaya Kumar
4 *
5 * This work was sponsored by CIS(M) Sdn Bhd.
6 * History:
7 * 05/08/2006 - Jaya Kumar
8 * I wrote this based on the konicawc by Simon Evans.
9 * -
10 * Full credit for reverse engineering and creating an initial
11 * working linux driver for the VV6422 goes to the qce-ga project by
12 * Tuukka Toivonen, Jochen Hoenicke, Peter McConnell,
13 * Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as
14 * others.
15 * ---
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
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.
25 *
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
29 *
30 */
31
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
38 #include "usbvideo.h"
39 #include "quickcam_messenger.h"
40
41 /*
42 * Version Information
43 */
44
45 #ifdef CONFIG_USB_DEBUG
46 static int debug;
47 #define DEBUG(n, format, arg...) \
48 if (n <= debug) { \
49 printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __func__ , ## arg); \
50 }
51 #else
52 #define DEBUG(n, arg...)
53 static const int debug;
54 #endif
55
56 #define DRIVER_VERSION "v0.01"
57 #define DRIVER_DESC "Logitech Quickcam Messenger USB"
58
59 #define USB_LOGITECH_VENDOR_ID 0x046D
60 #define USB_QCM_PRODUCT_ID 0x08F0
61
62 #define MAX_CAMERAS 1
63
64 #define MAX_COLOUR 32768
65 #define MAX_HUE 32768
66 #define MAX_BRIGHTNESS 32768
67 #define MAX_CONTRAST 32768
68 #define MAX_WHITENESS 32768
69
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;
76
77 static struct usbvideo *cams;
78
79 static struct usb_device_id qcm_table [] = {
80 { USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
81 { }
82 };
83 MODULE_DEVICE_TABLE(usb, qcm_table);
84
85 #ifdef CONFIG_INPUT
86 static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
87 {
88 struct input_dev *input_dev;
89 int error;
90
91 usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
92 strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
93
94 cam->input = input_dev = input_allocate_device();
95 if (!input_dev) {
96 warn("insufficient mem for cam input device");
97 return;
98 }
99
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;
104
105 input_dev->evbit[0] = BIT_MASK(EV_KEY);
106 input_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
107
108 error = input_register_device(cam->input);
109 if (error) {
110 warn("Failed to register camera's input device, err: %d\n",
111 error);
112 input_free_device(cam->input);
113 cam->input = NULL;
114 }
115 }
116
117 static void qcm_unregister_input(struct qcm *cam)
118 {
119 if (cam->input) {
120 input_unregister_device(cam->input);
121 cam->input = NULL;
122 }
123 }
124
125 static void qcm_report_buttonstat(struct qcm *cam)
126 {
127 if (cam->input) {
128 input_report_key(cam->input, BTN_0, cam->button_sts);
129 input_sync(cam->input);
130 }
131 }
132
133 static void qcm_int_irq(struct urb *urb)
134 {
135 int ret;
136 struct uvd *uvd = urb->context;
137 struct qcm *cam;
138
139 if (!CAMERA_IS_OPERATIONAL(uvd))
140 return;
141
142 if (!uvd->streaming)
143 return;
144
145 uvd->stats.urb_count++;
146
147 if (urb->status < 0)
148 uvd->stats.iso_err_count++;
149 else {
150 if (urb->actual_length > 0 ) {
151 cam = (struct qcm *) uvd->user_data;
152 if (cam->button_sts_buf == 0x88)
153 cam->button_sts = 0x0;
154 else if (cam->button_sts_buf == 0x80)
155 cam->button_sts = 0x1;
156 qcm_report_buttonstat(cam);
157 }
158 }
159
160 ret = usb_submit_urb(urb, GFP_ATOMIC);
161 if (ret < 0)
162 err("usb_submit_urb error (%d)", ret);
163 }
164
165 static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
166 {
167 int errflag;
168 usb_fill_int_urb(cam->button_urb, uvd->dev,
169 usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
170 &cam->button_sts_buf,
171 1,
172 qcm_int_irq,
173 uvd, 16);
174
175 errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
176 if (errflag)
177 err ("usb_submit_int ret %d", errflag);
178 return errflag;
179 }
180
181 static void qcm_stop_int_data(struct qcm *cam)
182 {
183 usb_kill_urb(cam->button_urb);
184 }
185
186 static int qcm_alloc_int_urb(struct qcm *cam)
187 {
188 cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
189
190 if (!cam->button_urb)
191 return -ENOMEM;
192
193 return 0;
194 }
195
196 static void qcm_free_int(struct qcm *cam)
197 {
198 usb_free_urb(cam->button_urb);
199 }
200 #endif /* CONFIG_INPUT */
201
202 static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
203 {
204 int ret;
205
206 /* we'll wait up to 3 slices but no more */
207 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
208 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
209 reg, 0, &val, 1, 3*HZ);
210 return ret;
211 }
212
213 static int qcm_stv_setw(struct usb_device *dev, u16 reg, __le16 val)
214 {
215 int ret;
216
217 /* we'll wait up to 3 slices but no more */
218 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
219 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
220 reg, 0, &val, 2, 3*HZ);
221 return ret;
222 }
223
224 static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
225 __le16 *val)
226 {
227 int ret;
228
229 /* we'll wait up to 3 slices but no more */
230 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
231 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
232 reg, 0, val, 2, 3*HZ);
233 return ret;
234 }
235
236 static int qcm_camera_on(struct uvd *uvd)
237 {
238 int ret;
239 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
240 return 0;
241 }
242
243 static int qcm_camera_off(struct uvd *uvd)
244 {
245 int ret;
246 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
247 return 0;
248 }
249
250 static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
251 {
252 unsigned int segment, valsat;
253 signed int h = (signed int) hue;
254 unsigned int s = (sat - 32768) * 2; /* rescale */
255 unsigned int v = val;
256 unsigned int p;
257
258 /*
259 the registers controlling gain are 8 bit of which
260 we affect only the last 4 bits with our gain.
261 we know that if saturation is 0, (unsaturated) then
262 we're grayscale (center axis of the colour cone) so
263 we set rgb=value. we use a formula obtained from
264 wikipedia to map the cone to the RGB plane. it's
265 as follows for the human value case of h=0..360,
266 s=0..1, v=0..1
267 h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
268 q = v(1 - f*s) , t = v(1 - (1-f)s)
269 h_i==0 => r=v , g=t, b=p
270 h_i==1 => r=q , g=v, b=p
271 h_i==2 => r=p , g=v, b=t
272 h_i==3 => r=p , g=q, b=v
273 h_i==4 => r=t , g=p, b=v
274 h_i==5 => r=v , g=p, b=q
275 the bottom side (the point) and the stuff just up
276 of that is black so we simplify those two cases.
277 */
278 if (sat < 32768) {
279 /* anything less than this is unsaturated */
280 *r = val;
281 *g = val;
282 *b = val;
283 return;
284 }
285 if (val <= (0xFFFF/8)) {
286 /* anything less than this is black */
287 *r = 0;
288 *g = 0;
289 *b = 0;
290 return;
291 }
292
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. */
297
298 segment = (h + 10923) & 0xFFFF;
299 segment = segment*3 >> 16; /* 0..2: 0=R, 1=G, 2=B */
300 hue -= segment * 21845; /* -10923..10923 */
301 h = hue;
302 h *= 3;
303 valsat = v*s >> 16; /* 0..65534 */
304 p = v - valsat;
305 if (h >= 0) {
306 unsigned int t = v - (valsat * (32769 - h) >> 15);
307 switch (segment) {
308 case 0: /* R-> */
309 *r = v;
310 *g = t;
311 *b = p;
312 break;
313 case 1: /* G-> */
314 *r = p;
315 *g = v;
316 *b = t;
317 break;
318 case 2: /* B-> */
319 *r = t;
320 *g = p;
321 *b = v;
322 break;
323 }
324 } else {
325 unsigned int q = v - (valsat * (32769 + h) >> 15);
326 switch (segment) {
327 case 0: /* ->R */
328 *r = v;
329 *g = p;
330 *b = q;
331 break;
332 case 1: /* ->G */
333 *r = q;
334 *g = v;
335 *b = p;
336 break;
337 case 2: /* ->B */
338 *r = p;
339 *g = q;
340 *b = v;
341 break;
342 }
343 }
344 }
345
346 static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
347 u16 saturation, u16 value)
348 {
349 int ret;
350 u16 r=0,g=0,b=0;
351
352 /* this code is based on qc-usb-messenger */
353 qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
354
355 r >>= 12;
356 g >>= 12;
357 b >>= 12;
358
359 /* min val is 8 */
360 r = max((u16) 8, r);
361 g = max((u16) 8, g);
362 b = max((u16) 8, b);
363
364 r |= 0x30;
365 g |= 0x30;
366 b |= 0x30;
367
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));
372
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));
377
378 return 0;
379 }
380
381 static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
382 {
383 int ret;
384 int formedval;
385
386 /* calculation was from qc-usb-messenger driver */
387 formedval = ( exposure >> 12 );
388
389 /* max value for formedval is 14 */
390 formedval = min(formedval, 14);
391
392 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
393 0x143A, 0xF0 | formedval));
394 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
395 return 0;
396 }
397
398 static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
399 int hue, int colour)
400 {
401 int ret;
402 /* brightness is exposure, contrast is gain, colour is saturation */
403 CHECK_RET(ret,
404 qcm_sensor_set_exposure(uvd, brightness));
405 CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
406
407 return 0;
408 }
409
410 static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
411 {
412 int ret;
413
414 CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
415 return 0;
416 }
417
418 static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
419 {
420 int ret;
421 /* some rescaling as done by the qc-usb-messenger code */
422 if (whiteness > 0xC000)
423 whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
424
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));
430
431 return 0;
432 }
433
434 static int qcm_sensor_init(struct uvd *uvd)
435 {
436 struct qcm *cam = (struct qcm *) uvd->user_data;
437 int ret;
438 int i;
439
440 for (i=0; i < ARRAY_SIZE(regval_table) ; i++) {
441 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
442 regval_table[i].reg,
443 regval_table[i].val));
444 }
445
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));
450
451 CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
452
453 CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
454
455 CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
456 uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
457
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));
460
461 return 0;
462 }
463
464 static int qcm_set_camera_size(struct uvd *uvd)
465 {
466 int ret;
467 struct qcm *cam = (struct qcm *) uvd->user_data;
468
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);
473
474 return 0;
475 }
476
477 static int qcm_setup_on_open(struct uvd *uvd)
478 {
479 int ret;
480
481 CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
482 uvd->vpic.colour, uvd->vpic.contrast));
483 CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
484 CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
485 CHECK_RET(ret, qcm_set_camera_size(uvd));
486 CHECK_RET(ret, qcm_camera_on(uvd));
487 return 0;
488 }
489
490 static void qcm_adjust_picture(struct uvd *uvd)
491 {
492 int ret;
493 struct qcm *cam = (struct qcm *) uvd->user_data;
494
495 ret = qcm_camera_off(uvd);
496 if (ret) {
497 err("can't turn camera off. abandoning pic adjustment");
498 return;
499 }
500
501 /* if there's been a change in contrast, hue, or
502 colour then we need to recalculate hsv in order
503 to update gains */
504 if ((cam->contrast != uvd->vpic.contrast) ||
505 (cam->hue != uvd->vpic.hue) ||
506 (cam->colour != uvd->vpic.colour)) {
507 cam->contrast = uvd->vpic.contrast;
508 cam->hue = uvd->vpic.hue;
509 cam->colour = uvd->vpic.colour;
510 ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
511 cam->contrast);
512 if (ret) {
513 err("can't set gains. abandoning pic adjustment");
514 return;
515 }
516 }
517
518 if (cam->brightness != uvd->vpic.brightness) {
519 cam->brightness = uvd->vpic.brightness;
520 ret = qcm_sensor_set_exposure(uvd, cam->brightness);
521 if (ret) {
522 err("can't set exposure. abandoning pic adjustment");
523 return;
524 }
525 }
526
527 if (cam->whiteness != uvd->vpic.whiteness) {
528 cam->whiteness = uvd->vpic.whiteness;
529 qcm_sensor_set_shutter(uvd, cam->whiteness);
530 if (ret) {
531 err("can't set shutter. abandoning pic adjustment");
532 return;
533 }
534 }
535
536 ret = qcm_camera_on(uvd);
537 if (ret) {
538 err("can't reenable camera. pic adjustment failed");
539 return;
540 }
541 }
542
543 static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
544 {
545 int datalen;
546 int totaldata;
547 struct framehdr {
548 __be16 id;
549 __be16 len;
550 };
551 struct framehdr *fhdr;
552
553 totaldata = 0;
554 while (framelen) {
555 fhdr = (struct framehdr *) cdata;
556 datalen = be16_to_cpu(fhdr->len);
557 framelen -= 4;
558 cdata += 4;
559
560 if ((fhdr->id) == cpu_to_be16(0x8001)) {
561 RingQueue_Enqueue(&uvd->dp, marker, 4);
562 totaldata += 4;
563 continue;
564 }
565 if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
566 RingQueue_Enqueue(&uvd->dp, cdata, datalen);
567 totaldata += datalen;
568 }
569 framelen -= datalen;
570 cdata += datalen;
571 }
572 return totaldata;
573 }
574
575 static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
576 {
577 int totlen;
578 int i;
579 unsigned char *cdata;
580
581 totlen=0;
582 for (i = 0; i < dataurb->number_of_packets; i++) {
583 int n = dataurb->iso_frame_desc[i].actual_length;
584 int st = dataurb->iso_frame_desc[i].status;
585
586 cdata = dataurb->transfer_buffer +
587 dataurb->iso_frame_desc[i].offset;
588
589 if (st < 0) {
590 warn("Data error: packet=%d. len=%d. status=%d.",
591 i, n, st);
592 uvd->stats.iso_err_count++;
593 continue;
594 }
595 if (!n)
596 continue;
597
598 totlen += qcm_process_frame(uvd, cdata, n);
599 }
600 return totlen;
601 }
602
603 static void resubmit_urb(struct uvd *uvd, struct urb *urb)
604 {
605 int ret;
606
607 urb->dev = uvd->dev;
608 ret = usb_submit_urb(urb, GFP_ATOMIC);
609 if (ret)
610 err("usb_submit_urb error (%d)", ret);
611 }
612
613 static void qcm_isoc_irq(struct urb *urb)
614 {
615 int len;
616 struct uvd *uvd = urb->context;
617
618 if (!CAMERA_IS_OPERATIONAL(uvd))
619 return;
620
621 if (!uvd->streaming)
622 return;
623
624 uvd->stats.urb_count++;
625
626 if (!urb->actual_length) {
627 resubmit_urb(uvd, urb);
628 return;
629 }
630
631 len = qcm_compress_iso(uvd, urb);
632 resubmit_urb(uvd, urb);
633 uvd->stats.urb_length = len;
634 uvd->stats.data_count += len;
635 if (len)
636 RingQueue_WakeUpInterruptible(&uvd->dp);
637 }
638
639 static int qcm_start_data(struct uvd *uvd)
640 {
641 struct qcm *cam = (struct qcm *) uvd->user_data;
642 int i;
643 int errflag;
644 int pktsz;
645 int err;
646
647 pktsz = uvd->iso_packet_len;
648 if (!CAMERA_IS_OPERATIONAL(uvd)) {
649 err("Camera is not operational");
650 return -EFAULT;
651 }
652
653 err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
654 if (err < 0) {
655 err("usb_set_interface error");
656 uvd->last_error = err;
657 return -EBUSY;
658 }
659
660 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
661 int j, k;
662 struct urb *urb = uvd->sbuf[i].urb;
663 urb->dev = uvd->dev;
664 urb->context = uvd;
665 urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
666 urb->interval = 1;
667 urb->transfer_flags = URB_ISO_ASAP;
668 urb->transfer_buffer = uvd->sbuf[i].data;
669 urb->complete = qcm_isoc_irq;
670 urb->number_of_packets = FRAMES_PER_DESC;
671 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
672 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
673 urb->iso_frame_desc[j].offset = k;
674 urb->iso_frame_desc[j].length = pktsz;
675 }
676 }
677
678 uvd->streaming = 1;
679 uvd->curframe = -1;
680 for (i=0; i < USBVIDEO_NUMSBUF; i++) {
681 errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
682 if (errflag)
683 err ("usb_submit_isoc(%d) ret %d", i, errflag);
684 }
685
686 CHECK_RET(err, qcm_setup_input_int(cam, uvd));
687 CHECK_RET(err, qcm_camera_on(uvd));
688 return 0;
689 }
690
691 static void qcm_stop_data(struct uvd *uvd)
692 {
693 struct qcm *cam = (struct qcm *) uvd->user_data;
694 int i, j;
695 int ret;
696
697 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
698 return;
699
700 ret = qcm_camera_off(uvd);
701 if (ret)
702 warn("couldn't turn the cam off.");
703
704 uvd->streaming = 0;
705
706 /* Unschedule all of the iso td's */
707 for (i=0; i < USBVIDEO_NUMSBUF; i++)
708 usb_kill_urb(uvd->sbuf[i].urb);
709
710 qcm_stop_int_data(cam);
711
712 if (!uvd->remove_pending) {
713 /* Set packet size to 0 */
714 j = usb_set_interface(uvd->dev, uvd->iface,
715 uvd->ifaceAltInactive);
716 if (j < 0) {
717 err("usb_set_interface() error %d.", j);
718 uvd->last_error = j;
719 }
720 }
721 }
722
723 static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
724 {
725 struct qcm *cam = (struct qcm *) uvd->user_data;
726 int x;
727 struct rgb *rgbL0;
728 struct rgb *rgbL1;
729 struct bayL0 *bayL0;
730 struct bayL1 *bayL1;
731 int hor,ver,hordel,verdel;
732 assert(frame != NULL);
733
734 switch (cam->size) {
735 case SIZE_160X120:
736 hor = 162; ver = 124; hordel = 1; verdel = 2;
737 break;
738 case SIZE_320X240:
739 default:
740 hor = 324; ver = 248; hordel = 2; verdel = 4;
741 break;
742 }
743
744 if (frame->scanstate == ScanState_Scanning) {
745 while (RingQueue_GetLength(&uvd->dp) >=
746 4 + (hor*verdel + hordel)) {
747 if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
748 (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
749 (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
750 (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
751 frame->curline = 0;
752 frame->scanstate = ScanState_Lines;
753 frame->frameState = FrameState_Grabbing;
754 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
755 /*
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
759 */
760 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
761 (hor*verdel + hordel));
762 break;
763 }
764 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
765 }
766 }
767
768 if (frame->scanstate == ScanState_Scanning)
769 return;
770
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.
775 */
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);
788
789 for (x=0; x < cam->width; x+=2) {
790 rgbL0->r = bayL0->r;
791 rgbL0->g = bayL0->g;
792 rgbL0->b = bayL1->b;
793
794 rgbL0->r2 = bayL0->r;
795 rgbL0->g2 = bayL1->g;
796 rgbL0->b2 = bayL1->b;
797
798 rgbL1->r = bayL0->r;
799 rgbL1->g = bayL1->g;
800 rgbL1->b = bayL1->b;
801
802 rgbL1->r2 = bayL0->r;
803 rgbL1->g2 = bayL1->g;
804 rgbL1->b2 = bayL1->b;
805
806 rgbL0++;
807 rgbL1++;
808
809 bayL0++;
810 bayL1++;
811 }
812
813 frame->seqRead_Length += cam->width*3*2;
814 frame->curline += 2;
815 }
816 /* See if we filled the frame */
817 if (frame->curline == cam->height) {
818 frame->frameState = FrameState_Done_Hold;
819 frame->curline = 0;
820 uvd->curframe = -1;
821 uvd->stats.frame_num++;
822 }
823 }
824
825 /* taken from konicawc */
826 static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
827 {
828 int ret;
829 int newsize;
830 int oldsize;
831 int x = vw->width;
832 int y = vw->height;
833 struct qcm *cam = (struct qcm *) uvd->user_data;
834
835 if (x > 0 && y > 0) {
836 DEBUG(2, "trying to find size %d,%d", x, y);
837 for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
838 if ((camera_sizes[newsize].width == x) &&
839 (camera_sizes[newsize].height == y))
840 break;
841 }
842 } else
843 newsize = cam->size;
844
845 if (newsize > MAX_FRAME_SIZE) {
846 DEBUG(1, "couldn't find size %d,%d", x, y);
847 return -EINVAL;
848 }
849
850 if (newsize == cam->size) {
851 DEBUG(1, "Nothing to do");
852 return 0;
853 }
854
855 qcm_stop_data(uvd);
856
857 if (cam->size != newsize) {
858 oldsize = cam->size;
859 cam->size = newsize;
860 ret = qcm_set_camera_size(uvd);
861 if (ret) {
862 err("Couldn't set camera size, err=%d",ret);
863 /* restore the original size */
864 cam->size = oldsize;
865 return ret;
866 }
867 }
868
869 /* Flush the input queue and clear any current frame in progress */
870
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;
876 }
877
878 CHECK_RET(ret, qcm_start_data(uvd));
879 return 0;
880 }
881
882 static int qcm_configure_video(struct uvd *uvd)
883 {
884 int ret;
885 memset(&uvd->vpic, 0, sizeof(uvd->vpic));
886 memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
887
888 uvd->vpic.colour = colour;
889 uvd->vpic.hue = hue;
890 uvd->vpic.brightness = brightness;
891 uvd->vpic.contrast = contrast;
892 uvd->vpic.whiteness = whiteness;
893 uvd->vpic.depth = 24;
894 uvd->vpic.palette = VIDEO_PALETTE_RGB24;
895
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;
901
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;
906
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");
913
914 CHECK_RET(ret, qcm_sensor_init(uvd));
915 return 0;
916 }
917
918 static int qcm_probe(struct usb_interface *intf,
919 const struct usb_device_id *devid)
920 {
921 int err;
922 struct uvd *uvd;
923 struct usb_device *dev = interface_to_usbdev(intf);
924 struct qcm *cam;
925 size_t buffer_size;
926 unsigned char video_ep;
927 struct usb_host_interface *interface;
928 struct usb_endpoint_descriptor *endpoint;
929 int i,j;
930 unsigned int ifacenum, ifacenum_inact=0;
931 __le16 sensor_id;
932
933 /* we don't support multiconfig cams */
934 if (dev->descriptor.bNumConfigurations != 1)
935 return -ENODEV;
936
937 /* first check for the video interface and not
938 * the audio interface */
939 interface = &intf->cur_altsetting[0];
940 if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
941 || (interface->desc.bInterfaceSubClass !=
942 USB_CLASS_VENDOR_SPEC))
943 return -ENODEV;
944
945 /*
946 walk through each endpoint in each setting in the interface
947 stop when we find the one that's an isochronous IN endpoint.
948 */
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;
955
956 if ((endpoint->bEndpointAddress &
957 USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
958 continue; /* not input then not good */
959
960 buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
961 if (!buffer_size) {
962 ifacenum_inact = ifacenum;
963 continue; /* 0 pkt size is not what we want */
964 }
965
966 if ((endpoint->bmAttributes &
967 USB_ENDPOINT_XFERTYPE_MASK) ==
968 USB_ENDPOINT_XFER_ISOC) {
969 video_ep = endpoint->bEndpointAddress;
970 /* break out of the search */
971 goto good_videoep;
972 }
973 }
974 }
975 /* failed out since nothing useful was found */
976 err("No suitable endpoint was found\n");
977 return -ENODEV;
978
979 good_videoep:
980 /* disable isochronous stream before doing anything else */
981 err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
982 if (err < 0) {
983 err("Failed to disable sensor stream");
984 return -EIO;
985 }
986
987 /*
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.
993 */
994 err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
995 if (err < 0) {
996 err("Couldn't read sensor values. Err %d\n",err);
997 return err;
998 }
999 if (sensor_id != cpu_to_le16(0x08F0)) {
1000 err("Sensor ID %x != %x. Unsupported. Sorry\n",
1001 le16_to_cpu(sensor_id), (0x08F0));
1002 return -ENODEV;
1003 }
1004
1005 uvd = usbvideo_AllocateDevice(cams);
1006 if (!uvd)
1007 return -ENOMEM;
1008
1009 cam = (struct qcm *) uvd->user_data;
1010
1011 /* buf for doing demosaicing */
1012 cam->scratch = kmalloc(324*2, GFP_KERNEL);
1013 if (!cam->scratch) /* uvd freed in dereg */
1014 return -ENOMEM;
1015
1016 /* yes, if we fail after here, cam->scratch gets freed
1017 by qcm_free_uvd */
1018
1019 err = qcm_alloc_int_urb(cam);
1020 if (err < 0)
1021 return err;
1022
1023 /* yes, if we fail after here, int urb gets freed
1024 by qcm_free_uvd */
1025
1026 RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1027 cam->width = camera_sizes[size].width;
1028 cam->height = camera_sizes[size].height;
1029 cam->size = size;
1030
1031 uvd->debug = debug;
1032 uvd->flags = 0;
1033 uvd->dev = dev;
1034 uvd->iface = intf->altsetting->desc.bInterfaceNumber;
1035 uvd->ifaceAltActive = ifacenum;
1036 uvd->ifaceAltInactive = ifacenum_inact;
1037 uvd->video_endp = video_ep;
1038 uvd->iso_packet_len = buffer_size;
1039 uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
1040 uvd->defaultPalette = VIDEO_PALETTE_RGB24;
1041 uvd->canvas = VIDEOSIZE(320, 240);
1042 uvd->videosize = VIDEOSIZE(cam->width, cam->height);
1043 err = qcm_configure_video(uvd);
1044 if (err) {
1045 err("failed to configure video settings");
1046 return err;
1047 }
1048
1049 err = usbvideo_RegisterVideoDevice(uvd);
1050 if (err) { /* the uvd gets freed in Deregister */
1051 err("usbvideo_RegisterVideoDevice() failed.");
1052 return err;
1053 }
1054
1055 uvd->max_frame_size = (320 * 240 * 3);
1056 qcm_register_input(cam, dev);
1057 usb_set_intfdata(intf, uvd);
1058 return 0;
1059 }
1060
1061 static void qcm_free_uvd(struct uvd *uvd)
1062 {
1063 struct qcm *cam = (struct qcm *) uvd->user_data;
1064
1065 kfree(cam->scratch);
1066 qcm_unregister_input(cam);
1067 qcm_free_int(cam);
1068 }
1069
1070 static struct usbvideo_cb qcm_driver = {
1071 .probe = qcm_probe,
1072 .setupOnOpen = qcm_setup_on_open,
1073 .processData = qcm_process_isoc,
1074 .setVideoMode = qcm_set_video_mode,
1075 .startDataPump = qcm_start_data,
1076 .stopDataPump = qcm_stop_data,
1077 .adjustPicture = qcm_adjust_picture,
1078 .userFree = qcm_free_uvd
1079 };
1080
1081 static int __init qcm_init(void)
1082 {
1083 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
1084 DRIVER_DESC "\n");
1085
1086 return usbvideo_register(
1087 &cams,
1088 MAX_CAMERAS,
1089 sizeof(struct qcm),
1090 "QCM",
1091 &qcm_driver,
1092 THIS_MODULE,
1093 qcm_table);
1094 }
1095
1096 static void __exit qcm_exit(void)
1097 {
1098 usbvideo_Deregister(&cams);
1099 }
1100
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");
1113
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)");
1117 #endif
1118
1119 module_init(qcm_init);
1120 module_exit(qcm_exit);
1121
1122 MODULE_LICENSE("GPL");
1123 MODULE_AUTHOR("Jaya Kumar");
1124 MODULE_DESCRIPTION("QCM USB Camera");
1125 MODULE_SUPPORTED_DEVICE("QCM USB Camera");