Import 2.1.81
[davej-history.git] / drivers / char / bw-qcam.c
blob0ba7df6b7edca74d4930759272c8ef176ba21fd5
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/config.h>
47 #include <linux/delay.h>
48 #include <linux/errno.h>
49 #include <linux/fs.h>
50 #include <linux/init.h>
51 #include <linux/kernel.h>
52 #include <linux/malloc.h>
53 #include <linux/mm.h>
54 #include <linux/parport.h>
55 #include <linux/sched.h>
56 #include <linux/version.h>
57 #include <linux/videodev.h>
58 #include <asm/uaccess.h>
60 #include "bw-qcam.h"
62 extern __inline__ int read_lpstatus(struct qcam_device *q)
64 return parport_read_status(q->pport);
67 extern __inline__ int read_lpcontrol(struct qcam_device *q)
69 return parport_read_control(q->pport);
72 extern __inline__ int read_lpdata(struct qcam_device *q)
74 return parport_read_data(q->pport);
77 extern __inline__ void write_lpdata(struct qcam_device *q, int d)
79 parport_write_data(q->pport, d);
82 extern __inline__ void write_lpcontrol(struct qcam_device *q, int d)
84 parport_write_control(q->pport, d);
87 static int qc_waithand(struct qcam_device *q, int val);
88 static int qc_command(struct qcam_device *q, int command);
89 static int qc_readparam(struct qcam_device *q);
90 static int qc_setscanmode(struct qcam_device *q);
91 static int qc_readbytes(struct qcam_device *q, char buffer[]);
93 static struct video_device qcam_template;
95 static int qc_calibrate(struct qcam_device *q)
98 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
99 * The white balance is an individiual value for each
100 * quickcam.
103 int value;
104 int count = 0;
106 qc_command(q, 27); /* AutoAdjustOffset */
107 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
109 /* GetOffset (33) will read 255 until autocalibration */
110 /* is finished. After that, a value of 1-254 will be */
111 /* returned. */
113 do {
114 qc_command(q, 33);
115 value = qc_readparam(q);
116 udelay(1000);
117 schedule();
118 count++;
119 } while (value == 0xff && count<2048);
121 q->whitebal = value;
122 return value;
125 /* Initialize the QuickCam driver control structure. This is where
126 * defaults are set for people who don't have a config file.*/
128 static struct qcam_device *qcam_init(struct parport *port)
130 struct qcam_device *q;
132 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
134 q->pport = port;
135 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
136 NULL, 0, NULL);
137 if (q->pdev == NULL)
139 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
140 port->name);
141 kfree(q);
142 return NULL;
145 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
147 q->port_mode = (QC_ANY | QC_NOTSET);
148 q->width = 320;
149 q->height = 240;
150 q->bpp = 4;
151 q->transfer_scale = 2;
152 q->contrast = 192;
153 q->brightness = 180;
154 q->whitebal = 105;
155 q->top = 1;
156 q->left = 14;
157 q->mode = -1;
158 return q;
162 /* qc_command is probably a bit of a misnomer -- it's used to send
163 * bytes *to* the camera. Generally, these bytes are either commands
164 * or arguments to commands, so the name fits, but it still bugs me a
165 * bit. See the documentation for a list of commands. */
167 static int qc_command(struct qcam_device *q, int command)
169 int n1, n2;
170 int cmd;
172 write_lpdata(q, command);
173 write_lpcontrol(q, 6);
175 n1 = qc_waithand(q, 1);
177 write_lpcontrol(q, 0xe);
178 n2 = qc_waithand(q, 0);
180 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
181 return cmd;
184 static int qc_readparam(struct qcam_device *q)
186 int n1, n2;
187 int cmd;
189 write_lpcontrol(q, 6);
190 n1 = qc_waithand(q, 1);
192 write_lpcontrol(q, 0xe);
193 n2 = qc_waithand(q, 0);
195 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
196 return cmd;
199 /* qc_waithand busy-waits for a handshake signal from the QuickCam.
200 * Almost all communication with the camera requires handshaking. */
202 static int qc_waithand(struct qcam_device *q, int val)
204 int status;
205 int runs=0;
207 if (val)
209 while (!((status = read_lpstatus(q)) & 8))
211 /* 1000 is enough spins on the I/O for all normal
212 cases, at that point we start to poll slowly
213 until the camera wakes up */
215 if(runs++>1000)
217 current->state=TASK_INTERRUPTIBLE;
218 current->timeout = jiffies+HZ/10;
219 schedule();
221 if(runs>1050)
222 return -1;
225 else
227 while (((status = read_lpstatus(q)) & 8))
229 /* 1000 is enough spins on the I/O for all normal
230 cases, at that point we start to poll slowly
231 until the camera wakes up */
233 if(runs++>1000)
235 current->state=TASK_INTERRUPTIBLE;
236 current->timeout = jiffies+HZ/10;
237 schedule();
239 if(runs++>1050) /* 5 seconds */
240 return -1;
244 return status;
247 /* Waithand2 is used when the qcam is in bidirectional mode, and the
248 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
249 * (bit 3 of status register). It also returns the last value read,
250 * since this data is useful. */
252 static unsigned int qc_waithand2(struct qcam_device *q, int val)
254 unsigned int status;
255 int runs=0;
259 status = read_lpdata(q);
260 /* 1000 is enough spins on the I/O for all normal
261 cases, at that point we start to poll slowly
262 until the camera wakes up */
264 if(runs++>1000)
266 current->state=TASK_INTERRUPTIBLE;
267 current->timeout = jiffies+HZ/10;
268 schedule();
270 if(runs++>1050) /* 5 seconds */
271 return 0;
273 while ((status & 1) != val);
275 return status;
279 /* Try to detect a QuickCam. It appears to flash the upper 4 bits of
280 the status register at 5-10 Hz. This is only used in the autoprobe
281 code. Be aware that this isn't the way Connectix detects the
282 camera (they send a reset and try to handshake), but this should be
283 almost completely safe, while their method screws up my printer if
284 I plug it in before the camera. */
286 static int qc_detect(struct qcam_device *q)
288 int reg, lastreg;
289 int count = 0;
290 int i;
292 lastreg = reg = read_lpstatus(q) & 0xf0;
294 for (i = 0; i < 300; i++)
296 reg = read_lpstatus(q) & 0xf0;
297 if (reg != lastreg)
298 count++;
299 lastreg = reg;
300 udelay(1000);
303 /* Be liberal in what you accept... */
305 if (count > 30 && count < 200)
306 return 1; /* found */
307 else
308 return 0; /* not found */
312 /* Reset the QuickCam. This uses the same sequence the Windows
313 * QuickPic program uses. Someone with a bi-directional port should
314 * check that bi-directional mode is detected right, and then
315 * implement bi-directional mode in qc_readbyte(). */
317 static void qc_reset(struct qcam_device *q)
319 switch (q->port_mode & QC_FORCE_MASK)
321 case QC_FORCE_UNIDIR:
322 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
323 break;
325 case QC_FORCE_BIDIR:
326 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
327 break;
329 case QC_ANY:
330 write_lpcontrol(q, 0x20);
331 write_lpdata(q, 0x75);
333 if (read_lpdata(q) != 0x75) {
334 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
335 } else {
336 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
338 break;
341 write_lpcontrol(q, 0xb);
342 udelay(250);
343 write_lpcontrol(q, 0xe);
344 qc_setscanmode(q); /* in case port_mode changed */
348 /* Decide which scan mode to use. There's no real requirement that
349 * the scanmode match the resolution in q->height and q-> width -- the
350 * camera takes the picture at the resolution specified in the
351 * "scanmode" and then returns the image at the resolution specified
352 * with the resolution commands. If the scan is bigger than the
353 * requested resolution, the upper-left hand corner of the scan is
354 * returned. If the scan is smaller, then the rest of the image
355 * returned contains garbage. */
357 static int qc_setscanmode(struct qcam_device *q)
359 switch (q->transfer_scale)
361 case 1:
362 q->mode = 0;
363 break;
364 case 2:
365 q->mode = 4;
366 break;
367 case 4:
368 q->mode = 8;
369 break;
372 switch (q->bpp)
374 case 4:
375 break;
376 case 6:
377 q->mode += 2;
378 break;
381 switch (q->port_mode & QC_MODE_MASK)
383 case QC_BIDIR:
384 q->mode += 1;
385 break;
386 case QC_NOTSET:
387 case QC_UNIDIR:
388 break;
390 return 0;
394 /* Reset the QuickCam and program for brightness, contrast,
395 * white-balance, and resolution. */
397 void qc_set(struct qcam_device *q)
399 int val;
400 int val2;
402 qc_reset(q);
404 /* Set the brightness. Yes, this is repetitive, but it works.
405 * Shorter versions seem to fail subtly. Feel free to try :-). */
406 /* I think the problem was in qc_command, not here -- bls */
408 qc_command(q, 0xb);
409 qc_command(q, q->brightness);
411 val = q->height / q->transfer_scale;
412 qc_command(q, 0x11);
413 qc_command(q, val);
414 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
415 /* The normal "transfers per line" calculation doesn't seem to work
416 as expected here (and yet it works fine in qc_scan). No idea
417 why this case is the odd man out. Fortunately, Laird's original
418 working version gives me a good way to guess at working values.
419 -- bls */
420 val = q->width;
421 val2 = q->transfer_scale * 4;
422 } else {
423 val = q->width * q->bpp;
424 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
425 q->transfer_scale;
427 val = (val + val2 - 1) / val2;
428 qc_command(q, 0x13);
429 qc_command(q, val);
431 /* Setting top and left -- bls */
432 qc_command(q, 0xd);
433 qc_command(q, q->top);
434 qc_command(q, 0xf);
435 qc_command(q, q->left / 2);
437 qc_command(q, 0x19);
438 qc_command(q, q->contrast);
439 qc_command(q, 0x1f);
440 qc_command(q, q->whitebal);
444 /* Qc_readbytes reads some bytes from the QC and puts them in
445 the supplied buffer. It returns the number of bytes read,
446 or -1 on error. */
448 extern __inline__ int qc_readbytes(struct qcam_device *q, char buffer[])
450 int ret=1;
451 unsigned int hi, lo;
452 unsigned int hi2, lo2;
453 static int state = 0;
455 if (buffer == NULL)
457 state = 0;
458 return 0;
461 switch (q->port_mode & QC_MODE_MASK)
463 case QC_BIDIR: /* Bi-directional Port */
464 write_lpcontrol(q, 0x26);
465 lo = (qc_waithand2(q, 1) >> 1);
466 hi = (read_lpstatus(q) >> 3) & 0x1f;
467 write_lpcontrol(q, 0x2e);
468 lo2 = (qc_waithand2(q, 0) >> 1);
469 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
470 switch (q->bpp)
472 case 4:
473 buffer[0] = lo & 0xf;
474 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
475 buffer[2] = (hi & 0x1e) >> 1;
476 buffer[3] = lo2 & 0xf;
477 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
478 buffer[5] = (hi2 & 0x1e) >> 1;
479 ret = 6;
480 break;
481 case 6:
482 buffer[0] = lo & 0x3f;
483 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
484 buffer[2] = lo2 & 0x3f;
485 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
486 ret = 4;
487 break;
489 break;
491 case QC_UNIDIR: /* Unidirectional Port */
492 write_lpcontrol(q, 6);
493 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
494 write_lpcontrol(q, 0xe);
495 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
497 switch (q->bpp)
499 case 4:
500 buffer[0] = lo;
501 buffer[1] = hi;
502 ret = 2;
503 break;
504 case 6:
505 switch (state)
507 case 0:
508 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
509 q->saved_bits = (hi & 3) << 4;
510 state = 1;
511 ret = 1;
512 break;
513 case 1:
514 buffer[0] = lo | q->saved_bits;
515 q->saved_bits = hi << 2;
516 state = 2;
517 ret = 1;
518 break;
519 case 2:
520 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
521 buffer[1] = ((lo & 3) << 4) | hi;
522 state = 0;
523 ret = 2;
524 break;
526 break;
528 break;
530 return ret;
533 /* requests a scan from the camera. It sends the correct instructions
534 * to the camera and then reads back the correct number of bytes. In
535 * previous versions of this routine the return structure contained
536 * the raw output from the camera, and there was a 'qc_convertscan'
537 * function that converted that to a useful format. In version 0.3 I
538 * rolled qc_convertscan into qc_scan and now I only return the
539 * converted scan. The format is just an one-dimensional array of
540 * characters, one for each pixel, with 0=black up to n=white, where
541 * n=2^(bit depth)-1. Ask me for more details if you don't understand
542 * this. */
544 long qc_capture(struct qcam_device * q, char *buf, unsigned long len)
546 int i, j, k;
547 int bytes;
548 int linestotrans, transperline;
549 int divisor;
550 int pixels_per_line;
551 int pixels_read = 0;
552 int got=0;
553 char buffer[6];
554 int shift=8-q->bpp;
555 char invert;
557 if (q->mode == -1)
558 return -ENXIO;
560 qc_command(q, 0x7);
561 qc_command(q, q->mode);
563 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
565 write_lpcontrol(q, 0x2e); /* turn port around */
566 write_lpcontrol(q, 0x26);
567 (void) qc_waithand(q, 1);
568 write_lpcontrol(q, 0x2e);
569 (void) qc_waithand(q, 0);
572 /* strange -- should be 15:63 below, but 4bpp is odd */
573 invert = (q->bpp == 4) ? 16 : 63;
575 linestotrans = q->height / q->transfer_scale;
576 pixels_per_line = q->width / q->transfer_scale;
577 transperline = q->width * q->bpp;
578 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
579 q->transfer_scale;
580 transperline = (transperline + divisor - 1) / divisor;
582 for (i = 0; i < linestotrans; i++)
584 for (pixels_read = j = 0; j < transperline; j++)
586 bytes = qc_readbytes(q, buffer);
587 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++)
589 int o;
590 if (buffer[k] == 0 && invert == 16)
592 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
593 must be 0-15 -- bls */
594 buffer[k] = 16;
596 o=i*pixels_per_line + pixels_read + k;
597 if(o<len)
599 got++;
600 put_user((invert - buffer[k])<<shift, buf+o);
603 pixels_read += bytes;
605 (void) qc_readbytes(q, 0); /* reset state machine */
608 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
610 write_lpcontrol(q, 2);
611 write_lpcontrol(q, 6);
612 udelay(3);
613 write_lpcontrol(q, 0xe);
615 if(got<len)
616 return got;
617 return len;
621 * Video4linux interfacing
624 static int qcam_open(struct video_device *dev, int flags)
626 MOD_INC_USE_COUNT;
627 return 0;
630 static void qcam_close(struct video_device *dev)
632 MOD_DEC_USE_COUNT;
635 static int qcam_init_done(struct video_device *dev)
637 return 0;
640 static long qcam_write(struct video_device *v, const char *buf, unsigned long count, int noblock)
642 return -EINVAL;
645 static int qcam_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
647 struct qcam_device *qcam=(struct qcam_device *)dev;
649 switch(cmd)
651 case VIDIOCGCAP:
653 struct video_capability b;
654 strcpy(b.name, "Quickcam");
655 b.type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
656 b.channels = 1;
657 b.audios = 0;
658 b.maxwidth = 320;
659 b.maxheight = 240;
660 b.minwidth = 80;
661 b.minheight = 60;
662 if(copy_to_user(arg, &b,sizeof(b)))
663 return -EFAULT;
664 return 0;
666 case VIDIOCGCHAN:
668 struct video_channel v;
669 if(copy_from_user(&v, arg, sizeof(v)))
670 return -EFAULT;
671 if(v.channel!=0)
672 return -EINVAL;
673 v.flags=0;
674 v.tuners=0;
675 /* Good question.. its composite or SVHS so.. */
676 v.type = VIDEO_TYPE_CAMERA;
677 strcpy(v.name, "Camera");
678 if(copy_to_user(arg, &v, sizeof(v)))
679 return -EFAULT;
680 return 0;
682 case VIDIOCSCHAN:
684 int v;
685 if(copy_from_user(&v, arg,sizeof(v)))
686 return -EFAULT;
687 if(v!=0)
688 return -EINVAL;
689 return 0;
691 case VIDIOCGTUNER:
693 struct video_tuner v;
694 if(copy_from_user(&v, arg, sizeof(v))!=0)
695 return -EFAULT;
696 if(v.tuner)
697 return -EINVAL;
698 strcpy(v.name, "Format");
699 v.rangelow=0;
700 v.rangehigh=0;
701 v.flags= 0;
702 v.mode = VIDEO_MODE_AUTO;
703 if(copy_to_user(arg,&v,sizeof(v))!=0)
704 return -EFAULT;
705 return 0;
707 case VIDIOCSTUNER:
709 struct video_tuner v;
710 if(copy_from_user(&v, arg, sizeof(v))!=0)
711 return -EFAULT;
712 if(v.tuner)
713 return -EINVAL;
714 if(v.mode!=VIDEO_MODE_AUTO)
715 return -EINVAL;
716 return 0;
718 case VIDIOCGPICT:
720 struct video_picture p;
721 p.colour=0x8000;
722 p.hue=0x8000;
723 p.brightness=qcam->brightness<<8;
724 p.contrast=qcam->contrast<<8;
725 p.whiteness=qcam->whitebal<<8;
726 p.depth=qcam->bpp;
727 p.palette=VIDEO_PALETTE_GREY;
728 if(copy_to_user(arg, &p, sizeof(p)))
729 return -EFAULT;
730 return 0;
732 case VIDIOCSPICT:
734 struct video_picture p;
735 if(copy_from_user(&p, arg, sizeof(p)))
736 return -EFAULT;
737 if(p.palette!=VIDEO_PALETTE_GREY)
738 return -EINVAL;
739 if(p.depth!=4 && p.depth!=6)
740 return -EINVAL;
743 * Now load the camera.
746 qcam->brightness = p.brightness>>8;
747 qcam->contrast = p.contrast>>8;
748 qcam->whitebal = p.whiteness>>8;
749 qcam->bpp = p.depth;
751 qc_setscanmode(qcam);
752 parport_claim_or_block(qcam->pdev);
753 qc_set(qcam);
754 parport_release(qcam->pdev);
755 return 0;
757 case VIDIOCSWIN:
759 struct video_window vw;
760 if(copy_from_user(&vw, arg,sizeof(vw)))
761 return -EFAULT;
762 if(vw.flags)
763 return -EINVAL;
764 if(vw.clipcount)
765 return -EINVAL;
766 if(vw.height<60||vw.height>240)
767 return -EINVAL;
768 if(vw.width<80||vw.width>320)
769 return -EINVAL;
771 qcam->width = 320;
772 qcam->height = 240;
773 qcam->transfer_scale = 4;
775 if(vw.width>=160 && vw.height>=120)
777 qcam->transfer_scale = 2;
779 if(vw.width>=320 && vw.height>=240)
781 qcam->width = 320;
782 qcam->height = 240;
783 qcam->transfer_scale = 1;
785 qc_setscanmode(qcam);
786 /* Ok we figured out what to use from our wide choice */
787 return 0;
789 case VIDIOCGWIN:
791 struct video_window vw;
792 vw.x=0;
793 vw.y=0;
794 vw.width=qcam->width/qcam->transfer_scale;
795 vw.height=qcam->height/qcam->transfer_scale;
796 vw.chromakey=0;
797 vw.flags=0;
798 if(copy_to_user(arg, &vw, sizeof(vw)))
799 return -EFAULT;
800 return 0;
802 case VIDIOCCAPTURE:
803 return -EINVAL;
804 case VIDIOCGFBUF:
805 return -EINVAL;
806 case VIDIOCSFBUF:
807 return -EINVAL;
808 case VIDIOCKEY:
809 return 0;
810 case VIDIOCGFREQ:
811 return -EINVAL;
812 case VIDIOCSFREQ:
813 return -EINVAL;
814 case VIDIOCGAUDIO:
815 return -EINVAL;
816 case VIDIOCSAUDIO:
817 return -EINVAL;
818 default:
819 return -ENOIOCTLCMD;
821 return 0;
824 static long qcam_read(struct video_device *v, char *buf, unsigned long count, int noblock)
826 struct qcam_device *qcam=(struct qcam_device *)v;
827 int len;
828 parport_claim_or_block(qcam->pdev);
829 /* Probably should have a semaphore against multiple users */
830 qc_reset(qcam);
831 len=qc_capture(qcam, buf,count);
832 parport_release(qcam->pdev);
833 return len;
837 static struct video_device qcam_template=
839 "Connectix Quickcam",
840 VID_TYPE_CAPTURE,
841 VID_HARDWARE_QCAM_BW,
842 qcam_open,
843 qcam_close,
844 qcam_read,
845 qcam_write,
846 qcam_ioctl,
847 NULL,
848 qcam_init_done,
849 NULL,
854 #define MAX_CAMS 4
855 static struct qcam_device *qcams[MAX_CAMS];
856 static unsigned int num_cams = 0;
858 int init_bwqcam(struct parport *port)
860 struct qcam_device *qcam;
862 if (num_cams == MAX_CAMS)
864 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
865 return -ENOSPC;
868 qcam=qcam_init(port);
869 if(qcam==NULL)
870 return -ENODEV;
872 parport_claim_or_block(qcam->pdev);
874 qc_reset(qcam);
876 if(qc_detect(qcam)==0)
878 parport_release(qcam->pdev);
879 parport_unregister_device(qcam->pdev);
880 kfree(qcam);
881 return -ENODEV;
883 qc_calibrate(qcam);
885 parport_release(qcam->pdev);
887 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
889 if(video_register_device(&qcam->vdev)==-1)
891 parport_unregister_device(qcam->pdev);
892 kfree(qcam);
893 return -ENODEV;
896 qcams[num_cams++] = qcam;
898 return 0;
901 void close_bwqcam(struct qcam_device *qcam)
903 video_unregister_device(&qcam->vdev);
904 parport_unregister_device(qcam->pdev);
905 kfree(qcam);
908 #ifdef MODULE
909 int init_module(void)
911 struct parport *port;
913 for (port = parport_enumerate(); port; port=port->next)
914 init_bwqcam(port);
916 return (num_cams)?0:-ENODEV;
919 void cleanup_module(void)
921 unsigned int i;
922 for (i = 0; i < num_cams; i++)
923 close_bwqcam(qcams[i]);
925 #else
926 __initfunc(int init_bw_qcams(struct video_init *unused))
928 struct parport *port;
930 for (port = parport_enumerate(); port; port=port->next)
931 init_bwqcam(port);
932 return 0;
934 #endif