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/mutex.h>
37 #include <linux/jiffies.h>
38 #include <linux/videodev2.h>
39 #include <asm/uaccess.h>
40 #include <media/v4l2-device.h>
41 #include <media/v4l2-common.h>
42 #include <media/v4l2-ioctl.h>
43 #include <media/v4l2-fh.h>
44 #include <media/v4l2-ctrls.h>
45 #include <media/v4l2-event.h>
48 struct v4l2_device v4l2_dev
;
49 struct video_device vdev
;
50 struct v4l2_ctrl_handler hdl
;
51 struct pardevice
*pdev
;
52 struct parport
*pport
;
54 int ccd_width
, ccd_height
;
56 int contrast
, brightness
, whitebal
;
58 unsigned int bidirectional
;
65 /* The three possible QuickCam modes */
66 #define QC_MILLIONS 0x18
67 #define QC_BILLIONS 0x10
68 #define QC_THOUSANDS 0x08 /* with VIDEC compression (not supported) */
70 /* The three possible decimations */
71 #define QC_DECIMATION_1 0
72 #define QC_DECIMATION_2 2
73 #define QC_DECIMATION_4 4
75 #define BANNER "Colour QuickCam for Video4Linux v0.06"
77 static int parport
[MAX_CAMS
] = { [1 ... MAX_CAMS
-1] = -1 };
79 static bool force_rgb
;
80 static int video_nr
= -1;
82 /* FIXME: parport=auto would never have worked, surely? --RR */
83 MODULE_PARM_DESC(parport
, "parport=<auto|n[,n]...> for port detection method\n"
84 "probe=<0|1|2> for camera detection method\n"
85 "force_rgb=<0|1> for RGB data format (default BGR)");
86 module_param_array(parport
, int, NULL
, 0);
87 module_param(probe
, int, 0);
88 module_param(force_rgb
, bool, 0);
89 module_param(video_nr
, int, 0);
91 static struct qcam
*qcams
[MAX_CAMS
];
92 static unsigned int num_cams
;
94 static inline void qcam_set_ack(struct qcam
*qcam
, unsigned int i
)
96 /* note: the QC specs refer to the PCAck pin by voltage, not
97 software level. PC ports have builtin inverters. */
98 parport_frob_control(qcam
->pport
, 8, i
? 8 : 0);
101 static inline unsigned int qcam_ready1(struct qcam
*qcam
)
103 return (parport_read_status(qcam
->pport
) & 0x8) ? 1 : 0;
106 static inline unsigned int qcam_ready2(struct qcam
*qcam
)
108 return (parport_read_data(qcam
->pport
) & 0x1) ? 1 : 0;
111 static unsigned int qcam_await_ready1(struct qcam
*qcam
, int value
)
113 struct v4l2_device
*v4l2_dev
= &qcam
->v4l2_dev
;
114 unsigned long oldjiffies
= jiffies
;
117 for (oldjiffies
= jiffies
;
118 time_before(jiffies
, oldjiffies
+ msecs_to_jiffies(40));)
119 if (qcam_ready1(qcam
) == value
)
122 /* If the camera didn't respond within 1/25 second, poll slowly
124 for (i
= 0; i
< 50; i
++) {
125 if (qcam_ready1(qcam
) == value
)
127 msleep_interruptible(100);
130 /* Probably somebody pulled the plug out. Not much we can do. */
131 v4l2_err(v4l2_dev
, "ready1 timeout (%d) %x %x\n", value
,
132 parport_read_status(qcam
->pport
),
133 parport_read_control(qcam
->pport
));
137 static unsigned int qcam_await_ready2(struct qcam
*qcam
, int value
)
139 struct v4l2_device
*v4l2_dev
= &qcam
->v4l2_dev
;
140 unsigned long oldjiffies
= jiffies
;
143 for (oldjiffies
= jiffies
;
144 time_before(jiffies
, oldjiffies
+ msecs_to_jiffies(40));)
145 if (qcam_ready2(qcam
) == value
)
148 /* If the camera didn't respond within 1/25 second, poll slowly
150 for (i
= 0; i
< 50; i
++) {
151 if (qcam_ready2(qcam
) == value
)
153 msleep_interruptible(100);
156 /* Probably somebody pulled the plug out. Not much we can do. */
157 v4l2_err(v4l2_dev
, "ready2 timeout (%d) %x %x %x\n", value
,
158 parport_read_status(qcam
->pport
),
159 parport_read_control(qcam
->pport
),
160 parport_read_data(qcam
->pport
));
164 static int qcam_read_data(struct qcam
*qcam
)
168 qcam_set_ack(qcam
, 0);
169 if (qcam_await_ready1(qcam
, 1))
171 idata
= parport_read_status(qcam
->pport
) & 0xf0;
172 qcam_set_ack(qcam
, 1);
173 if (qcam_await_ready1(qcam
, 0))
175 idata
|= parport_read_status(qcam
->pport
) >> 4;
179 static int qcam_write_data(struct qcam
*qcam
, unsigned int data
)
181 struct v4l2_device
*v4l2_dev
= &qcam
->v4l2_dev
;
184 parport_write_data(qcam
->pport
, data
);
185 idata
= qcam_read_data(qcam
);
187 v4l2_warn(v4l2_dev
, "sent %x but received %x\n", data
,
194 static inline int qcam_set(struct qcam
*qcam
, unsigned int cmd
, unsigned int data
)
196 if (qcam_write_data(qcam
, cmd
))
198 if (qcam_write_data(qcam
, data
))
203 static inline int qcam_get(struct qcam
*qcam
, unsigned int cmd
)
205 if (qcam_write_data(qcam
, cmd
))
207 return qcam_read_data(qcam
);
210 static int qc_detect(struct qcam
*qcam
)
212 unsigned int stat
, ostat
, i
, count
= 0;
214 /* The probe routine below is not very reliable. The IEEE-1284
215 probe takes precedence. */
216 /* XXX Currently parport provides no way to distinguish between
217 "the IEEE probe was not done" and "the probe was done, but
218 no device was found". Fix this one day. */
219 if (qcam
->pport
->probe_info
[0].class == PARPORT_CLASS_MEDIA
220 && qcam
->pport
->probe_info
[0].model
221 && !strcmp(qcam
->pdev
->port
->probe_info
[0].model
,
222 "Color QuickCam 2.0")) {
223 printk(KERN_DEBUG
"QuickCam: Found by IEEE1284 probe.\n");
230 parport_write_control(qcam
->pport
, 0xc);
232 /* look for a heartbeat */
233 ostat
= stat
= parport_read_status(qcam
->pport
);
234 for (i
= 0; i
< 250; i
++) {
236 stat
= parport_read_status(qcam
->pport
);
244 /* Reset the camera and try again */
245 parport_write_control(qcam
->pport
, 0xc);
246 parport_write_control(qcam
->pport
, 0x8);
248 parport_write_control(qcam
->pport
, 0xc);
252 ostat
= stat
= parport_read_status(qcam
->pport
);
253 for (i
= 0; i
< 250; i
++) {
255 stat
= parport_read_status(qcam
->pport
);
263 /* no (or flatline) camera, give up */
267 static void qc_reset(struct qcam
*qcam
)
269 parport_write_control(qcam
->pport
, 0xc);
270 parport_write_control(qcam
->pport
, 0x8);
272 parport_write_control(qcam
->pport
, 0xc);
276 /* Reset the QuickCam and program for brightness, contrast,
277 * white-balance, and resolution. */
279 static void qc_setup(struct qcam
*qcam
)
283 /* Set the brightness. */
284 qcam_set(qcam
, 11, qcam
->brightness
);
286 /* Set the height and width. These refer to the actual
287 CCD area *before* applying the selected decimation. */
288 qcam_set(qcam
, 17, qcam
->ccd_height
);
289 qcam_set(qcam
, 19, qcam
->ccd_width
/ 2);
291 /* Set top and left. */
292 qcam_set(qcam
, 0xd, qcam
->top
);
293 qcam_set(qcam
, 0xf, qcam
->left
);
295 /* Set contrast and white balance. */
296 qcam_set(qcam
, 0x19, qcam
->contrast
);
297 qcam_set(qcam
, 0x1f, qcam
->whitebal
);
300 qcam_set(qcam
, 45, 2);
303 /* Read some bytes from the camera and put them in the buffer.
304 nbytes should be a multiple of 3, because bidirectional mode gives
305 us three bytes at a time. */
307 static unsigned int qcam_read_bytes(struct qcam
*qcam
, unsigned char *buf
, unsigned int nbytes
)
309 unsigned int bytes
= 0;
311 qcam_set_ack(qcam
, 0);
312 if (qcam
->bidirectional
) {
313 /* It's a bidirectional port */
314 while (bytes
< nbytes
) {
315 unsigned int lo1
, hi1
, lo2
, hi2
;
316 unsigned char r
, g
, b
;
318 if (qcam_await_ready2(qcam
, 1))
320 lo1
= parport_read_data(qcam
->pport
) >> 1;
321 hi1
= ((parport_read_status(qcam
->pport
) >> 3) & 0x1f) ^ 0x10;
322 qcam_set_ack(qcam
, 1);
323 if (qcam_await_ready2(qcam
, 0))
325 lo2
= parport_read_data(qcam
->pport
) >> 1;
326 hi2
= ((parport_read_status(qcam
->pport
) >> 3) & 0x1f) ^ 0x10;
327 qcam_set_ack(qcam
, 0);
328 r
= lo1
| ((hi1
& 1) << 7);
329 g
= ((hi1
& 0x1e) << 3) | ((hi2
& 0x1e) >> 1);
330 b
= lo2
| ((hi2
& 1) << 7);
342 /* It's a unidirectional port */
343 int i
= 0, n
= bytes
;
344 unsigned char rgb
[3];
346 while (bytes
< nbytes
) {
349 if (qcam_await_ready1(qcam
, 1))
351 hi
= (parport_read_status(qcam
->pport
) & 0xf0);
352 qcam_set_ack(qcam
, 1);
353 if (qcam_await_ready1(qcam
, 0))
355 lo
= (parport_read_status(qcam
->pport
) & 0xf0);
356 qcam_set_ack(qcam
, 0);
358 rgb
[(i
= bytes
++ % 3)] = (hi
| (lo
>> 4)) ^ 0x88;
382 static long qc_capture(struct qcam
*qcam
, char __user
*buf
, unsigned long len
)
384 struct v4l2_device
*v4l2_dev
= &qcam
->v4l2_dev
;
385 unsigned lines
, pixelsperline
;
386 unsigned int is_bi_dir
= qcam
->bidirectional
;
387 size_t wantlen
, outptr
= 0;
390 if (!access_ok(VERIFY_WRITE
, buf
, len
))
393 /* Wait for camera to become ready */
395 int i
= qcam_get(qcam
, 41);
406 if (qcam_set(qcam
, 7, (qcam
->mode
| (is_bi_dir
? 1 : 0)) + 1))
409 lines
= qcam
->height
;
410 pixelsperline
= qcam
->width
;
413 /* Turn the port around */
414 parport_data_reverse(qcam
->pport
);
416 qcam_set_ack(qcam
, 0);
417 if (qcam_await_ready1(qcam
, 1)) {
421 qcam_set_ack(qcam
, 1);
422 if (qcam_await_ready1(qcam
, 0)) {
428 wantlen
= lines
* pixelsperline
* 24 / 8;
433 s
= (wantlen
> BUFSZ
) ? BUFSZ
: wantlen
;
434 t
= qcam_read_bytes(qcam
, tmpbuf
, s
);
436 size_t sz
= len
- outptr
;
440 if (__copy_to_user(buf
+ outptr
, tmpbuf
, sz
))
453 v4l2_err(v4l2_dev
, "short read.\n");
455 parport_data_forward(qcam
->pport
);
464 l
= qcam_read_bytes(qcam
, tmpbuf
, 3);
466 } while (l
&& (tmpbuf
[0] == 0x7e || tmpbuf
[1] == 0x7e || tmpbuf
[2] == 0x7e));
468 if (tmpbuf
[0] != 0xe || tmpbuf
[1] != 0x0 || tmpbuf
[2] != 0xf)
469 v4l2_err(v4l2_dev
, "bad EOF\n");
471 if (tmpbuf
[0] != 0xf || tmpbuf
[1] != 0x0 || tmpbuf
[2] != 0xe)
472 v4l2_err(v4l2_dev
, "bad EOF\n");
474 qcam_set_ack(qcam
, 0);
475 if (qcam_await_ready1(qcam
, 1)) {
476 v4l2_err(v4l2_dev
, "no ack after EOF\n");
477 parport_data_forward(qcam
->pport
);
481 parport_data_forward(qcam
->pport
);
483 qcam_set_ack(qcam
, 1);
484 if (qcam_await_ready1(qcam
, 0)) {
485 v4l2_err(v4l2_dev
, "no ack to port turnaround\n");
493 l
= qcam_read_bytes(qcam
, tmpbuf
, 1);
495 } while (l
&& tmpbuf
[0] == 0x7e);
496 l
= qcam_read_bytes(qcam
, tmpbuf
+ 1, 2);
498 if (tmpbuf
[0] != 0xe || tmpbuf
[1] != 0x0 || tmpbuf
[2] != 0xf)
499 v4l2_err(v4l2_dev
, "bad EOF\n");
501 if (tmpbuf
[0] != 0xf || tmpbuf
[1] != 0x0 || tmpbuf
[2] != 0xe)
502 v4l2_err(v4l2_dev
, "bad EOF\n");
506 qcam_write_data(qcam
, 0);
511 * Video4linux interfacing
514 static int qcam_querycap(struct file
*file
, void *priv
,
515 struct v4l2_capability
*vcap
)
517 struct qcam
*qcam
= video_drvdata(file
);
519 strlcpy(vcap
->driver
, qcam
->v4l2_dev
.name
, sizeof(vcap
->driver
));
520 strlcpy(vcap
->card
, "Color Quickcam", sizeof(vcap
->card
));
521 strlcpy(vcap
->bus_info
, "parport", sizeof(vcap
->bus_info
));
522 vcap
->device_caps
= V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_READWRITE
;
523 vcap
->capabilities
= vcap
->device_caps
| V4L2_CAP_DEVICE_CAPS
;
527 static int qcam_enum_input(struct file
*file
, void *fh
, struct v4l2_input
*vin
)
531 strlcpy(vin
->name
, "Camera", sizeof(vin
->name
));
532 vin
->type
= V4L2_INPUT_TYPE_CAMERA
;
540 static int qcam_g_input(struct file
*file
, void *fh
, unsigned int *inp
)
546 static int qcam_s_input(struct file
*file
, void *fh
, unsigned int inp
)
548 return (inp
> 0) ? -EINVAL
: 0;
551 static int qcam_g_fmt_vid_cap(struct file
*file
, void *fh
, struct v4l2_format
*fmt
)
553 struct qcam
*qcam
= video_drvdata(file
);
554 struct v4l2_pix_format
*pix
= &fmt
->fmt
.pix
;
556 pix
->width
= qcam
->width
;
557 pix
->height
= qcam
->height
;
558 pix
->pixelformat
= V4L2_PIX_FMT_RGB24
;
559 pix
->field
= V4L2_FIELD_NONE
;
560 pix
->bytesperline
= 3 * qcam
->width
;
561 pix
->sizeimage
= 3 * qcam
->width
* qcam
->height
;
563 pix
->colorspace
= V4L2_COLORSPACE_SRGB
;
567 static int qcam_try_fmt_vid_cap(struct file
*file
, void *fh
, struct v4l2_format
*fmt
)
569 struct v4l2_pix_format
*pix
= &fmt
->fmt
.pix
;
571 if (pix
->height
< 60 || pix
->width
< 80) {
574 } else if (pix
->height
< 120 || pix
->width
< 160) {
581 pix
->pixelformat
= V4L2_PIX_FMT_RGB24
;
582 pix
->field
= V4L2_FIELD_NONE
;
583 pix
->bytesperline
= 3 * pix
->width
;
584 pix
->sizeimage
= 3 * pix
->width
* pix
->height
;
586 pix
->colorspace
= V4L2_COLORSPACE_SRGB
;
590 static int qcam_s_fmt_vid_cap(struct file
*file
, void *fh
, struct v4l2_format
*fmt
)
592 struct qcam
*qcam
= video_drvdata(file
);
593 struct v4l2_pix_format
*pix
= &fmt
->fmt
.pix
;
594 int ret
= qcam_try_fmt_vid_cap(file
, fh
, fmt
);
598 switch (pix
->height
) {
600 qcam
->mode
= QC_DECIMATION_4
;
603 qcam
->mode
= QC_DECIMATION_2
;
606 qcam
->mode
= QC_DECIMATION_1
;
610 mutex_lock(&qcam
->lock
);
611 qcam
->mode
|= QC_MILLIONS
;
612 qcam
->height
= pix
->height
;
613 qcam
->width
= pix
->width
;
614 parport_claim_or_block(qcam
->pdev
);
616 parport_release(qcam
->pdev
);
617 mutex_unlock(&qcam
->lock
);
621 static int qcam_enum_fmt_vid_cap(struct file
*file
, void *fh
, struct v4l2_fmtdesc
*fmt
)
623 static struct v4l2_fmtdesc formats
[] = {
625 "RGB 8:8:8", V4L2_PIX_FMT_RGB24
,
629 enum v4l2_buf_type type
= fmt
->type
;
634 *fmt
= formats
[fmt
->index
];
639 static ssize_t
qcam_read(struct file
*file
, char __user
*buf
,
640 size_t count
, loff_t
*ppos
)
642 struct qcam
*qcam
= video_drvdata(file
);
645 mutex_lock(&qcam
->lock
);
646 parport_claim_or_block(qcam
->pdev
);
647 /* Probably should have a semaphore against multiple users */
648 len
= qc_capture(qcam
, buf
, count
);
649 parport_release(qcam
->pdev
);
650 mutex_unlock(&qcam
->lock
);
654 static int qcam_s_ctrl(struct v4l2_ctrl
*ctrl
)
657 container_of(ctrl
->handler
, struct qcam
, hdl
);
660 mutex_lock(&qcam
->lock
);
662 case V4L2_CID_BRIGHTNESS
:
663 qcam
->brightness
= ctrl
->val
;
665 case V4L2_CID_CONTRAST
:
666 qcam
->contrast
= ctrl
->val
;
669 qcam
->whitebal
= ctrl
->val
;
676 parport_claim_or_block(qcam
->pdev
);
678 parport_release(qcam
->pdev
);
680 mutex_unlock(&qcam
->lock
);
684 static const struct v4l2_file_operations qcam_fops
= {
685 .owner
= THIS_MODULE
,
686 .open
= v4l2_fh_open
,
687 .release
= v4l2_fh_release
,
688 .poll
= v4l2_ctrl_poll
,
689 .unlocked_ioctl
= video_ioctl2
,
693 static const struct v4l2_ioctl_ops qcam_ioctl_ops
= {
694 .vidioc_querycap
= qcam_querycap
,
695 .vidioc_g_input
= qcam_g_input
,
696 .vidioc_s_input
= qcam_s_input
,
697 .vidioc_enum_input
= qcam_enum_input
,
698 .vidioc_enum_fmt_vid_cap
= qcam_enum_fmt_vid_cap
,
699 .vidioc_g_fmt_vid_cap
= qcam_g_fmt_vid_cap
,
700 .vidioc_s_fmt_vid_cap
= qcam_s_fmt_vid_cap
,
701 .vidioc_try_fmt_vid_cap
= qcam_try_fmt_vid_cap
,
702 .vidioc_log_status
= v4l2_ctrl_log_status
,
703 .vidioc_subscribe_event
= v4l2_ctrl_subscribe_event
,
704 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
707 static const struct v4l2_ctrl_ops qcam_ctrl_ops
= {
708 .s_ctrl
= qcam_s_ctrl
,
711 /* Initialize the QuickCam driver control structure. */
713 static struct qcam
*qcam_init(struct parport
*port
)
716 struct v4l2_device
*v4l2_dev
;
718 qcam
= kzalloc(sizeof(*qcam
), GFP_KERNEL
);
722 v4l2_dev
= &qcam
->v4l2_dev
;
723 strlcpy(v4l2_dev
->name
, "c-qcam", sizeof(v4l2_dev
->name
));
725 if (v4l2_device_register(NULL
, v4l2_dev
) < 0) {
726 v4l2_err(v4l2_dev
, "Could not register v4l2_device\n");
731 v4l2_ctrl_handler_init(&qcam
->hdl
, 3);
732 v4l2_ctrl_new_std(&qcam
->hdl
, &qcam_ctrl_ops
,
733 V4L2_CID_BRIGHTNESS
, 0, 255, 1, 240);
734 v4l2_ctrl_new_std(&qcam
->hdl
, &qcam_ctrl_ops
,
735 V4L2_CID_CONTRAST
, 0, 255, 1, 192);
736 v4l2_ctrl_new_std(&qcam
->hdl
, &qcam_ctrl_ops
,
737 V4L2_CID_GAMMA
, 0, 255, 1, 128);
738 if (qcam
->hdl
.error
) {
739 v4l2_err(v4l2_dev
, "couldn't register controls\n");
740 v4l2_ctrl_handler_free(&qcam
->hdl
);
746 qcam
->pdev
= parport_register_device(port
, "c-qcam", NULL
, NULL
,
749 qcam
->bidirectional
= (qcam
->pport
->modes
& PARPORT_MODE_TRISTATE
) ? 1 : 0;
751 if (qcam
->pdev
== NULL
) {
752 v4l2_err(v4l2_dev
, "couldn't register for %s.\n", port
->name
);
753 v4l2_ctrl_handler_free(&qcam
->hdl
);
758 strlcpy(qcam
->vdev
.name
, "Colour QuickCam", sizeof(qcam
->vdev
.name
));
759 qcam
->vdev
.v4l2_dev
= v4l2_dev
;
760 qcam
->vdev
.fops
= &qcam_fops
;
761 qcam
->vdev
.ioctl_ops
= &qcam_ioctl_ops
;
762 qcam
->vdev
.release
= video_device_release_empty
;
763 qcam
->vdev
.ctrl_handler
= &qcam
->hdl
;
764 set_bit(V4L2_FL_USE_FH_PRIO
, &qcam
->vdev
.flags
);
765 video_set_drvdata(&qcam
->vdev
, qcam
);
767 mutex_init(&qcam
->lock
);
768 qcam
->width
= qcam
->ccd_width
= 320;
769 qcam
->height
= qcam
->ccd_height
= 240;
770 qcam
->mode
= QC_MILLIONS
| QC_DECIMATION_1
;
771 qcam
->contrast
= 192;
772 qcam
->brightness
= 240;
773 qcam
->whitebal
= 128;
779 static int init_cqcam(struct parport
*port
)
782 struct v4l2_device
*v4l2_dev
;
784 if (parport
[0] != -1) {
785 /* The user gave specific instructions */
788 for (i
= 0; i
< MAX_CAMS
&& parport
[i
] != -1; i
++) {
789 if (parport
[0] == port
->number
)
796 if (num_cams
== MAX_CAMS
)
799 qcam
= qcam_init(port
);
803 v4l2_dev
= &qcam
->v4l2_dev
;
805 parport_claim_or_block(qcam
->pdev
);
809 if (probe
&& qc_detect(qcam
) == 0) {
810 parport_release(qcam
->pdev
);
811 parport_unregister_device(qcam
->pdev
);
818 parport_release(qcam
->pdev
);
820 if (video_register_device(&qcam
->vdev
, VFL_TYPE_GRABBER
, video_nr
) < 0) {
821 v4l2_err(v4l2_dev
, "Unable to register Colour QuickCam on %s\n",
823 parport_unregister_device(qcam
->pdev
);
828 v4l2_info(v4l2_dev
, "%s: Colour QuickCam found on %s\n",
829 video_device_node_name(&qcam
->vdev
), qcam
->pport
->name
);
831 qcams
[num_cams
++] = qcam
;
836 static void close_cqcam(struct qcam
*qcam
)
838 video_unregister_device(&qcam
->vdev
);
839 v4l2_ctrl_handler_free(&qcam
->hdl
);
840 parport_unregister_device(qcam
->pdev
);
844 static void cq_attach(struct parport
*port
)
849 static void cq_detach(struct parport
*port
)
851 /* Write this some day. */
854 static struct parport_driver cqcam_driver
= {
860 static int __init
cqcam_init(void)
862 printk(KERN_INFO BANNER
"\n");
864 return parport_register_driver(&cqcam_driver
);
867 static void __exit
cqcam_cleanup(void)
871 for (i
= 0; i
< num_cams
; i
++)
872 close_cqcam(qcams
[i
]);
874 parport_unregister_driver(&cqcam_driver
);
877 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
878 MODULE_DESCRIPTION(BANNER
);
879 MODULE_LICENSE("GPL");
880 MODULE_VERSION("0.0.4");
882 module_init(cqcam_init
);
883 module_exit(cqcam_cleanup
);