2 * Video4Linux Colour QuickCam driver
3 * Copyright 1997-2000 Philip Blundell <philb@gnu.org>
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
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
15 * force_rgb=1 -- force data format to RGB (default is BGR)
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>
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>
26 #include <linux/module.h>
27 #include <linux/delay.h>
28 #include <linux/errno.h>
30 #include <linux/init.h>
31 #include <linux/kernel.h>
32 #include <linux/slab.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>
41 struct video_device vdev;
42 struct pardevice *pdev;
43 struct parport *pport;
45 int ccd_width, ccd_height;
47 int contrast, brightness, whitebal;
49 unsigned int bidirectional;
50 struct semaphore lock;
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) */
61 /* The three possible decimations */
62 #define QC_DECIMATION_1 0
63 #define QC_DECIMATION_2 2
64 #define QC_DECIMATION_4 4
66 #define BANNER "Colour QuickCam for Video4Linux v0.05"
68 static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
70 static int force_rgb = 0;
71 static int video_nr = -1;
73 static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
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);
80 static inline unsigned int qcam_ready1(struct qcam_device *qcam)
82 return (parport_read_status(qcam->pport) & 0x8)?1:0;
85 static inline unsigned int qcam_ready2(struct qcam_device *qcam)
87 return (parport_read_data(qcam->pport) & 0x1)?1:0;
90 static unsigned int qcam_await_ready1(struct qcam_device *qcam,
93 unsigned long oldjiffies = jiffies;
96 for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
97 if (qcam_ready1(qcam) == value)
100 /* If the camera didn't respond within 1/25 second, poll slowly
102 for (i = 0; i < 50; i++)
104 if (qcam_ready1(qcam) == value)
106 msleep_interruptible(100);
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));
116 static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
118 unsigned long oldjiffies = jiffies;
121 for (oldjiffies = jiffies; (jiffies - oldjiffies) < (HZ/25); )
122 if (qcam_ready2(qcam) == value)
125 /* If the camera didn't respond within 1/25 second, poll slowly
127 for (i = 0; i < 50; i++)
129 if (qcam_ready2(qcam) == value)
131 msleep_interruptible(100);
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));
142 static int qcam_read_data(struct qcam_device *qcam)
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);
154 static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
157 parport_write_data(qcam->pport, data);
158 idata = qcam_read_data(qcam);
161 printk(KERN_WARNING "cqcam: sent %x but received %x\n", data,
168 static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data)
170 if (qcam_write_data(qcam, cmd))
172 if (qcam_write_data(qcam, data))
177 static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd)
179 if (qcam_write_data(qcam, cmd))
181 return qcam_read_data(qcam);
184 static int qc_detect(struct qcam_device *qcam)
186 unsigned int stat, ostat, i, count = 0;
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");
204 parport_write_control(qcam->pport, 0xc);
206 /* look for a heartbeat */
207 ostat = stat = parport_read_status(qcam->pport);
208 for (i=0; i<250; i++)
211 stat = parport_read_status(qcam->pport);
214 if (++count >= 3) return 1;
219 /* Reset the camera and try again */
220 parport_write_control(qcam->pport, 0xc);
221 parport_write_control(qcam->pport, 0x8);
223 parport_write_control(qcam->pport, 0xc);
227 ostat = stat = parport_read_status(qcam->pport);
228 for (i=0; i<250; i++)
231 stat = parport_read_status(qcam->pport);
234 if (++count >= 3) return 1;
239 /* no (or flatline) camera, give up */
243 static void qc_reset(struct qcam_device *qcam)
245 parport_write_control(qcam->pport, 0xc);
246 parport_write_control(qcam->pport, 0x8);
248 parport_write_control(qcam->pport, 0xc);
252 /* Reset the QuickCam and program for brightness, contrast,
253 * white-balance, and resolution. */
255 static void qc_setup(struct qcam_device *q)
259 /* Set the brightness. */
260 qcam_set(q, 11, q->brightness);
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);
267 /* Set top and left. */
268 qcam_set(q, 0xd, q->top);
269 qcam_set(q, 0xf, q->left);
271 /* Set contrast and white balance. */
272 qcam_set(q, 0x19, q->contrast);
273 qcam_set(q, 0x1f, q->whitebal);
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. */
283 static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes)
285 unsigned int bytes = 0;
288 if (q->bidirectional)
290 /* It's a bidirectional port */
291 while (bytes < nbytes)
293 unsigned int lo1, hi1, lo2, hi2;
294 unsigned char r, g, b;
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;
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;
304 r = (lo1 | ((hi1 & 1)<<7));
305 g = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1);
306 b = (lo2 | ((hi2 & 1)<<7));
320 /* It's a unidirectional port */
321 int i = 0, n = bytes;
322 unsigned char rgb[3];
324 while (bytes < nbytes)
328 if (qcam_await_ready1(q, 1)) return bytes;
329 hi = (parport_read_status(q->pport) & 0xf0);
331 if (qcam_await_ready1(q, 0)) return bytes;
332 lo = (parport_read_status(q->pport) & 0xf0);
335 rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
359 static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len)
361 unsigned lines, pixelsperline, bitsperxfer;
362 unsigned int is_bi_dir = q->bidirectional;
363 size_t wantlen, outptr = 0;
366 if (!access_ok(VERIFY_WRITE, buf, len))
369 /* Wait for camera to become ready */
372 int i = qcam_get(q, 41);
383 if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1))
387 pixelsperline = q->width;
388 bitsperxfer = (is_bi_dir) ? 24 : 8;
392 /* Turn the port around */
393 parport_data_reverse(q->pport);
396 if (qcam_await_ready1(q, 1)) {
401 if (qcam_await_ready1(q, 0)) {
407 wantlen = lines * pixelsperline * 24 / 8;
412 s = (wantlen > BUFSZ)?BUFSZ:wantlen;
413 t = qcam_read_bytes(q, tmpbuf, s);
416 size_t sz = len - outptr;
418 if (__copy_to_user(buf+outptr, tmpbuf, sz))
432 printk("qcam: short read.\n");
434 parport_data_forward(q->pport);
443 l = qcam_read_bytes(q, tmpbuf, 3);
445 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
447 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
448 printk("qcam: bad EOF\n");
450 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
451 printk("qcam: bad EOF\n");
454 if (qcam_await_ready1(q, 1))
456 printk("qcam: no ack after EOF\n");
457 parport_data_forward(q->pport);
461 parport_data_forward(q->pport);
464 if (qcam_await_ready1(q, 0))
466 printk("qcam: no ack to port turnaround\n");
475 l = qcam_read_bytes(q, tmpbuf, 1);
477 } while (l && tmpbuf[0] == 0x7e);
478 l = qcam_read_bytes(q, tmpbuf+1, 2);
480 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
481 printk("qcam: bad EOF\n");
483 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
484 printk("qcam: bad EOF\n");
488 qcam_write_data(q, 0);
493 * Video4linux interfacing
496 static int qcam_do_ioctl(struct inode *inode, struct file *file,
497 unsigned int cmd, void *arg)
499 struct video_device *dev = video_devdata(file);
500 struct qcam_device *qcam=(struct qcam_device *)dev;
506 struct video_capability *b = arg;
507 strcpy(b->name, "Quickcam");
508 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
519 struct video_channel *v = arg;
524 /* Good question.. its composite or SVHS so.. */
525 v->type = VIDEO_TYPE_CAMERA;
526 strcpy(v->name, "Camera");
531 struct video_channel *v = arg;
538 struct video_tuner *v = arg;
541 memset(v,0,sizeof(*v));
542 strcpy(v->name, "Format");
543 v->mode = VIDEO_MODE_AUTO;
548 struct video_tuner *v = arg;
551 if(v->mode!=VIDEO_MODE_AUTO)
557 struct video_picture *p = arg;
560 p->brightness=qcam->brightness<<8;
561 p->contrast=qcam->contrast<<8;
562 p->whiteness=qcam->whitebal<<8;
564 p->palette=VIDEO_PALETTE_RGB24;
569 struct video_picture *p = arg;
574 if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
578 * Now load the camera.
580 qcam->brightness = p->brightness>>8;
581 qcam->contrast = p->contrast>>8;
582 qcam->whitebal = p->whiteness>>8;
585 parport_claim_or_block(qcam->pdev);
587 parport_release(qcam->pdev);
593 struct video_window *vw = arg;
599 if(vw->height<60||vw->height>240)
601 if(vw->width<80||vw->width>320)
606 qcam->mode = QC_DECIMATION_4;
608 if(vw->width>=160 && vw->height>=120)
612 qcam->mode = QC_DECIMATION_2;
614 if(vw->width>=320 && vw->height>=240)
618 qcam->mode = QC_DECIMATION_1;
620 qcam->mode |= QC_MILLIONS;
622 if(vw->width>=640 && vw->height>=480)
626 qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
629 /* Ok we figured out what to use from our
632 parport_claim_or_block(qcam->pdev);
634 parport_release(qcam->pdev);
640 struct video_window *vw = arg;
641 memset(vw, 0, sizeof(*vw));
642 vw->width=qcam->width;
643 vw->height=qcam->height;
662 static int qcam_ioctl(struct inode *inode, struct file *file,
663 unsigned int cmd, unsigned long arg)
665 return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
668 static ssize_t qcam_read(struct file *file, char __user *buf,
669 size_t count, loff_t *ppos)
671 struct video_device *v = video_devdata(file);
672 struct qcam_device *qcam=(struct qcam_device *)v;
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);
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,
690 .compat_ioctl = v4l_compat_ioctl32,
695 static struct video_device qcam_template=
697 .owner = THIS_MODULE,
698 .name = "Colour QuickCam",
699 .type = VID_TYPE_CAPTURE,
700 .hardware = VID_HARDWARE_QCAM_C,
704 /* Initialize the QuickCam driver control structure. */
706 static struct qcam_device *qcam_init(struct parport *port)
708 struct qcam_device *q;
710 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
715 q->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
718 q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0;
722 printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
728 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
730 init_MUTEX(&q->lock);
731 q->width = q->ccd_width = 320;
732 q->height = q->ccd_height = 240;
733 q->mode = QC_MILLIONS | QC_DECIMATION_1;
742 static struct qcam_device *qcams[MAX_CAMS];
743 static unsigned int num_cams = 0;
745 static int init_cqcam(struct parport *port)
747 struct qcam_device *qcam;
749 if (parport[0] != -1)
751 /* The user gave specific instructions */
753 for (i = 0; i < MAX_CAMS && parport[i] != -1; i++)
755 if (parport[0] == port->number)
762 if (num_cams == MAX_CAMS)
765 qcam = qcam_init(port);
769 parport_claim_or_block(qcam->pdev);
773 if (probe && qc_detect(qcam)==0)
775 parport_release(qcam->pdev);
776 parport_unregister_device(qcam->pdev);
783 parport_release(qcam->pdev);
785 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
787 printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
789 parport_unregister_device(qcam->pdev);
794 printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
795 qcam->vdev.minor, qcam->pport->name);
797 qcams[num_cams++] = qcam;
802 static void close_cqcam(struct qcam_device *qcam)
804 video_unregister_device(&qcam->vdev);
805 parport_unregister_device(qcam->pdev);
809 static void cq_attach(struct parport *port)
814 static void cq_detach(struct parport *port)
816 /* Write this some day. */
819 static struct parport_driver cqcam_driver = {
825 static int __init cqcam_init (void)
829 return parport_register_driver(&cqcam_driver);
832 static void __exit cqcam_cleanup (void)
836 for (i = 0; i < num_cams; i++)
837 close_cqcam(qcams[i]);
839 parport_unregister_driver(&cqcam_driver);
842 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
843 MODULE_DESCRIPTION(BANNER);
844 MODULE_LICENSE("GPL");
846 /* FIXME: parport=auto would never have worked, surely? --RR */
847 MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\
848 probe=<0|1|2> for camera detection method\n\
849 force_rgb=<0|1> for RGB data format (default BGR)");
850 module_param_array(parport, int, NULL, 0);
851 module_param(probe, int, 0);
852 module_param(force_rgb, bool, 0);
853 module_param(video_nr, int, 0);
855 module_init(cqcam_init);
856 module_exit(cqcam_cleanup);