2 * Video4Linux Colour QuickCam driver
3 * Copyright 1997-1998 Philip Blundell <philb@gnu.org>
7 #include <linux/module.h>
8 #include <linux/delay.h>
9 #include <linux/errno.h>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/malloc.h>
15 #include <linux/parport.h>
16 #include <linux/sched.h>
17 #include <linux/version.h>
18 #include <linux/videodev.h>
19 #include <asm/uaccess.h>
22 struct video_device vdev
;
23 struct pardevice
*pdev
;
24 struct parport
*pport
;
26 int ccd_width
, ccd_height
;
28 int contrast
, brightness
, whitebal
;
30 unsigned int bidirectional
;
33 /* The three possible QuickCam modes */
34 #define QC_MILLIONS 0x18
35 #define QC_BILLIONS 0x10
36 #define QC_THOUSANDS 0x08 /* with VIDEC compression (not supported) */
38 /* The three possible decimations */
39 #define QC_DECIMATION_1 0
40 #define QC_DECIMATION_2 2
41 #define QC_DECIMATION_4 4
43 static inline void qcam_set_ack(struct qcam_device
*qcam
, unsigned int i
)
45 /* note: the QC specs refer to the PCAck pin by voltage, not
46 software level. PC ports have builtin inverters. */
47 parport_frob_control(qcam
->pport
, 8, i
?8:0);
50 static inline unsigned int qcam_ready1(struct qcam_device
*qcam
)
52 return (parport_read_status(qcam
->pport
) & 0x8)?1:0;
55 static inline unsigned int qcam_ready2(struct qcam_device
*qcam
)
57 return (parport_read_data(qcam
->pport
) & 0x1)?1:0;
60 static unsigned int qcam_await_ready1(struct qcam_device
*qcam
,
63 unsigned long oldjiffies
= jiffies
;
66 for (oldjiffies
= jiffies
; (jiffies
- oldjiffies
) < (HZ
/25); )
67 if (qcam_ready1(qcam
) == value
)
70 /* If the camera didn't respond within 1/25 second, poll slowly
72 for (i
= 0; i
< 50; i
++)
74 if (qcam_ready1(qcam
) == value
)
76 current
->state
=TASK_INTERRUPTIBLE
;
77 schedule_timeout(HZ
/10);
80 /* Probably somebody pulled the plug out. Not much we can do. */
81 printk(KERN_ERR
"c-qcam: ready1 timeout (%d) %x %x\n", value
,
82 parport_read_status(qcam
->pport
),
83 parport_read_control(qcam
->pport
));
87 static unsigned int qcam_await_ready2(struct qcam_device
*qcam
, int value
)
89 unsigned long oldjiffies
= jiffies
;
92 for (oldjiffies
= jiffies
; (jiffies
- oldjiffies
) < (HZ
/25); )
93 if (qcam_ready2(qcam
) == value
)
96 /* If the camera didn't respond within 1/25 second, poll slowly
98 for (i
= 0; i
< 50; i
++)
100 if (qcam_ready2(qcam
) == value
)
102 current
->state
=TASK_INTERRUPTIBLE
;
103 schedule_timeout(HZ
/10);
106 /* Probably somebody pulled the plug out. Not much we can do. */
107 printk(KERN_ERR
"c-qcam: ready2 timeout (%d) %x %x %x\n", value
,
108 parport_read_status(qcam
->pport
),
109 parport_read_control(qcam
->pport
),
110 parport_read_data(qcam
->pport
));
114 static int qcam_read_data(struct qcam_device
*qcam
)
117 qcam_set_ack(qcam
, 0);
118 if (qcam_await_ready1(qcam
, 1)) return -1;
119 idata
= parport_read_status(qcam
->pport
) & 0xf0;
120 qcam_set_ack(qcam
, 1);
121 if (qcam_await_ready1(qcam
, 0)) return -1;
122 idata
|= (parport_read_status(qcam
->pport
) >> 4);
126 static int qcam_write_data(struct qcam_device
*qcam
, unsigned int data
)
129 parport_write_data(qcam
->pport
, data
);
130 idata
= qcam_read_data(qcam
);
133 printk(KERN_WARNING
"cqcam: sent %x but received %x\n", data
,
140 static inline int qcam_set(struct qcam_device
*qcam
, unsigned int cmd
, unsigned int data
)
142 if (qcam_write_data(qcam
, cmd
))
144 if (qcam_write_data(qcam
, data
))
149 static inline int qcam_get(struct qcam_device
*qcam
, unsigned int cmd
)
151 if (qcam_write_data(qcam
, cmd
))
153 return qcam_read_data(qcam
);
156 static int qc_detect(struct qcam_device
*qcam
)
158 unsigned int stat
, ostat
, i
, count
= 0;
160 parport_write_control(qcam
->pport
, 0xc);
162 /* look for a heartbeat */
163 ostat
= stat
= parport_read_status(qcam
->pport
);
164 for (i
=0; i
<250; i
++)
167 stat
= parport_read_status(qcam
->pport
);
170 if (++count
>= 3) return 1;
175 /* no (or flatline) camera, give up */
179 static void qc_reset(struct qcam_device
*qcam
)
181 parport_write_control(qcam
->pport
, 0xc);
182 parport_write_control(qcam
->pport
, 0x8);
184 parport_write_control(qcam
->pport
, 0xc);
188 /* Reset the QuickCam and program for brightness, contrast,
189 * white-balance, and resolution. */
191 static void qc_setup(struct qcam_device
*q
)
195 /* Set the brightness. */
196 qcam_set(q
, 11, q
->brightness
);
198 /* Set the height and width. These refer to the actual
199 CCD area *before* applying the selected decimation. */
200 qcam_set(q
, 17, q
->ccd_height
);
201 qcam_set(q
, 19, q
->ccd_width
/ 2);
203 /* Set top and left. */
204 qcam_set(q
, 0xd, q
->top
);
205 qcam_set(q
, 0xf, q
->left
);
207 /* Set contrast and white balance. */
208 qcam_set(q
, 0x19, q
->contrast
);
209 qcam_set(q
, 0x1f, q
->whitebal
);
215 /* Read some bytes from the camera and put them in the buffer.
216 nbytes should be a multiple of 3, because bidirectional mode gives
217 us three bytes at a time. */
219 static unsigned int qcam_read_bytes(struct qcam_device
*q
, unsigned char *buf
, unsigned int nbytes
)
221 unsigned int bytes
= 0;
223 if (q
->bidirectional
)
225 /* It's a bidirectional port */
226 while (bytes
< nbytes
)
228 unsigned int lo1
, hi1
, lo2
, hi2
;
229 if (qcam_await_ready2(q
, 1)) return bytes
;
230 lo1
= parport_read_data(q
->pport
) >> 1;
231 hi1
= ((parport_read_status(q
->pport
) >> 3) & 0x1f) ^ 0x10;
233 if (qcam_await_ready2(q
, 0)) return bytes
;
234 lo2
= parport_read_data(q
->pport
) >> 1;
235 hi2
= ((parport_read_status(q
->pport
) >> 3) & 0x1f) ^ 0x10;
237 buf
[bytes
++] = (lo1
| ((hi1
& 1)<<7));
238 buf
[bytes
++] = ((hi1
& 0x1e)<<3) | ((hi2
& 0x1e)>>1);
239 buf
[bytes
++] = (lo2
| ((hi2
& 1)<<7));
244 /* It's a unidirectional port */
245 while (bytes
< nbytes
)
248 if (qcam_await_ready1(q
, 1)) return bytes
;
249 hi
= (parport_read_status(q
->pport
) & 0xf0);
251 if (qcam_await_ready1(q
, 0)) return bytes
;
252 lo
= (parport_read_status(q
->pport
) & 0xf0);
255 buf
[bytes
++] = (hi
| (lo
>> 4)) ^ 0x88;
263 static long qc_capture(struct qcam_device
*q
, char *buf
, unsigned long len
)
265 unsigned lines
, pixelsperline
, bitsperxfer
;
266 unsigned int is_bi_dir
= q
->bidirectional
;
267 size_t wantlen
, outptr
= 0;
270 if (verify_area(VERIFY_WRITE
, buf
, len
))
273 /* Wait for camera to become ready */
276 int i
= qcam_get(q
, 41);
287 if (qcam_set(q
, 7, (q
->mode
| (is_bi_dir
?1:0)) + 1))
291 pixelsperline
= q
->width
;
292 bitsperxfer
= (is_bi_dir
) ? 24 : 8;
296 /* Turn the port around */
297 parport_frob_control(q
->pport
, 0x20, 0x20);
300 if (qcam_await_ready1(q
, 1)) {
305 if (qcam_await_ready1(q
, 0)) {
311 wantlen
= lines
* pixelsperline
* 24 / 8;
316 s
= (wantlen
> BUFSZ
)?BUFSZ
:wantlen
;
317 t
= qcam_read_bytes(q
, tmpbuf
, s
);
320 size_t sz
= len
- outptr
;
322 if (__copy_to_user(buf
+outptr
, tmpbuf
, sz
))
329 if (current
->need_resched
)
337 printk("qcam: short read.\n");
339 parport_frob_control(q
->pport
, 0x20, 0);
348 l
= qcam_read_bytes(q
, tmpbuf
, 3);
349 if (current
->need_resched
)
351 } while (l
&& (tmpbuf
[0] == 0x7e || tmpbuf
[1] == 0x7e || tmpbuf
[2] == 0x7e));
352 if (tmpbuf
[0] != 0xe || tmpbuf
[1] != 0x0 || tmpbuf
[2] != 0xf)
353 printk("qcam: bad EOF\n");
355 if (qcam_await_ready1(q
, 1))
357 printk("qcam: no ack after EOF\n");
358 parport_frob_control(q
->pport
, 0x20, 0);
362 parport_frob_control(q
->pport
, 0x20, 0);
365 if (qcam_await_ready1(q
, 0))
367 printk("qcam: no ack to port turnaround\n");
376 l
= qcam_read_bytes(q
, tmpbuf
, 1);
377 if (current
->need_resched
)
379 } while (l
&& tmpbuf
[0] == 0x7e);
380 l
= qcam_read_bytes(q
, tmpbuf
+1, 2);
381 if (tmpbuf
[0] != 0xe || tmpbuf
[1] != 0x0 || tmpbuf
[2] != 0xf)
382 printk("qcam: bad EOF\n");
385 qcam_write_data(q
, 0);
390 * Video4linux interfacing
393 static int qcam_open(struct video_device
*dev
, int flags
)
399 static void qcam_close(struct video_device
*dev
)
404 static int qcam_init_done(struct video_device
*dev
)
409 static long qcam_write(struct video_device
*v
, const char *buf
, unsigned long count
, int noblock
)
414 static int qcam_ioctl(struct video_device
*dev
, unsigned int cmd
, void *arg
)
416 struct qcam_device
*qcam
=(struct qcam_device
*)dev
;
422 struct video_capability b
;
423 strcpy(b
.name
, "Quickcam");
424 b
.type
= VID_TYPE_CAPTURE
|VID_TYPE_SCALES
;
431 if(copy_to_user(arg
, &b
,sizeof(b
)))
437 struct video_channel v
;
438 if(copy_from_user(&v
, arg
, sizeof(v
)))
444 /* Good question.. its composite or SVHS so.. */
445 v
.type
= VIDEO_TYPE_CAMERA
;
446 strcpy(v
.name
, "Camera");
447 if(copy_to_user(arg
, &v
, sizeof(v
)))
454 if(copy_from_user(&v
, arg
,sizeof(v
)))
462 struct video_tuner v
;
463 if(copy_from_user(&v
, arg
, sizeof(v
))!=0)
467 strcpy(v
.name
, "Format");
471 v
.mode
= VIDEO_MODE_AUTO
;
472 if(copy_to_user(arg
,&v
,sizeof(v
))!=0)
478 struct video_tuner v
;
479 if(copy_from_user(&v
, arg
, sizeof(v
))!=0)
483 if(v
.mode
!=VIDEO_MODE_AUTO
)
489 struct video_picture p
;
492 p
.brightness
=qcam
->brightness
<<8;
493 p
.contrast
=qcam
->contrast
<<8;
494 p
.whiteness
=qcam
->whitebal
<<8;
496 p
.palette
=VIDEO_PALETTE_RGB24
;
497 if(copy_to_user(arg
, &p
, sizeof(p
)))
503 struct video_picture p
;
504 if(copy_from_user(&p
, arg
, sizeof(p
)))
510 if (p
.depth
!= 24 || p
.palette
!= VIDEO_PALETTE_RGB24
)
514 * Now load the camera.
516 qcam
->brightness
= p
.brightness
>>8;
517 qcam
->contrast
= p
.contrast
>>8;
518 qcam
->whitebal
= p
.whiteness
>>8;
520 parport_claim_or_block(qcam
->pdev
);
522 parport_release(qcam
->pdev
);
527 struct video_window vw
;
529 if(copy_from_user(&vw
, arg
,sizeof(vw
)))
535 if(vw
.height
<60||vw
.height
>240)
537 if(vw
.width
<80||vw
.width
>320)
542 qcam
->mode
= QC_DECIMATION_4
;
544 if(vw
.width
>=160 && vw
.height
>=120)
548 qcam
->mode
= QC_DECIMATION_2
;
550 if(vw
.width
>=320 && vw
.height
>=240)
554 qcam
->mode
= QC_DECIMATION_1
;
556 qcam
->mode
|= QC_MILLIONS
;
558 if(vw
.width
>=640 && vw
.height
>=480)
562 qcam
->mode
= QC_BILLIONS
| QC_DECIMATION_1
;
565 /* Ok we figured out what to use from our
567 parport_claim_or_block(qcam
->pdev
);
569 parport_release(qcam
->pdev
);
574 struct video_window vw
;
577 vw
.width
=qcam
->width
;
578 vw
.height
=qcam
->height
;
581 if(copy_to_user(arg
, &vw
, sizeof(vw
)))
607 static long qcam_read(struct video_device
*v
, char *buf
, unsigned long count
, int noblock
)
609 struct qcam_device
*qcam
=(struct qcam_device
*)v
;
611 parport_claim_or_block(qcam
->pdev
);
612 /* Probably should have a semaphore against multiple users */
613 len
= qc_capture(qcam
, buf
,count
);
614 parport_release(qcam
->pdev
);
618 /* video device template */
619 static struct video_device qcam_template
=
637 /* Initialize the QuickCam driver control structure. */
639 static struct qcam_device
*qcam_init(struct parport
*port
)
641 struct qcam_device
*q
;
643 q
= kmalloc(sizeof(struct qcam_device
), GFP_KERNEL
);
646 q
->pdev
= parport_register_device(port
, "c-qcam", NULL
, NULL
,
649 q
->bidirectional
= (q
->pport
->modes
& PARPORT_MODE_PCPS2
)?1:0;
653 printk(KERN_ERR
"c-qcam: couldn't register for %s.\n",
659 memcpy(&q
->vdev
, &qcam_template
, sizeof(qcam_template
));
661 q
->width
= q
->ccd_width
= 320;
662 q
->height
= q
->ccd_height
= 240;
663 q
->mode
= QC_MILLIONS
| QC_DECIMATION_1
;
673 static struct qcam_device
*qcams
[MAX_CAMS
];
674 static unsigned int num_cams
= 0;
676 int init_cqcam(struct parport
*port
)
678 struct qcam_device
*qcam
;
680 if (num_cams
== MAX_CAMS
)
682 printk(KERN_ERR
"Too many Quickcams (max %d)\n", MAX_CAMS
);
686 qcam
= qcam_init(port
);
690 parport_claim_or_block(qcam
->pdev
);
694 if (qc_detect(qcam
)==0)
696 parport_release(qcam
->pdev
);
697 parport_unregister_device(qcam
->pdev
);
704 parport_release(qcam
->pdev
);
706 printk(KERN_INFO
"Colour Quickcam found on %s\n",
709 if (video_register_device(&qcam
->vdev
, VFL_TYPE_GRABBER
)==-1)
711 parport_unregister_device(qcam
->pdev
);
716 qcams
[num_cams
++] = qcam
;
721 void close_cqcam(struct qcam_device
*qcam
)
723 video_unregister_device(&qcam
->vdev
);
724 parport_unregister_device(qcam
->pdev
);
728 #define BANNER "Connectix Colour Quickcam driver v0.02\n"
731 int init_module(void)
733 struct parport
*port
;
737 for (port
= parport_enumerate(); port
; port
=port
->next
)
740 return (num_cams
)?0:-ENODEV
;
743 void cleanup_module(void)
746 for (i
= 0; i
< num_cams
; i
++)
747 close_cqcam(qcams
[i
]);
750 __initfunc(int init_colour_qcams(struct video_init
*unused
))
752 struct parport
*port
;
756 for (port
= parport_enumerate(); port
; port
=port
->next
)