Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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                 dev_warn(&dev->dev, "insufficient mem for cam input device\n");
 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(KEY_CAMERA)] = BIT_MASK(KEY_CAMERA);
107 
108         error = input_register_device(cam->input);
109         if (error) {
110                 dev_warn(&dev->dev,
111                          "Failed to register camera's input device, err: %d\n",
112                          error);
113                 input_free_device(cam->input);
114                 cam->input = NULL;
115         }
116 }
117 
118 static void qcm_unregister_input(struct qcm *cam)
119 {
120         if (cam->input) {
121                 input_unregister_device(cam->input);
122                 cam->input = NULL;
123         }
124 }
125 
126 static void qcm_report_buttonstat(struct qcm *cam)
127 {
128         if (cam->input) {
129                 input_report_key(cam->input, KEY_CAMERA, cam->button_sts);
130                 input_sync(cam->input);
131         }
132 }
133 
134 static void qcm_int_irq(struct urb *urb)
135 {
136         int ret;
137         struct uvd *uvd = urb->context;
138         struct qcm *cam;
139 
140         if (!CAMERA_IS_OPERATIONAL(uvd))
141                 return;
142 
143         if (!uvd->streaming)
144                 return;
145 
146         uvd->stats.urb_count++;
147 
148         if (urb->status < 0)
149                 uvd->stats.iso_err_count++;
150         else {
151                 if (urb->actual_length > 0 ) {
152                         cam = (struct qcm *) uvd->user_data;
153                         if (cam->button_sts_buf == 0x88)
154                                 cam->button_sts = 0x0;
155                         else if (cam->button_sts_buf == 0x80)
156                                 cam->button_sts = 0x1;
157                         qcm_report_buttonstat(cam);
158                 }
159         }
160 
161         ret = usb_submit_urb(urb, GFP_ATOMIC);
162         if (ret < 0)
163                 err("usb_submit_urb error (%d)", ret);
164 }
165 
166 static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
167 {
168         int errflag;
169         usb_fill_int_urb(cam->button_urb, uvd->dev,
170                         usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
171                         &cam->button_sts_buf,
172                         1,
173                         qcm_int_irq,
174                         uvd, 16);
175 
176         errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
177         if (errflag)
178                 err ("usb_submit_int ret %d", errflag);
179         return errflag;
180 }
181 
182 static void qcm_stop_int_data(struct qcm *cam)
183 {
184         usb_kill_urb(cam->button_urb);
185 }
186 
187 static int qcm_alloc_int_urb(struct qcm *cam)
188 {
189         cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
190 
191         if (!cam->button_urb)
192                 return -ENOMEM;
193 
194         return 0;
195 }
196 
197 static void qcm_free_int(struct qcm *cam)
198 {
199         usb_free_urb(cam->button_urb);
200 }
201 #endif /* CONFIG_INPUT */
202 
203 static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
204 {
205         int ret;
206 
207         /* we'll wait up to 3 slices but no more */
208         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
209                 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
210                 reg, 0, &val, 1, 3*HZ);
211         return ret;
212 }
213 
214 static int qcm_stv_setw(struct usb_device *dev, u16 reg, __le16 val)
215 {
216         int ret;
217 
218         /* we'll wait up to 3 slices but no more */
219         ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
220                 0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
221                 reg, 0, &val, 2, 3*HZ);
222         return ret;
223 }
224 
225 static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
226                                                         __le16 *val)
227 {
228         int ret;
229 
230         /* we'll wait up to 3 slices but no more */
231         ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
232                 0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
233                 reg, 0, val, 2, 3*HZ);
234         return ret;
235 }
236 
237 static int qcm_camera_on(struct uvd *uvd)
238 {
239         int ret;
240         CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
241         return 0;
242 }
243 
244 static int qcm_camera_off(struct uvd *uvd)
245 {
246         int ret;
247         CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
248         return 0;
249 }
250 
251 static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
252 {
253         unsigned int segment, valsat;
254         signed int   h = (signed int) hue;
255         unsigned int s = (sat - 32768) * 2;     /* rescale */
256         unsigned int v = val;
257         unsigned int p;
258 
259         /*
260         the registers controlling gain are 8 bit of which
261         we affect only the last 4 bits with our gain.
262         we know that if saturation is 0, (unsaturated) then
263         we're grayscale (center axis of the colour cone) so
264         we set rgb=value. we use a formula obtained from
265         wikipedia to map the cone to the RGB plane. it's
266         as follows for the human value case of h=0..360,
267         s=0..1, v=0..1
268         h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
269         q = v(1 - f*s) , t = v(1 - (1-f)s)
270         h_i==0 => r=v , g=t, b=p
271         h_i==1 => r=q , g=v, b=p
272         h_i==2 => r=p , g=v, b=t
273         h_i==3 => r=p , g=q, b=v
274         h_i==4 => r=t , g=p, b=v
275         h_i==5 => r=v , g=p, b=q
276         the bottom side (the point) and the stuff just up
277         of that is black so we simplify those two cases.
278         */
279         if (sat < 32768) {
280                 /* anything less than this is unsaturated */
281                 *r = val;
282                 *g = val;
283                 *b = val;
284                 return;
285         }
286         if (val <= (0xFFFF/8)) {
287                 /* anything less than this is black */
288                 *r = 0;
289                 *g = 0;
290                 *b = 0;
291                 return;
292         }
293 
294         /* the rest of this code is copying tukkat's
295         implementation of the hsv2rgb conversion as taken
296         from qc-usb-messenger code. the 10923 is 0xFFFF/6
297         to divide the cone into 6 sectors.  */
298 
299         segment = (h + 10923) & 0xFFFF;
300         segment = segment*3 >> 16;              /* 0..2: 0=R, 1=G, 2=B */
301         hue -= segment * 21845;                 /* -10923..10923 */
302         h = hue;
303         h *= 3;
304         valsat = v*s >> 16;                     /* 0..65534 */
305         p = v - valsat;
306         if (h >= 0) {
307                 unsigned int t = v - (valsat * (32769 - h) >> 15);
308                 switch (segment) {
309                 case 0: /* R-> */
310                         *r = v;
311                         *g = t;
312                         *b = p;
313                         break;
314                 case 1: /* G-> */
315                         *r = p;
316                         *g = v;
317                         *b = t;
318                         break;
319                 case 2: /* B-> */
320                         *r = t;
321                         *g = p;
322                         *b = v;
323                         break;
324                 }
325         } else {
326                 unsigned int q = v - (valsat * (32769 + h) >> 15);
327                 switch (segment) {
328                 case 0: /* ->R */
329                         *r = v;
330                         *g = p;
331                         *b = q;
332                         break;
333                 case 1: /* ->G */
334                         *r = q;
335                         *g = v;
336                         *b = p;
337                         break;
338                 case 2: /* ->B */
339                         *r = p;
340                         *g = q;
341                         *b = v;
342                         break;
343                 }
344         }
345 }
346 
347 static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
348         u16 saturation, u16 value)
349 {
350         int ret;
351         u16 r=0,g=0,b=0;
352 
353         /* this code is based on qc-usb-messenger */
354         qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
355 
356         r >>= 12;
357         g >>= 12;
358         b >>= 12;
359 
360         /* min val is 8 */
361         r = max((u16) 8, r);
362         g = max((u16) 8, g);
363         b = max((u16) 8, b);
364 
365         r |= 0x30;
366         g |= 0x30;
367         b |= 0x30;
368 
369         /* set the r,g,b gain registers */
370         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
371         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
372         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
373 
374         /* doing as qc-usb did */
375         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
376         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
377         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
378 
379         return 0;
380 }
381 
382 static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
383 {
384         int ret;
385         int formedval;
386 
387         /* calculation was from qc-usb-messenger driver */
388         formedval = ( exposure >> 12 );
389 
390         /* max value for formedval is 14 */
391         formedval = min(formedval, 14);
392 
393         CHECK_RET(ret, qcm_stv_setb(uvd->dev,
394                         0x143A, 0xF0 | formedval));
395         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
396         return 0;
397 }
398 
399 static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
400                                         int hue, int colour)
401 {
402         int ret;
403         /* brightness is exposure, contrast is gain, colour is saturation */
404         CHECK_RET(ret,
405                 qcm_sensor_set_exposure(uvd, brightness));
406         CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
407 
408         return 0;
409 }
410 
411 static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
412 {
413         int ret;
414 
415         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
416         return 0;
417 }
418 
419 static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
420 {
421         int ret;
422         /* some rescaling as done by the qc-usb-messenger code */
423         if (whiteness > 0xC000)
424                 whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
425 
426         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
427                                 (whiteness >> 8) & 0xFF));
428         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
429                                 (whiteness >> 16) & 0x03));
430         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
431 
432         return 0;
433 }
434 
435 static int qcm_sensor_init(struct uvd *uvd)
436 {
437         struct qcm *cam = (struct qcm *) uvd->user_data;
438         int ret;
439         int i;
440 
441         for (i=0; i < ARRAY_SIZE(regval_table) ; i++) {
442                 CHECK_RET(ret, qcm_stv_setb(uvd->dev,
443                                         regval_table[i].reg,
444                                         regval_table[i].val));
445         }
446 
447         CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
448                                 cpu_to_le16(ISOC_PACKET_SIZE)));
449         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
450         CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143f, 0x01));
451 
452         CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
453 
454         CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
455 
456         CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
457                         uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
458 
459         CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
460         CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
461 
462         return 0;
463 }
464 
465 static int qcm_set_camera_size(struct uvd *uvd)
466 {
467         int ret;
468         struct qcm *cam = (struct qcm *) uvd->user_data;
469 
470         CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
471         cam->width = camera_sizes[cam->size].width;
472         cam->height = camera_sizes[cam->size].height;
473         uvd->videosize = VIDEOSIZE(cam->width, cam->height);
474 
475         return 0;
476 }
477 
478 static int qcm_setup_on_open(struct uvd *uvd)
479 {
480         int ret;
481 
482         CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
483                                 uvd->vpic.colour, uvd->vpic.contrast));
484         CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
485         CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
486         CHECK_RET(ret, qcm_set_camera_size(uvd));
487         CHECK_RET(ret, qcm_camera_on(uvd));
488         return 0;
489 }
490 
491 static void qcm_adjust_picture(struct uvd *uvd)
492 {
493         int ret;
494         struct qcm *cam = (struct qcm *) uvd->user_data;
495 
496         ret = qcm_camera_off(uvd);
497         if (ret) {
498                 err("can't turn camera off. abandoning pic adjustment");
499                 return;
500         }
501 
502         /* if there's been a change in contrast, hue, or
503         colour then we need to recalculate hsv in order
504         to update gains */
505         if ((cam->contrast != uvd->vpic.contrast) ||
506                 (cam->hue != uvd->vpic.hue) ||
507                 (cam->colour != uvd->vpic.colour)) {
508                 cam->contrast = uvd->vpic.contrast;
509                 cam->hue = uvd->vpic.hue;
510                 cam->colour = uvd->vpic.colour;
511                 ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
512                                                 cam->contrast);
513                 if (ret) {
514                         err("can't set gains. abandoning pic adjustment");
515                         return;
516                 }
517         }
518 
519         if (cam->brightness != uvd->vpic.brightness) {
520                 cam->brightness = uvd->vpic.brightness;
521                 ret = qcm_sensor_set_exposure(uvd, cam->brightness);
522                 if (ret) {
523                         err("can't set exposure. abandoning pic adjustment");
524                         return;
525                 }
526         }
527 
528         if (cam->whiteness != uvd->vpic.whiteness) {
529                 cam->whiteness = uvd->vpic.whiteness;
530                 qcm_sensor_set_shutter(uvd, cam->whiteness);
531                 if (ret) {
532                         err("can't set shutter. abandoning pic adjustment");
533                         return;
534                 }
535         }
536 
537         ret = qcm_camera_on(uvd);
538         if (ret) {
539                 err("can't reenable camera. pic adjustment failed");
540                 return;
541         }
542 }
543 
544 static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
545 {
546         int datalen;
547         int totaldata;
548         struct framehdr {
549                 __be16 id;
550                 __be16 len;
551         };
552         struct framehdr *fhdr;
553 
554         totaldata = 0;
555         while (framelen) {
556                 fhdr = (struct framehdr *) cdata;
557                 datalen = be16_to_cpu(fhdr->len);
558                 framelen -= 4;
559                 cdata += 4;
560 
561                 if ((fhdr->id) == cpu_to_be16(0x8001)) {
562                         RingQueue_Enqueue(&uvd->dp, marker, 4);
563                         totaldata += 4;
564                         continue;
565                 }
566                 if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
567                         RingQueue_Enqueue(&uvd->dp, cdata, datalen);
568                         totaldata += datalen;
569                 }
570                 framelen -= datalen;
571                 cdata += datalen;
572         }
573         return totaldata;
574 }
575 
576 static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
577 {
578         int totlen;
579         int i;
580         unsigned char *cdata;
581 
582         totlen=0;
583         for (i = 0; i < dataurb->number_of_packets; i++) {
584                 int n = dataurb->iso_frame_desc[i].actual_length;
585                 int st = dataurb->iso_frame_desc[i].status;
586 
587                 cdata = dataurb->transfer_buffer +
588                         dataurb->iso_frame_desc[i].offset;
589 
590                 if (st < 0) {
591                         dev_warn(&uvd->dev->dev,
592                                  "Data error: packet=%d. len=%d. status=%d.\n",
593                                  i, n, st);
594                         uvd->stats.iso_err_count++;
595                         continue;
596                 }
597                 if (!n)
598                         continue;
599 
600                 totlen += qcm_process_frame(uvd, cdata, n);
601         }
602         return totlen;
603 }
604 
605 static void resubmit_urb(struct uvd *uvd, struct urb *urb)
606 {
607         int ret;
608 
609         urb->dev = uvd->dev;
610         ret = usb_submit_urb(urb, GFP_ATOMIC);
611         if (ret)
612                 err("usb_submit_urb error (%d)", ret);
613 }
614 
615 static void qcm_isoc_irq(struct urb *urb)
616 {
617         int len;
618         struct uvd *uvd = urb->context;
619 
620         if (!CAMERA_IS_OPERATIONAL(uvd))
621                 return;
622 
623         if (!uvd->streaming)
624                 return;
625 
626         uvd->stats.urb_count++;
627 
628         if (!urb->actual_length) {
629                 resubmit_urb(uvd, urb);
630                 return;
631         }
632 
633         len = qcm_compress_iso(uvd, urb);
634         resubmit_urb(uvd, urb);
635         uvd->stats.urb_length = len;
636         uvd->stats.data_count += len;
637         if (len)
638                 RingQueue_WakeUpInterruptible(&uvd->dp);
639 }
640 
641 static int qcm_start_data(struct uvd *uvd)
642 {
643         struct qcm *cam = (struct qcm *) uvd->user_data;
644         int i;
645         int errflag;
646         int pktsz;
647         int err;
648 
649         pktsz = uvd->iso_packet_len;
650         if (!CAMERA_IS_OPERATIONAL(uvd)) {
651                 err("Camera is not operational");
652                 return -EFAULT;
653         }
654 
655         err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
656         if (err < 0) {
657                 err("usb_set_interface error");
658                 uvd->last_error = err;
659                 return -EBUSY;
660         }
661 
662         for (i=0; i < USBVIDEO_NUMSBUF; i++) {
663                 int j, k;
664                 struct urb *urb = uvd->sbuf[i].urb;
665                 urb->dev = uvd->dev;
666                 urb->context = uvd;
667                 urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
668                 urb->interval = 1;
669                 urb->transfer_flags = URB_ISO_ASAP;
670                 urb->transfer_buffer = uvd->sbuf[i].data;
671                 urb->complete = qcm_isoc_irq;
672                 urb->number_of_packets = FRAMES_PER_DESC;
673                 urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
674                 for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
675                         urb->iso_frame_desc[j].offset = k;
676                         urb->iso_frame_desc[j].length = pktsz;
677                 }
678         }
679 
680         uvd->streaming = 1;
681         uvd->curframe = -1;
682         for (i=0; i < USBVIDEO_NUMSBUF; i++) {
683                 errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
684                 if (errflag)
685                         err ("usb_submit_isoc(%d) ret %d", i, errflag);
686         }
687 
688         CHECK_RET(err, qcm_setup_input_int(cam, uvd));
689         CHECK_RET(err, qcm_camera_on(uvd));
690         return 0;
691 }
692 
693 static void qcm_stop_data(struct uvd *uvd)
694 {
695         struct qcm *cam = (struct qcm *) uvd->user_data;
696         int i, j;
697         int ret;
698 
699         if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
700                 return;
701 
702         ret = qcm_camera_off(uvd);
703         if (ret)
704                 dev_warn(&uvd->dev->dev, "couldn't turn the cam off.\n");
705 
706         uvd->streaming = 0;
707 
708         /* Unschedule all of the iso td's */
709         for (i=0; i < USBVIDEO_NUMSBUF; i++)
710                 usb_kill_urb(uvd->sbuf[i].urb);
711 
712         qcm_stop_int_data(cam);
713 
714         if (!uvd->remove_pending) {
715                 /* Set packet size to 0 */
716                 j = usb_set_interface(uvd->dev, uvd->iface,
717                                         uvd->ifaceAltInactive);
718                 if (j < 0) {
719                         err("usb_set_interface() error %d.", j);
720                         uvd->last_error = j;
721                 }
722         }
723 }
724 
725 static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
726 {
727         struct qcm *cam = (struct qcm *) uvd->user_data;
728         int x;
729         struct rgb *rgbL0;
730         struct rgb *rgbL1;
731         struct bayL0 *bayL0;
732         struct bayL1 *bayL1;
733         int hor,ver,hordel,verdel;
734         assert(frame != NULL);
735 
736         switch (cam->size) {
737         case SIZE_160X120:
738                 hor = 162; ver = 124; hordel = 1; verdel = 2;
739                 break;
740         case SIZE_320X240:
741         default:
742                 hor = 324; ver = 248; hordel = 2; verdel = 4;
743                 break;
744         }
745 
746         if (frame->scanstate == ScanState_Scanning) {
747                 while (RingQueue_GetLength(&uvd->dp) >=
748                          4 + (hor*verdel + hordel)) {
749                         if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
750                             (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
751                             (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
752                             (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
753                                 frame->curline = 0;
754                                 frame->scanstate = ScanState_Lines;
755                                 frame->frameState = FrameState_Grabbing;
756                                 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
757                         /*
758                         * if we're starting, we need to discard the first
759                         * 4 lines of y bayer data
760                         * and the first 2 gr elements of x bayer data
761                         */
762                                 RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
763                                                         (hor*verdel + hordel));
764                                 break;
765                         }
766                         RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
767                 }
768         }
769 
770         if (frame->scanstate == ScanState_Scanning)
771                 return;
772 
773         /* now we can start processing bayer data so long as we have at least
774         * 2 lines worth of data. this is the simplest demosaicing method that
775         * I could think of. I use each 2x2 bayer element without interpolation
776         * to generate 4 rgb pixels.
777         */
778         while ( frame->curline < cam->height &&
779                 (RingQueue_GetLength(&uvd->dp) >= hor*2)) {
780                 /* get 2 lines of bayer for demosaicing
781                  * into 2 lines of RGB */
782                 RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
783                 bayL0 = (struct bayL0 *) cam->scratch;
784                 bayL1 = (struct bayL1 *) (cam->scratch + hor);
785                 /* frame->curline is the rgb y line */
786                 rgbL0 = (struct rgb *)
787                                 ( frame->data + (cam->width*3*frame->curline));
788                 /* w/2 because we're already doing 2 pixels */
789                 rgbL1 = rgbL0 + (cam->width/2);
790 
791                 for (x=0; x < cam->width; x+=2) {
792                         rgbL0->r = bayL0->r;
793                         rgbL0->g = bayL0->g;
794                         rgbL0->b = bayL1->b;
795 
796                         rgbL0->r2 = bayL0->r;
797                         rgbL0->g2 = bayL1->g;
798                         rgbL0->b2 = bayL1->b;
799 
800                         rgbL1->r = bayL0->r;
801                         rgbL1->g = bayL1->g;
802                         rgbL1->b = bayL1->b;
803 
804                         rgbL1->r2 = bayL0->r;
805                         rgbL1->g2 = bayL1->g;
806                         rgbL1->b2 = bayL1->b;
807 
808                         rgbL0++;
809                         rgbL1++;
810 
811                         bayL0++;
812                         bayL1++;
813                 }
814 
815                 frame->seqRead_Length += cam->width*3*2;
816                 frame->curline += 2;
817         }
818         /* See if we filled the frame */
819         if (frame->curline == cam->height) {
820                 frame->frameState = FrameState_Done_Hold;
821                 frame->curline = 0;
822                 uvd->curframe = -1;
823                 uvd->stats.frame_num++;
824         }
825 }
826 
827 /* taken from konicawc */
828 static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
829 {
830         int ret;
831         int newsize;
832         int oldsize;
833         int x = vw->width;
834         int y = vw->height;
835         struct qcm *cam = (struct qcm *) uvd->user_data;
836 
837         if (x > 0 && y > 0) {
838                 DEBUG(2, "trying to find size %d,%d", x, y);
839                 for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
840                         if ((camera_sizes[newsize].width == x) &&
841                                 (camera_sizes[newsize].height == y))
842                                 break;
843                 }
844         } else
845                 newsize = cam->size;
846 
847         if (newsize > MAX_FRAME_SIZE) {
848                 DEBUG(1, "couldn't find size %d,%d", x, y);
849                 return -EINVAL;
850         }
851 
852         if (newsize == cam->size) {
853                 DEBUG(1, "Nothing to do");
854                 return 0;
855         }
856 
857         qcm_stop_data(uvd);
858 
859         if (cam->size != newsize) {
860                 oldsize = cam->size;
861                 cam->size = newsize;
862                 ret = qcm_set_camera_size(uvd);
863                 if (ret) {
864                         err("Couldn't set camera size, err=%d",ret);
865                         /* restore the original size */
866                         cam->size = oldsize;
867                         return ret;
868                 }
869         }
870 
871         /* Flush the input queue and clear any current frame in progress */
872 
873         RingQueue_Flush(&uvd->dp);
874         if (uvd->curframe != -1) {
875                 uvd->frame[uvd->curframe].curline = 0;
876                 uvd->frame[uvd->curframe].seqRead_Length = 0;
877                 uvd->frame[uvd->curframe].seqRead_Index = 0;
878         }
879 
880         CHECK_RET(ret, qcm_start_data(uvd));
881         return 0;
882 }
883 
884 static int qcm_configure_video(struct uvd *uvd)
885 {
886         int ret;
887         memset(&uvd->vpic, 0, sizeof(uvd->vpic));
888         memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
889 
890         uvd->vpic.colour = colour;
891         uvd->vpic.hue = hue;
892         uvd->vpic.brightness = brightness;
893         uvd->vpic.contrast = contrast;
894         uvd->vpic.whiteness = whiteness;
895         uvd->vpic.depth = 24;
896         uvd->vpic.palette = VIDEO_PALETTE_RGB24;
897 
898         memset(&uvd->vcap, 0, sizeof(uvd->vcap));
899         strcpy(uvd->vcap.name, "QCM USB Camera");
900         uvd->vcap.type = VID_TYPE_CAPTURE;
901         uvd->vcap.channels = 1;
902         uvd->vcap.audios = 0;
903 
904         uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
905         uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
906         uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
907         uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
908 
909         memset(&uvd->vchan, 0, sizeof(uvd->vchan));
910         uvd->vchan.flags = 0 ;
911         uvd->vchan.tuners = 0;
912         uvd->vchan.channel = 0;
913         uvd->vchan.type = VIDEO_TYPE_CAMERA;
914         strcpy(uvd->vchan.name, "Camera");
915 
916         CHECK_RET(ret, qcm_sensor_init(uvd));
917         return 0;
918 }
919 
920 static int qcm_probe(struct usb_interface *intf,
921                         const struct usb_device_id *devid)
922 {
923         int err;
924         struct uvd *uvd;
925         struct usb_device *dev = interface_to_usbdev(intf);
926         struct qcm *cam;
927         size_t buffer_size;
928         unsigned char video_ep;
929         struct usb_host_interface *interface;
930         struct usb_endpoint_descriptor *endpoint;
931         int i,j;
932         unsigned int ifacenum, ifacenum_inact=0;
933         __le16 sensor_id;
934 
935         /* we don't support multiconfig cams */
936         if (dev->descriptor.bNumConfigurations != 1)
937                 return -ENODEV;
938 
939         /* first check for the video interface and not
940         * the audio interface */
941         interface = &intf->cur_altsetting[0];
942         if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
943                 || (interface->desc.bInterfaceSubClass !=
944                         USB_CLASS_VENDOR_SPEC))
945                 return -ENODEV;
946 
947         /*
948         walk through each endpoint in each setting in the interface
949         stop when we find the one that's an isochronous IN endpoint.
950         */
951         for (i=0; i < intf->num_altsetting; i++) {
952                 interface = &intf->cur_altsetting[i];
953                 ifacenum = interface->desc.bAlternateSetting;
954                 /* walk the end points */
955                 for (j=0; j < interface->desc.bNumEndpoints; j++) {
956                         endpoint = &interface->endpoint[j].desc;
957 
958                         if (usb_endpoint_dir_out(endpoint))
959                                 continue; /* not input then not good */
960 
961                         buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
962                         if (!buffer_size) {
963                                 ifacenum_inact = ifacenum;
964                                 continue; /* 0 pkt size is not what we want */
965                         }
966 
967                         if (usb_endpoint_xfer_isoc(endpoint)) {
968                                 video_ep = endpoint->bEndpointAddress;
969                                 /* break out of the search */
970                                 goto good_videoep;
971                         }
972                 }
973         }
974         /* failed out since nothing useful was found */
975         err("No suitable endpoint was found\n");
976         return -ENODEV;
977 
978 good_videoep:
979         /* disable isochronous stream before doing anything else */
980         err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
981         if (err < 0) {
982                 err("Failed to disable sensor stream");
983                 return -EIO;
984         }
985 
986         /*
987         Check that this is the same unknown sensor that is known to work. This
988         sensor is suspected to be the ST VV6422C001. I'll check the same value
989         that the qc-usb driver checks. This value is probably not even the
990         sensor ID since it matches the USB dev ID. Oh well. If it doesn't
991         match, it's probably a diff sensor so exit and apologize.
992         */
993         err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
994         if (err < 0) {
995                 err("Couldn't read sensor values. Err %d\n",err);
996                 return err;
997         }
998         if (sensor_id != cpu_to_le16(0x08F0)) {
999                 err("Sensor ID %x != %x. Unsupported. Sorry\n",
1000                         le16_to_cpu(sensor_id), (0x08F0));
1001                 return -ENODEV;
1002         }
1003 
1004         uvd = usbvideo_AllocateDevice(cams);
1005         if (!uvd)
1006                 return -ENOMEM;
1007 
1008         cam = (struct qcm *) uvd->user_data;
1009 
1010         /* buf for doing demosaicing */
1011         cam->scratch = kmalloc(324*2, GFP_KERNEL);
1012         if (!cam->scratch) /* uvd freed in dereg */
1013                 return -ENOMEM;
1014 
1015         /* yes, if we fail after here, cam->scratch gets freed
1016         by qcm_free_uvd */
1017 
1018         err = qcm_alloc_int_urb(cam);
1019         if (err < 0)
1020                 return err;
1021 
1022         /* yes, if we fail after here, int urb gets freed
1023         by qcm_free_uvd */
1024 
1025         RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1026         cam->width = camera_sizes[size].width;
1027         cam->height = camera_sizes[size].height;
1028         cam->size = size;
1029 
1030         uvd->debug = debug;
1031         uvd->flags = 0;
1032         uvd->dev = dev;
1033         uvd->iface = intf->altsetting->desc.bInterfaceNumber;
1034         uvd->ifaceAltActive = ifacenum;
1035         uvd->ifaceAltInactive = ifacenum_inact;
1036         uvd->video_endp = video_ep;
1037         uvd->iso_packet_len = buffer_size;
1038         uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
1039         uvd->defaultPalette = VIDEO_PALETTE_RGB24;
1040         uvd->canvas = VIDEOSIZE(320, 240);
1041         uvd->videosize = VIDEOSIZE(cam->width, cam->height);
1042         err = qcm_configure_video(uvd);
1043         if (err) {
1044                 err("failed to configure video settings");
1045                 return err;
1046         }
1047 
1048         err = usbvideo_RegisterVideoDevice(uvd);
1049         if (err) { /* the uvd gets freed in Deregister */
1050                 err("usbvideo_RegisterVideoDevice() failed.");
1051                 return err;
1052         }
1053 
1054         uvd->max_frame_size = (320 * 240 * 3);
1055         qcm_register_input(cam, dev);
1056         usb_set_intfdata(intf, uvd);
1057         return 0;
1058 }
1059 
1060 static void qcm_free_uvd(struct uvd *uvd)
1061 {
1062         struct qcm *cam = (struct qcm *) uvd->user_data;
1063 
1064         kfree(cam->scratch);
1065         qcm_unregister_input(cam);
1066         qcm_free_int(cam);
1067 }
1068 
1069 static struct usbvideo_cb qcm_driver = {
1070         .probe =                qcm_probe,
1071         .setupOnOpen =          qcm_setup_on_open,
1072         .processData =          qcm_process_isoc,
1073         .setVideoMode =         qcm_set_video_mode,
1074         .startDataPump =        qcm_start_data,
1075         .stopDataPump =         qcm_stop_data,
1076         .adjustPicture =        qcm_adjust_picture,
1077         .userFree =             qcm_free_uvd
1078 };
1079 
1080 static int __init qcm_init(void)
1081 {
1082         printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
1083                DRIVER_DESC "\n");
1084 
1085         return usbvideo_register(
1086                 &cams,
1087                 MAX_CAMERAS,
1088                 sizeof(struct qcm),
1089                 "QCM",
1090                 &qcm_driver,
1091                 THIS_MODULE,
1092                 qcm_table);
1093 }
1094 
1095 static void __exit qcm_exit(void)
1096 {
1097         usbvideo_Deregister(&cams);
1098 }
1099 
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");
1112 
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)");
1116 #endif
1117 
1118 module_init(qcm_init);
1119 module_exit(qcm_exit);
1120 
1121 MODULE_LICENSE("GPL");
1122 MODULE_AUTHOR("Jaya Kumar");
1123 MODULE_DESCRIPTION("QCM USB Camera");
1124 MODULE_SUPPORTED_DEVICE("QCM USB Camera");
1125 
  This page was automatically generated by the LXR engine.