>> Btw, I've been looking at why Andrea thinks he's patches are needed,
[davej-history.git] / drivers / char / bw-qcam.c
blob9f8935e8b8147d5e4aea64b1debb7cb9c4f89171
1 /*
2 * QuickCam Driver For Video4Linux.
4 * This version only works as a module.
6 * Video4Linux conversion work by Alan Cox.
7 * Parport compatibility by Phil Blundell.
8 */
10 /* qcam-lib.c -- Library for programming with the Connectix QuickCam.
11 * See the included documentation for usage instructions and details
12 * of the protocol involved. */
15 /* Version 0.5, August 4, 1996 */
16 /* Version 0.7, August 27, 1996 */
17 /* Version 0.9, November 17, 1996 */
20 /******************************************************************
22 Copyright (C) 1996 by Scott Laird
24 Permission is hereby granted, free of charge, to any person obtaining
25 a copy of this software and associated documentation files (the
26 "Software"), to deal in the Software without restriction, including
27 without limitation the rights to use, copy, modify, merge, publish,
28 distribute, sublicense, and/or sell copies of the Software, and to
29 permit persons to whom the Software is furnished to do so, subject to
30 the following conditions:
32 The above copyright notice and this permission notice shall be
33 included in all copies or substantial portions of the Software.
35 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
36 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
38 IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
39 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
40 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41 OTHER DEALINGS IN THE SOFTWARE.
43 ******************************************************************/
45 #include <linux/module.h>
46 #include <linux/delay.h>
47 #include <linux/errno.h>
48 #include <linux/fs.h>
49 #include <linux/init.h>
50 #include <linux/kernel.h>
51 #include <linux/malloc.h>
52 #include <linux/mm.h>
53 #include <linux/parport.h>
54 #include <linux/sched.h>
55 #include <linux/version.h>
56 #include <linux/videodev.h>
57 #include <asm/uaccess.h>
59 #include "bw-qcam.h"
61 extern __inline__ int read_lpstatus(struct qcam_device *q)
63 return parport_read_status(q->pport);
66 extern __inline__ int read_lpcontrol(struct qcam_device *q)
68 return parport_read_control(q->pport);
71 extern __inline__ int read_lpdata(struct qcam_device *q)
73 return parport_read_data(q->pport);
76 extern __inline__ void write_lpdata(struct qcam_device *q, int d)
78 parport_write_data(q->pport, d);
81 extern __inline__ void write_lpcontrol(struct qcam_device *q, int d)
83 parport_write_control(q->pport, d);
86 static int qc_waithand(struct qcam_device *q, int val);
87 static int qc_command(struct qcam_device *q, int command);
88 static int qc_readparam(struct qcam_device *q);
89 static int qc_setscanmode(struct qcam_device *q);
90 static int qc_readbytes(struct qcam_device *q, char buffer[]);
92 static struct video_device qcam_template;
94 static int qc_calibrate(struct qcam_device *q)
97 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
98 * The white balance is an individiual value for each
99 * quickcam.
102 int value;
103 int count = 0;
105 qc_command(q, 27); /* AutoAdjustOffset */
106 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
108 /* GetOffset (33) will read 255 until autocalibration */
109 /* is finished. After that, a value of 1-254 will be */
110 /* returned. */
112 do {
113 qc_command(q, 33);
114 value = qc_readparam(q);
115 mdelay(1);
116 schedule();
117 count++;
118 } while (value == 0xff && count<2048);
120 q->whitebal = value;
121 return value;
124 /* Initialize the QuickCam driver control structure. This is where
125 * defaults are set for people who don't have a config file.*/
127 static struct qcam_device *qcam_init(struct parport *port)
129 struct qcam_device *q;
131 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
133 q->pport = port;
134 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
135 NULL, 0, NULL);
136 if (q->pdev == NULL)
138 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
139 port->name);
140 kfree(q);
141 return NULL;
144 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
146 q->port_mode = (QC_ANY | QC_NOTSET);
147 q->width = 320;
148 q->height = 240;
149 q->bpp = 4;
150 q->transfer_scale = 2;
151 q->contrast = 192;
152 q->brightness = 180;
153 q->whitebal = 105;
154 q->top = 1;
155 q->left = 14;
156 q->mode = -1;
157 return q;
161 /* qc_command is probably a bit of a misnomer -- it's used to send
162 * bytes *to* the camera. Generally, these bytes are either commands
163 * or arguments to commands, so the name fits, but it still bugs me a
164 * bit. See the documentation for a list of commands. */
166 static int qc_command(struct qcam_device *q, int command)
168 int n1, n2;
169 int cmd;
171 write_lpdata(q, command);
172 write_lpcontrol(q, 6);
174 n1 = qc_waithand(q, 1);
176 write_lpcontrol(q, 0xe);
177 n2 = qc_waithand(q, 0);
179 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
180 return cmd;
183 static int qc_readparam(struct qcam_device *q)
185 int n1, n2;
186 int cmd;
188 write_lpcontrol(q, 6);
189 n1 = qc_waithand(q, 1);
191 write_lpcontrol(q, 0xe);
192 n2 = qc_waithand(q, 0);
194 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
195 return cmd;
198 /* qc_waithand busy-waits for a handshake signal from the QuickCam.
199 * Almost all communication with the camera requires handshaking. */
201 static int qc_waithand(struct qcam_device *q, int val)
203 int status;
204 int runs=0;
206 if (val)
208 while (!((status = read_lpstatus(q)) & 8))
210 /* 1000 is enough spins on the I/O for all normal
211 cases, at that point we start to poll slowly
212 until the camera wakes up */
214 if(runs++>1000)
216 current->state=TASK_INTERRUPTIBLE;
217 schedule_timeout(HZ/10);
219 if(runs>1050)
220 return -1;
223 else
225 while (((status = read_lpstatus(q)) & 8))
227 /* 1000 is enough spins on the I/O for all normal
228 cases, at that point we start to poll slowly
229 until the camera wakes up */
231 if(runs++>1000)
233 current->state=TASK_INTERRUPTIBLE;
234 schedule_timeout(HZ/10);
236 if(runs++>1050) /* 5 seconds */
237 return -1;
241 return status;
244 /* Waithand2 is used when the qcam is in bidirectional mode, and the
245 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
246 * (bit 3 of status register). It also returns the last value read,
247 * since this data is useful. */
249 static unsigned int qc_waithand2(struct qcam_device *q, int val)
251 unsigned int status;
252 int runs=0;
256 status = read_lpdata(q);
257 /* 1000 is enough spins on the I/O for all normal
258 cases, at that point we start to poll slowly
259 until the camera wakes up */
261 if(runs++>1000)
263 current->state=TASK_INTERRUPTIBLE;
264 schedule_timeout(HZ/10);
266 if(runs++>1050) /* 5 seconds */
267 return 0;
269 while ((status & 1) != val);
271 return status;
275 /* Try to detect a QuickCam. It appears to flash the upper 4 bits of
276 the status register at 5-10 Hz. This is only used in the autoprobe
277 code. Be aware that this isn't the way Connectix detects the
278 camera (they send a reset and try to handshake), but this should be
279 almost completely safe, while their method screws up my printer if
280 I plug it in before the camera. */
282 static int qc_detect(struct qcam_device *q)
284 int reg, lastreg;
285 int count = 0;
286 int i;
288 lastreg = reg = read_lpstatus(q) & 0xf0;
290 for (i = 0; i < 300; i++)
292 reg = read_lpstatus(q) & 0xf0;
293 if (reg != lastreg)
294 count++;
295 lastreg = reg;
296 mdelay(2);
299 /* Be liberal in what you accept... */
301 if (count > 30 && count < 200)
302 return 1; /* found */
303 else
304 return 0; /* not found */
308 /* Reset the QuickCam. This uses the same sequence the Windows
309 * QuickPic program uses. Someone with a bi-directional port should
310 * check that bi-directional mode is detected right, and then
311 * implement bi-directional mode in qc_readbyte(). */
313 static void qc_reset(struct qcam_device *q)
315 switch (q->port_mode & QC_FORCE_MASK)
317 case QC_FORCE_UNIDIR:
318 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
319 break;
321 case QC_FORCE_BIDIR:
322 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
323 break;
325 case QC_ANY:
326 write_lpcontrol(q, 0x20);
327 write_lpdata(q, 0x75);
329 if (read_lpdata(q) != 0x75) {
330 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
331 } else {
332 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
334 break;
337 write_lpcontrol(q, 0xb);
338 udelay(250);
339 write_lpcontrol(q, 0xe);
340 qc_setscanmode(q); /* in case port_mode changed */
344 /* Decide which scan mode to use. There's no real requirement that
345 * the scanmode match the resolution in q->height and q-> width -- the
346 * camera takes the picture at the resolution specified in the
347 * "scanmode" and then returns the image at the resolution specified
348 * with the resolution commands. If the scan is bigger than the
349 * requested resolution, the upper-left hand corner of the scan is
350 * returned. If the scan is smaller, then the rest of the image
351 * returned contains garbage. */
353 static int qc_setscanmode(struct qcam_device *q)
355 switch (q->transfer_scale)
357 case 1:
358 q->mode = 0;
359 break;
360 case 2:
361 q->mode = 4;
362 break;
363 case 4:
364 q->mode = 8;
365 break;
368 switch (q->bpp)
370 case 4:
371 break;
372 case 6:
373 q->mode += 2;
374 break;
377 switch (q->port_mode & QC_MODE_MASK)
379 case QC_BIDIR:
380 q->mode += 1;
381 break;
382 case QC_NOTSET:
383 case QC_UNIDIR:
384 break;
386 return 0;
390 /* Reset the QuickCam and program for brightness, contrast,
391 * white-balance, and resolution. */
393 void qc_set(struct qcam_device *q)
395 int val;
396 int val2;
398 qc_reset(q);
400 /* Set the brightness. Yes, this is repetitive, but it works.
401 * Shorter versions seem to fail subtly. Feel free to try :-). */
402 /* I think the problem was in qc_command, not here -- bls */
404 qc_command(q, 0xb);
405 qc_command(q, q->brightness);
407 val = q->height / q->transfer_scale;
408 qc_command(q, 0x11);
409 qc_command(q, val);
410 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
411 /* The normal "transfers per line" calculation doesn't seem to work
412 as expected here (and yet it works fine in qc_scan). No idea
413 why this case is the odd man out. Fortunately, Laird's original
414 working version gives me a good way to guess at working values.
415 -- bls */
416 val = q->width;
417 val2 = q->transfer_scale * 4;
418 } else {
419 val = q->width * q->bpp;
420 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
421 q->transfer_scale;
423 val = (val + val2 - 1) / val2;
424 qc_command(q, 0x13);
425 qc_command(q, val);
427 /* Setting top and left -- bls */
428 qc_command(q, 0xd);
429 qc_command(q, q->top);
430 qc_command(q, 0xf);
431 qc_command(q, q->left / 2);
433 qc_command(q, 0x19);
434 qc_command(q, q->contrast);
435 qc_command(q, 0x1f);
436 qc_command(q, q->whitebal);
440 /* Qc_readbytes reads some bytes from the QC and puts them in
441 the supplied buffer. It returns the number of bytes read,
442 or -1 on error. */
444 extern __inline__ int qc_readbytes(struct qcam_device *q, char buffer[])
446 int ret=1;
447 unsigned int hi, lo;
448 unsigned int hi2, lo2;
449 static int state = 0;
451 if (buffer == NULL)
453 state = 0;
454 return 0;
457 switch (q->port_mode & QC_MODE_MASK)
459 case QC_BIDIR: /* Bi-directional Port */
460 write_lpcontrol(q, 0x26);
461 lo = (qc_waithand2(q, 1) >> 1);
462 hi = (read_lpstatus(q) >> 3) & 0x1f;
463 write_lpcontrol(q, 0x2e);
464 lo2 = (qc_waithand2(q, 0) >> 1);
465 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
466 switch (q->bpp)
468 case 4:
469 buffer[0] = lo & 0xf;
470 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
471 buffer[2] = (hi & 0x1e) >> 1;
472 buffer[3] = lo2 & 0xf;
473 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
474 buffer[5] = (hi2 & 0x1e) >> 1;
475 ret = 6;
476 break;
477 case 6:
478 buffer[0] = lo & 0x3f;
479 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
480 buffer[2] = lo2 & 0x3f;
481 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
482 ret = 4;
483 break;
485 break;
487 case QC_UNIDIR: /* Unidirectional Port */
488 write_lpcontrol(q, 6);
489 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
490 write_lpcontrol(q, 0xe);
491 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
493 switch (q->bpp)
495 case 4:
496 buffer[0] = lo;
497 buffer[1] = hi;
498 ret = 2;
499 break;
500 case 6:
501 switch (state)
503 case 0:
504 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
505 q->saved_bits = (hi & 3) << 4;
506 state = 1;
507 ret = 1;
508 break;
509 case 1:
510 buffer[0] = lo | q->saved_bits;
511 q->saved_bits = hi << 2;
512 state = 2;
513 ret = 1;
514 break;
515 case 2:
516 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
517 buffer[1] = ((lo & 3) << 4) | hi;
518 state = 0;
519 ret = 2;
520 break;
522 break;
524 break;
526 return ret;
529 /* requests a scan from the camera. It sends the correct instructions
530 * to the camera and then reads back the correct number of bytes. In
531 * previous versions of this routine the return structure contained
532 * the raw output from the camera, and there was a 'qc_convertscan'
533 * function that converted that to a useful format. In version 0.3 I
534 * rolled qc_convertscan into qc_scan and now I only return the
535 * converted scan. The format is just an one-dimensional array of
536 * characters, one for each pixel, with 0=black up to n=white, where
537 * n=2^(bit depth)-1. Ask me for more details if you don't understand
538 * this. */
540 long qc_capture(struct qcam_device * q, char *buf, unsigned long len)
542 int i, j, k;
543 int bytes;
544 int linestotrans, transperline;
545 int divisor;
546 int pixels_per_line;
547 int pixels_read = 0;
548 int got=0;
549 char buffer[6];
550 int shift=8-q->bpp;
551 char invert;
553 if (q->mode == -1)
554 return -ENXIO;
556 qc_command(q, 0x7);
557 qc_command(q, q->mode);
559 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
561 write_lpcontrol(q, 0x2e); /* turn port around */
562 write_lpcontrol(q, 0x26);
563 (void) qc_waithand(q, 1);
564 write_lpcontrol(q, 0x2e);
565 (void) qc_waithand(q, 0);
568 /* strange -- should be 15:63 below, but 4bpp is odd */
569 invert = (q->bpp == 4) ? 16 : 63;
571 linestotrans = q->height / q->transfer_scale;
572 pixels_per_line = q->width / q->transfer_scale;
573 transperline = q->width * q->bpp;
574 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
575 q->transfer_scale;
576 transperline = (transperline + divisor - 1) / divisor;
578 for (i = 0; i < linestotrans; i++)
580 for (pixels_read = j = 0; j < transperline; j++)
582 bytes = qc_readbytes(q, buffer);
583 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++)
585 int o;
586 if (buffer[k] == 0 && invert == 16)
588 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
589 must be 0-15 -- bls */
590 buffer[k] = 16;
592 o=i*pixels_per_line + pixels_read + k;
593 if(o<len)
595 got++;
596 put_user((invert - buffer[k])<<shift, buf+o);
599 pixels_read += bytes;
601 (void) qc_readbytes(q, 0); /* reset state machine */
604 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
606 write_lpcontrol(q, 2);
607 write_lpcontrol(q, 6);
608 udelay(3);
609 write_lpcontrol(q, 0xe);
611 if(got<len)
612 return got;
613 return len;
617 * Video4linux interfacing
620 static int qcam_open(struct video_device *dev, int flags)
622 MOD_INC_USE_COUNT;
623 return 0;
626 static void qcam_close(struct video_device *dev)
628 MOD_DEC_USE_COUNT;
631 static int qcam_init_done(struct video_device *dev)
633 return 0;
636 static long qcam_write(struct video_device *v, const char *buf, unsigned long count, int noblock)
638 return -EINVAL;
641 static int qcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
643 struct qcam_device *qcam=(struct qcam_device *)dev;
645 switch(cmd)
647 case VIDIOCGCAP:
649 struct video_capability b;
650 strcpy(b.name, "Quickcam");
651 b.type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
652 b.channels = 1;
653 b.audios = 0;
654 b.maxwidth = 320;
655 b.maxheight = 240;
656 b.minwidth = 80;
657 b.minheight = 60;
658 if(copy_to_user(arg, &b,sizeof(b)))
659 return -EFAULT;
660 return 0;
662 case VIDIOCGCHAN:
664 struct video_channel v;
665 if(copy_from_user(&v, arg, sizeof(v)))
666 return -EFAULT;
667 if(v.channel!=0)
668 return -EINVAL;
669 v.flags=0;
670 v.tuners=0;
671 /* Good question.. its composite or SVHS so.. */
672 v.type = VIDEO_TYPE_CAMERA;
673 strcpy(v.name, "Camera");
674 if(copy_to_user(arg, &v, sizeof(v)))
675 return -EFAULT;
676 return 0;
678 case VIDIOCSCHAN:
680 int v;
681 if(copy_from_user(&v, arg,sizeof(v)))
682 return -EFAULT;
683 if(v!=0)
684 return -EINVAL;
685 return 0;
687 case VIDIOCGTUNER:
689 struct video_tuner v;
690 if(copy_from_user(&v, arg, sizeof(v))!=0)
691 return -EFAULT;
692 if(v.tuner)
693 return -EINVAL;
694 strcpy(v.name, "Format");
695 v.rangelow=0;
696 v.rangehigh=0;
697 v.flags= 0;
698 v.mode = VIDEO_MODE_AUTO;
699 if(copy_to_user(arg,&v,sizeof(v))!=0)
700 return -EFAULT;
701 return 0;
703 case VIDIOCSTUNER:
705 struct video_tuner v;
706 if(copy_from_user(&v, arg, sizeof(v))!=0)
707 return -EFAULT;
708 if(v.tuner)
709 return -EINVAL;
710 if(v.mode!=VIDEO_MODE_AUTO)
711 return -EINVAL;
712 return 0;
714 case VIDIOCGPICT:
716 struct video_picture p;
717 p.colour=0x8000;
718 p.hue=0x8000;
719 p.brightness=qcam->brightness<<8;
720 p.contrast=qcam->contrast<<8;
721 p.whiteness=qcam->whitebal<<8;
722 p.depth=qcam->bpp;
723 p.palette=VIDEO_PALETTE_GREY;
724 if(copy_to_user(arg, &p, sizeof(p)))
725 return -EFAULT;
726 return 0;
728 case VIDIOCSPICT:
730 struct video_picture p;
731 if(copy_from_user(&p, arg, sizeof(p)))
732 return -EFAULT;
733 if(p.palette!=VIDEO_PALETTE_GREY)
734 return -EINVAL;
735 if(p.depth!=4 && p.depth!=6)
736 return -EINVAL;
739 * Now load the camera.
742 qcam->brightness = p.brightness>>8;
743 qcam->contrast = p.contrast>>8;
744 qcam->whitebal = p.whiteness>>8;
745 qcam->bpp = p.depth;
747 qc_setscanmode(qcam);
748 parport_claim_or_block(qcam->pdev);
749 qc_set(qcam);
750 parport_release(qcam->pdev);
751 return 0;
753 case VIDIOCSWIN:
755 struct video_window vw;
756 if(copy_from_user(&vw, arg,sizeof(vw)))
757 return -EFAULT;
758 if(vw.flags)
759 return -EINVAL;
760 if(vw.clipcount)
761 return -EINVAL;
762 if(vw.height<60||vw.height>240)
763 return -EINVAL;
764 if(vw.width<80||vw.width>320)
765 return -EINVAL;
767 qcam->width = 320;
768 qcam->height = 240;
769 qcam->transfer_scale = 4;
771 if(vw.width>=160 && vw.height>=120)
773 qcam->transfer_scale = 2;
775 if(vw.width>=320 && vw.height>=240)
777 qcam->width = 320;
778 qcam->height = 240;
779 qcam->transfer_scale = 1;
781 qc_setscanmode(qcam);
782 /* Ok we figured out what to use from our wide choice */
783 return 0;
785 case VIDIOCGWIN:
787 struct video_window vw;
788 vw.x=0;
789 vw.y=0;
790 vw.width=qcam->width/qcam->transfer_scale;
791 vw.height=qcam->height/qcam->transfer_scale;
792 vw.chromakey=0;
793 vw.flags=0;
794 if(copy_to_user(arg, &vw, sizeof(vw)))
795 return -EFAULT;
796 return 0;
798 case VIDIOCCAPTURE:
799 return -EINVAL;
800 case VIDIOCGFBUF:
801 return -EINVAL;
802 case VIDIOCSFBUF:
803 return -EINVAL;
804 case VIDIOCKEY:
805 return 0;
806 case VIDIOCGFREQ:
807 return -EINVAL;
808 case VIDIOCSFREQ:
809 return -EINVAL;
810 case VIDIOCGAUDIO:
811 return -EINVAL;
812 case VIDIOCSAUDIO:
813 return -EINVAL;
814 default:
815 return -ENOIOCTLCMD;
817 return 0;
820 static long qcam_read(struct video_device *v, char *buf, unsigned long count, int noblock)
822 struct qcam_device *qcam=(struct qcam_device *)v;
823 int len;
824 parport_claim_or_block(qcam->pdev);
825 /* Probably should have a semaphore against multiple users */
826 qc_reset(qcam);
827 len=qc_capture(qcam, buf,count);
828 parport_release(qcam->pdev);
829 return len;
833 static struct video_device qcam_template=
835 "Connectix Quickcam",
836 VID_TYPE_CAPTURE,
837 VID_HARDWARE_QCAM_BW,
838 qcam_open,
839 qcam_close,
840 qcam_read,
841 qcam_write,
842 NULL,
843 qcam_ioctl,
844 NULL,
845 qcam_init_done,
846 NULL,
851 #define MAX_CAMS 4
852 static struct qcam_device *qcams[MAX_CAMS];
853 static unsigned int num_cams = 0;
855 int init_bwqcam(struct parport *port)
857 struct qcam_device *qcam;
859 if (num_cams == MAX_CAMS)
861 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
862 return -ENOSPC;
865 qcam=qcam_init(port);
866 if(qcam==NULL)
867 return -ENODEV;
869 parport_claim_or_block(qcam->pdev);
871 qc_reset(qcam);
873 if(qc_detect(qcam)==0)
875 parport_release(qcam->pdev);
876 parport_unregister_device(qcam->pdev);
877 kfree(qcam);
878 return -ENODEV;
880 qc_calibrate(qcam);
882 parport_release(qcam->pdev);
884 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
886 if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER)==-1)
888 parport_unregister_device(qcam->pdev);
889 kfree(qcam);
890 return -ENODEV;
893 qcams[num_cams++] = qcam;
895 return 0;
898 void close_bwqcam(struct qcam_device *qcam)
900 video_unregister_device(&qcam->vdev);
901 parport_unregister_device(qcam->pdev);
902 kfree(qcam);
905 #ifdef MODULE
906 int init_module(void)
908 struct parport *port;
910 for (port = parport_enumerate(); port; port=port->next)
911 init_bwqcam(port);
913 return (num_cams)?0:-ENODEV;
916 void cleanup_module(void)
918 unsigned int i;
919 for (i = 0; i < num_cams; i++)
920 close_bwqcam(qcams[i]);
922 #else
923 __initfunc(int init_bw_qcams(struct video_init *unused))
925 struct parport *port;
927 for (port = parport_enumerate(); port; port=port->next)
928 init_bwqcam(port);
929 return 0;
931 #endif