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