commented early_printk patch because of rejects.
[linux-flexiantxendom0-3.2.10.git] / drivers / media / video / c-qcam.c
1 /*
2  *      Video4Linux Colour QuickCam driver
3  *      Copyright 1997-2000 Philip Blundell <philb@gnu.org>
4  *
5  *    Module parameters:
6  *
7  *      parport=auto      -- probe all parports (default)
8  *      parport=0         -- parport0 becomes qcam1
9  *      parport=2,0,1     -- parports 2,0,1 are tried in that order
10  *
11  *      probe=0           -- do no probing, assume camera is present
12  *      probe=1           -- use IEEE-1284 autoprobe data only (default)
13  *      probe=2           -- probe aggressively for cameras
14  *
15  *      force_rgb=1       -- force data format to RGB (default is BGR)
16  *
17  * The parport parameter controls which parports will be scanned.
18  * Scanning all parports causes some printers to print a garbage page.
19  *       -- March 14, 1999  Billy Donahue <billy@escape.com> 
20  *
21  * Fixed data format to BGR, added force_rgb parameter. Added missing
22  * parport_unregister_driver() on module removal.
23  *       -- May 28, 2000  Claudio Matsuoka <claudio@conectiva.com>
24  */
25
26 #include <linux/module.h>
27 #include <linux/delay.h>
28 #include <linux/errno.h>
29 #include <linux/fs.h>
30 #include <linux/init.h>
31 #include <linux/kernel.h>
32 #include <linux/slab.h>
33 #include <linux/mm.h>
34 #include <linux/parport.h>
35 #include <linux/sched.h>
36 #include <linux/version.h>
37 #include <linux/videodev.h>
38 #include <asm/semaphore.h>
39 #include <asm/uaccess.h>
40
41 struct qcam_device {
42         struct video_device vdev;
43         struct pardevice *pdev;
44         struct parport *pport;
45         int width, height;
46         int ccd_width, ccd_height;
47         int mode;
48         int contrast, brightness, whitebal;
49         int top, left;
50         unsigned int bidirectional;
51         struct semaphore lock;
52 };
53
54 /* cameras maximum */
55 #define MAX_CAMS 4
56
57 /* The three possible QuickCam modes */
58 #define QC_MILLIONS     0x18
59 #define QC_BILLIONS     0x10
60 #define QC_THOUSANDS    0x08    /* with VIDEC compression (not supported) */
61
62 /* The three possible decimations */
63 #define QC_DECIMATION_1         0
64 #define QC_DECIMATION_2         2
65 #define QC_DECIMATION_4         4
66
67 #define BANNER "Colour QuickCam for Video4Linux v0.05"
68
69 static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
70 static int probe = 2;
71 static int force_rgb = 0;
72 static int video_nr = -1;
73
74 static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
75 {
76         /* note: the QC specs refer to the PCAck pin by voltage, not
77            software level.  PC ports have builtin inverters. */
78         parport_frob_control(qcam->pport, 8, i?8:0);
79 }
80
81 static inline unsigned int qcam_ready1(struct qcam_device *qcam)
82 {
83         return (parport_read_status(qcam->pport) & 0x8)?1:0;
84 }
85
86 static inline unsigned int qcam_ready2(struct qcam_device *qcam)
87 {
88         return (parport_read_data(qcam->pport) & 0x1)?1:0;
89 }
90
91 static unsigned int qcam_await_ready1(struct qcam_device *qcam, 
92                                              int value)
93 {
94         unsigned long oldjiffies = jiffies;
95         unsigned int i;
96
97         for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
98                 if (qcam_ready1(qcam) == value)
99                         return 0;
100
101         /* If the camera didn't respond within 1/25 second, poll slowly 
102            for a while. */
103         for (i = 0; i < 50; i++)
104         {
105                 if (qcam_ready1(qcam) == value)
106                         return 0;
107                 current->state=TASK_INTERRUPTIBLE;
108                 schedule_timeout(HZ/10);
109         }
110
111         /* Probably somebody pulled the plug out.  Not much we can do. */
112         printk(KERN_ERR "c-qcam: ready1 timeout (%d) %x %x\n", value,
113                parport_read_status(qcam->pport),
114                parport_read_control(qcam->pport));
115         return 1;
116 }
117
118 static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
119 {
120         unsigned long oldjiffies = jiffies;
121         unsigned int i;
122
123         for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
124                 if (qcam_ready2(qcam) == value)
125                         return 0;
126
127         /* If the camera didn't respond within 1/25 second, poll slowly 
128            for a while. */
129         for (i = 0; i < 50; i++)
130         {
131                 if (qcam_ready2(qcam) == value)
132                         return 0;
133                 current->state=TASK_INTERRUPTIBLE;
134                 schedule_timeout(HZ/10);
135         }
136
137         /* Probably somebody pulled the plug out.  Not much we can do. */
138         printk(KERN_ERR "c-qcam: ready2 timeout (%d) %x %x %x\n", value,
139                parport_read_status(qcam->pport),
140                parport_read_control(qcam->pport),
141                parport_read_data(qcam->pport));
142         return 1;
143 }
144
145 static int qcam_read_data(struct qcam_device *qcam)
146 {
147         unsigned int idata;
148         qcam_set_ack(qcam, 0);
149         if (qcam_await_ready1(qcam, 1)) return -1;
150         idata = parport_read_status(qcam->pport) & 0xf0;
151         qcam_set_ack(qcam, 1);
152         if (qcam_await_ready1(qcam, 0)) return -1;
153         idata |= (parport_read_status(qcam->pport) >> 4);
154         return idata;
155 }
156
157 static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
158 {
159         unsigned int idata;
160         parport_write_data(qcam->pport, data);
161         idata = qcam_read_data(qcam);
162         if (data != idata) 
163         {
164                 printk(KERN_WARNING "cqcam: sent %x but received %x\n", data, 
165                        idata);
166                 return 1;
167         } 
168         return 0;
169 }
170
171 static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data)
172 {
173         if (qcam_write_data(qcam, cmd))
174                 return -1;
175         if (qcam_write_data(qcam, data))
176                 return -1;
177         return 0;
178 }
179
180 static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd)
181 {
182         if (qcam_write_data(qcam, cmd))
183                 return -1;
184         return qcam_read_data(qcam);
185 }
186
187 static int qc_detect(struct qcam_device *qcam)
188 {
189         unsigned int stat, ostat, i, count = 0;
190
191         /* The probe routine below is not very reliable.  The IEEE-1284
192            probe takes precedence. */
193         /* XXX Currently parport provides no way to distinguish between
194            "the IEEE probe was not done" and "the probe was done, but
195            no device was found".  Fix this one day. */
196         if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
197             && qcam->pport->probe_info[0].model
198             && !strcmp(qcam->pdev->port->probe_info[0].model, 
199                        "Color QuickCam 2.0")) {
200                 printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
201                 return 1;
202         }
203         
204         if (probe < 2)
205                 return 0;
206
207         parport_write_control(qcam->pport, 0xc);
208
209         /* look for a heartbeat */
210         ostat = stat = parport_read_status(qcam->pport);
211         for (i=0; i<250; i++) 
212         {
213                 mdelay(1);
214                 stat = parport_read_status(qcam->pport);
215                 if (ostat != stat) 
216                 {
217                         if (++count >= 3) return 1;
218                         ostat = stat;
219                 }
220         }
221
222         /* Reset the camera and try again */
223         parport_write_control(qcam->pport, 0xc);
224         parport_write_control(qcam->pport, 0x8);
225         mdelay(1);
226         parport_write_control(qcam->pport, 0xc);
227         mdelay(1);
228         count = 0;
229
230         ostat = stat = parport_read_status(qcam->pport);
231         for (i=0; i<250; i++) 
232         {
233                 mdelay(1);
234                 stat = parport_read_status(qcam->pport);
235                 if (ostat != stat) 
236                 {
237                         if (++count >= 3) return 1;
238                         ostat = stat;
239                 }
240         }
241
242         /* no (or flatline) camera, give up */
243         return 0;
244 }
245
246 static void qc_reset(struct qcam_device *qcam)
247 {
248         parport_write_control(qcam->pport, 0xc);
249         parport_write_control(qcam->pport, 0x8);
250         mdelay(1);
251         parport_write_control(qcam->pport, 0xc);
252         mdelay(1);          
253 }
254
255 /* Reset the QuickCam and program for brightness, contrast,
256  * white-balance, and resolution. */
257
258 static void qc_setup(struct qcam_device *q)
259 {
260         qc_reset(q);
261
262         /* Set the brightness.  */
263         qcam_set(q, 11, q->brightness);
264
265         /* Set the height and width.  These refer to the actual
266            CCD area *before* applying the selected decimation.  */
267         qcam_set(q, 17, q->ccd_height);
268         qcam_set(q, 19, q->ccd_width / 2);
269
270         /* Set top and left.  */
271         qcam_set(q, 0xd, q->top);
272         qcam_set(q, 0xf, q->left);
273
274         /* Set contrast and white balance.  */
275         qcam_set(q, 0x19, q->contrast);
276         qcam_set(q, 0x1f, q->whitebal);
277         
278         /* Set the speed.  */
279         qcam_set(q, 45, 2);
280 }
281
282 /* Read some bytes from the camera and put them in the buffer. 
283    nbytes should be a multiple of 3, because bidirectional mode gives
284    us three bytes at a time.  */
285
286 static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes)
287 {
288         unsigned int bytes = 0;
289
290         qcam_set_ack(q, 0);
291         if (q->bidirectional)
292         {
293                 /* It's a bidirectional port */
294                 while (bytes < nbytes)
295                 {
296                         unsigned int lo1, hi1, lo2, hi2;
297                         unsigned char r, g, b;
298
299                         if (qcam_await_ready2(q, 1)) return bytes;
300                         lo1 = parport_read_data(q->pport) >> 1;
301                         hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
302                         qcam_set_ack(q, 1);
303                         if (qcam_await_ready2(q, 0)) return bytes;
304                         lo2 = parport_read_data(q->pport) >> 1;
305                         hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
306                         qcam_set_ack(q, 0);
307                         r = (lo1 | ((hi1 & 1)<<7));
308                         g = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1);
309                         b = (lo2 | ((hi2 & 1)<<7));
310                         if (force_rgb) {
311                                 buf[bytes++] = r;
312                                 buf[bytes++] = g;
313                                 buf[bytes++] = b;
314                         } else {
315                                 buf[bytes++] = b;
316                                 buf[bytes++] = g;
317                                 buf[bytes++] = r;
318                         }
319                 }
320         }
321         else
322         {
323                 /* It's a unidirectional port */
324                 int i = 0, n = bytes;
325                 unsigned char rgb[3];
326
327                 while (bytes < nbytes)
328                 {
329                         unsigned int hi, lo;
330
331                         if (qcam_await_ready1(q, 1)) return bytes;
332                         hi = (parport_read_status(q->pport) & 0xf0);
333                         qcam_set_ack(q, 1);
334                         if (qcam_await_ready1(q, 0)) return bytes;
335                         lo = (parport_read_status(q->pport) & 0xf0);
336                         qcam_set_ack(q, 0);
337                         /* flip some bits */
338                         rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
339                         if (i >= 2) {
340 get_fragment:
341                                 if (force_rgb) {
342                                         buf[n++] = rgb[0];
343                                         buf[n++] = rgb[1];
344                                         buf[n++] = rgb[2];
345                                 } else {
346                                         buf[n++] = rgb[2];
347                                         buf[n++] = rgb[1];
348                                         buf[n++] = rgb[0];
349                                 }
350                         }
351                 }
352                 if (i) {
353                         i = 0;
354                         goto get_fragment;
355                 }
356         }
357         return bytes;
358 }
359
360 #define BUFSZ   150
361
362 static long qc_capture(struct qcam_device *q, char *buf, unsigned long len)
363 {
364         unsigned lines, pixelsperline, bitsperxfer;
365         unsigned int is_bi_dir = q->bidirectional;
366         size_t wantlen, outptr = 0;
367         char tmpbuf[BUFSZ];
368
369         if (verify_area(VERIFY_WRITE, buf, len))
370                 return -EFAULT;
371
372         /* Wait for camera to become ready */
373         for (;;)
374         {
375                 int i = qcam_get(q, 41);
376                 if (i == -1) {
377                         qc_setup(q);
378                         return -EIO;
379                 }
380                 if ((i & 0x80) == 0)
381                         break;
382                 else
383                         schedule();
384         }
385
386         if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1))
387                 return -EIO;
388         
389         lines = q->height;
390         pixelsperline = q->width;
391         bitsperxfer = (is_bi_dir) ? 24 : 8;
392
393         if (is_bi_dir)
394         {
395                 /* Turn the port around */
396                 parport_data_reverse(q->pport);
397                 mdelay(3);
398                 qcam_set_ack(q, 0);
399                 if (qcam_await_ready1(q, 1)) {
400                         qc_setup(q);
401                         return -EIO;
402                 }
403                 qcam_set_ack(q, 1);
404                 if (qcam_await_ready1(q, 0)) {
405                         qc_setup(q);
406                         return -EIO;
407                 }
408         }
409
410         wantlen = lines * pixelsperline * 24 / 8;
411
412         while (wantlen)
413         {
414                 size_t t, s;
415                 s = (wantlen > BUFSZ)?BUFSZ:wantlen;
416                 t = qcam_read_bytes(q, tmpbuf, s);
417                 if (outptr < len)
418                 {
419                         size_t sz = len - outptr;
420                         if (sz > t) sz = t;
421                         if (__copy_to_user(buf+outptr, tmpbuf, sz))
422                                 break;
423                         outptr += sz;
424                 }
425                 wantlen -= t;
426                 if (t < s)
427                         break;
428                 cond_resched();
429         }
430
431         len = outptr;
432
433         if (wantlen)
434         {
435                 printk("qcam: short read.\n");
436                 if (is_bi_dir)
437                         parport_data_forward(q->pport);
438                 qc_setup(q);
439                 return len;
440         }
441
442         if (is_bi_dir)
443         {
444                 int l;
445                 do {
446                         l = qcam_read_bytes(q, tmpbuf, 3);
447                         cond_resched();
448                 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
449                 if (force_rgb) {
450                         if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
451                                 printk("qcam: bad EOF\n");
452                 } else {
453                         if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
454                                 printk("qcam: bad EOF\n");
455                 }
456                 qcam_set_ack(q, 0);
457                 if (qcam_await_ready1(q, 1))
458                 {
459                         printk("qcam: no ack after EOF\n");
460                         parport_data_forward(q->pport);
461                         qc_setup(q);
462                         return len;
463                 }
464                 parport_data_forward(q->pport);
465                 mdelay(3);
466                 qcam_set_ack(q, 1);
467                 if (qcam_await_ready1(q, 0))
468                 {
469                         printk("qcam: no ack to port turnaround\n");
470                         qc_setup(q);
471                         return len;
472                 }
473         }
474         else
475         {
476                 int l;
477                 do {
478                         l = qcam_read_bytes(q, tmpbuf, 1);
479                         cond_resched();
480                 } while (l && tmpbuf[0] == 0x7e);
481                 l = qcam_read_bytes(q, tmpbuf+1, 2);
482                 if (force_rgb) {
483                         if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
484                                 printk("qcam: bad EOF\n");
485                 } else {
486                         if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
487                                 printk("qcam: bad EOF\n");
488                 }
489         }
490
491         qcam_write_data(q, 0);
492         return len;
493 }
494
495 /*
496  *      Video4linux interfacing
497  */
498
499 static int qcam_do_ioctl(struct inode *inode, struct file *file,
500                          unsigned int cmd, void *arg)
501 {
502         struct video_device *dev = video_devdata(file);
503         struct qcam_device *qcam=(struct qcam_device *)dev;
504         
505         switch(cmd)
506         {
507                 case VIDIOCGCAP:
508                 {
509                         struct video_capability *b = arg;
510                         strcpy(b->name, "Quickcam");
511                         b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
512                         b->channels = 1;
513                         b->audios = 0;
514                         b->maxwidth = 320;
515                         b->maxheight = 240;
516                         b->minwidth = 80;
517                         b->minheight = 60;
518                         return 0;
519                 }
520                 case VIDIOCGCHAN:
521                 {
522                         struct video_channel *v = arg;
523                         if(v->channel!=0)
524                                 return -EINVAL;
525                         v->flags=0;
526                         v->tuners=0;
527                         /* Good question.. its composite or SVHS so.. */
528                         v->type = VIDEO_TYPE_CAMERA;
529                         strcpy(v->name, "Camera");
530                         return 0;
531                 }
532                 case VIDIOCSCHAN:
533                 {
534                         struct video_channel *v = arg;
535                         if(v->channel!=0)
536                                 return -EINVAL;
537                         return 0;
538                 }
539                 case VIDIOCGTUNER:
540                 {
541                         struct video_tuner *v = arg;
542                         if(v->tuner)
543                                 return -EINVAL;
544                         memset(v,0,sizeof(*v));
545                         strcpy(v->name, "Format");
546                         v->mode = VIDEO_MODE_AUTO;
547                         return 0;
548                 }
549                 case VIDIOCSTUNER:
550                 {
551                         struct video_tuner *v = arg;
552                         if(v->tuner)
553                                 return -EINVAL;
554                         if(v->mode!=VIDEO_MODE_AUTO)
555                                 return -EINVAL;
556                         return 0;
557                 }
558                 case VIDIOCGPICT:
559                 {
560                         struct video_picture *p = arg;
561                         p->colour=0x8000;
562                         p->hue=0x8000;
563                         p->brightness=qcam->brightness<<8;
564                         p->contrast=qcam->contrast<<8;
565                         p->whiteness=qcam->whitebal<<8;
566                         p->depth=24;
567                         p->palette=VIDEO_PALETTE_RGB24;
568                         return 0;
569                 }
570                 case VIDIOCSPICT:
571                 {
572                         struct video_picture *p = arg;
573
574                         /*
575                          *      Sanity check args
576                          */
577                         if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
578                                 return -EINVAL;
579                         
580                         /*
581                          *      Now load the camera.
582                          */
583                         qcam->brightness = p->brightness>>8;
584                         qcam->contrast = p->contrast>>8;
585                         qcam->whitebal = p->whiteness>>8;
586
587                         down(&qcam->lock);                      
588                         parport_claim_or_block(qcam->pdev);
589                         qc_setup(qcam); 
590                         parport_release(qcam->pdev);
591                         up(&qcam->lock);
592                         return 0;
593                 }
594                 case VIDIOCSWIN:
595                 {
596                         struct video_window *vw = arg;
597
598                         if(vw->flags)
599                                 return -EINVAL;
600                         if(vw->clipcount)
601                                 return -EINVAL;
602                         if(vw->height<60||vw->height>240)
603                                 return -EINVAL;
604                         if(vw->width<80||vw->width>320)
605                                 return -EINVAL;
606                                 
607                         qcam->width = 80;
608                         qcam->height = 60;
609                         qcam->mode = QC_DECIMATION_4;
610                         
611                         if(vw->width>=160 && vw->height>=120)
612                         {
613                                 qcam->width = 160;
614                                 qcam->height = 120;
615                                 qcam->mode = QC_DECIMATION_2;
616                         }
617                         if(vw->width>=320 && vw->height>=240)
618                         {
619                                 qcam->width = 320;
620                                 qcam->height = 240;
621                                 qcam->mode = QC_DECIMATION_1;
622                         }
623                         qcam->mode |= QC_MILLIONS;
624 #if 0
625                         if(vw->width>=640 && vw->height>=480)
626                         {
627                                 qcam->width = 640;
628                                 qcam->height = 480;
629                                 qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
630                         }
631 #endif
632                         /* Ok we figured out what to use from our 
633                            wide choice */
634                         down(&qcam->lock);
635                         parport_claim_or_block(qcam->pdev);
636                         qc_setup(qcam);
637                         parport_release(qcam->pdev);
638                         up(&qcam->lock);
639                         return 0;
640                 }
641                 case VIDIOCGWIN:
642                 {
643                         struct video_window *vw = arg;
644                         memset(vw, 0, sizeof(*vw));
645                         vw->width=qcam->width;
646                         vw->height=qcam->height;
647                         return 0;
648                 }
649                 case VIDIOCKEY:
650                         return 0;
651                 case VIDIOCCAPTURE:
652                 case VIDIOCGFBUF:
653                 case VIDIOCSFBUF:
654                 case VIDIOCGFREQ:
655                 case VIDIOCSFREQ:
656                 case VIDIOCGAUDIO:
657                 case VIDIOCSAUDIO:
658                         return -EINVAL;
659                 default:
660                         return -ENOIOCTLCMD;
661         }
662         return 0;
663 }
664
665 static int qcam_ioctl(struct inode *inode, struct file *file,
666                      unsigned int cmd, unsigned long arg)
667 {
668         return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
669 }
670
671 static ssize_t qcam_read(struct file *file, char *buf,
672                          size_t count, loff_t *ppos)
673 {
674         struct video_device *v = video_devdata(file);
675         struct qcam_device *qcam=(struct qcam_device *)v;
676         int len;
677
678         down(&qcam->lock);
679         parport_claim_or_block(qcam->pdev);
680         /* Probably should have a semaphore against multiple users */
681         len = qc_capture(qcam, buf,count); 
682         parport_release(qcam->pdev);
683         up(&qcam->lock);
684         return len;
685 }
686
687 /* video device template */
688 static struct file_operations qcam_fops = {
689         .owner          = THIS_MODULE,
690         .open           = video_exclusive_open,
691         .release        = video_exclusive_release,
692         .ioctl          = qcam_ioctl,
693         .read           = qcam_read,
694         .llseek         = no_llseek,
695 };
696
697 static struct video_device qcam_template=
698 {
699         .owner          = THIS_MODULE,
700         .name           = "Colour QuickCam",
701         .type           = VID_TYPE_CAPTURE,
702         .hardware       = VID_HARDWARE_QCAM_C,
703         .fops           = &qcam_fops,
704 };
705
706 /* Initialize the QuickCam driver control structure. */
707
708 static struct qcam_device *qcam_init(struct parport *port)
709 {
710         struct qcam_device *q;
711         
712         q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
713         if(q==NULL)
714                 return NULL;
715
716         q->pport = port;
717         q->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
718                                           NULL, 0, NULL);
719
720         q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0;
721
722         if (q->pdev == NULL) 
723         {
724                 printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
725                        port->name);
726                 kfree(q);
727                 return NULL;
728         }
729         
730         memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
731
732         init_MUTEX(&q->lock);
733         q->width = q->ccd_width = 320;
734         q->height = q->ccd_height = 240;
735         q->mode = QC_MILLIONS | QC_DECIMATION_1;
736         q->contrast = 192;
737         q->brightness = 240;
738         q->whitebal = 128;
739         q->top = 1;
740         q->left = 14;
741         return q;
742 }
743
744 static struct qcam_device *qcams[MAX_CAMS];
745 static unsigned int num_cams = 0;
746
747 int init_cqcam(struct parport *port)
748 {
749         struct qcam_device *qcam;
750
751         if (parport[0] != -1)
752         {
753                 /* The user gave specific instructions */
754                 int i, found = 0;
755                 for (i = 0; i < MAX_CAMS && parport[i] != -1; i++)
756                 {
757                         if (parport[0] == port->number)
758                                 found = 1;
759                 }
760                 if (!found)
761                         return -ENODEV;
762         }
763
764         if (num_cams == MAX_CAMS)
765                 return -ENOSPC;
766
767         qcam = qcam_init(port);
768         if (qcam==NULL)
769                 return -ENODEV;
770                 
771         parport_claim_or_block(qcam->pdev);
772
773         qc_reset(qcam);
774         
775         if (probe && qc_detect(qcam)==0)
776         {
777                 parport_release(qcam->pdev);
778                 parport_unregister_device(qcam->pdev);
779                 kfree(qcam);
780                 return -ENODEV;
781         }
782
783         qc_setup(qcam);
784
785         parport_release(qcam->pdev);
786         
787         if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
788         {
789                 printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
790                        qcam->pport->name);
791                 parport_unregister_device(qcam->pdev);
792                 kfree(qcam);
793                 return -ENODEV;
794         }
795
796         printk(KERN_INFO "video%d: Colour QuickCam found on %s\n", 
797                qcam->vdev.minor, qcam->pport->name);
798         
799         qcams[num_cams++] = qcam;
800
801         return 0;
802 }
803
804 void close_cqcam(struct qcam_device *qcam)
805 {
806         video_unregister_device(&qcam->vdev);
807         parport_unregister_device(qcam->pdev);
808         kfree(qcam);
809 }
810
811 static void cq_attach(struct parport *port)
812 {
813         init_cqcam(port);
814 }
815
816 static void cq_detach(struct parport *port)
817 {
818         /* Write this some day. */
819 }
820
821 static struct parport_driver cqcam_driver = {
822         "cqcam",
823         cq_attach,
824         cq_detach,
825         NULL
826 };
827
828 static int __init cqcam_init (void)
829 {
830         printk(BANNER "\n");
831
832         return parport_register_driver(&cqcam_driver);
833 }
834
835 static void __exit cqcam_cleanup (void)
836 {
837         unsigned int i;
838
839         for (i = 0; i < num_cams; i++)
840                 close_cqcam(qcams[i]);
841
842         parport_unregister_driver(&cqcam_driver);
843 }
844
845 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
846 MODULE_DESCRIPTION(BANNER);
847 MODULE_LICENSE("GPL");
848
849 MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\
850 probe=<0|1|2> for camera detection method\n\
851 force_rgb=<0|1> for RGB data format (default BGR)");
852 MODULE_PARM(parport, "1-" __MODULE_STRING(MAX_CAMS) "i");
853 MODULE_PARM(probe, "i");
854 MODULE_PARM(force_rgb, "i");
855 MODULE_PARM(video_nr,"i");
856
857 module_init(cqcam_init);
858 module_exit(cqcam_cleanup);