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