Linux 3.12.39
[linux/fpc-iii.git] / drivers / media / parport / c-qcam.c
blobec51e1f12e823b47e7567f57884670a8f94364c9
1 /*
2 * Video4Linux Colour QuickCam driver
3 * Copyright 1997-2000 Philip Blundell <philb@gnu.org>
5 * Module parameters:
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>
29 #include <linux/fs.h>
30 #include <linux/init.h>
31 #include <linux/kernel.h>
32 #include <linux/slab.h>
33 #include <linux/mm.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>
47 struct qcam {
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;
53 int width, height;
54 int ccd_width, ccd_height;
55 int mode;
56 int contrast, brightness, whitebal;
57 int top, left;
58 unsigned int bidirectional;
59 struct mutex lock;
62 /* cameras maximum */
63 #define MAX_CAMS 4
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 };
78 static int probe = 2;
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;
115 unsigned int i;
117 for (oldjiffies = jiffies;
118 time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
119 if (qcam_ready1(qcam) == value)
120 return 0;
122 /* If the camera didn't respond within 1/25 second, poll slowly
123 for a while. */
124 for (i = 0; i < 50; i++) {
125 if (qcam_ready1(qcam) == value)
126 return 0;
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));
134 return 1;
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;
141 unsigned int i;
143 for (oldjiffies = jiffies;
144 time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
145 if (qcam_ready2(qcam) == value)
146 return 0;
148 /* If the camera didn't respond within 1/25 second, poll slowly
149 for a while. */
150 for (i = 0; i < 50; i++) {
151 if (qcam_ready2(qcam) == value)
152 return 0;
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));
161 return 1;
164 static int qcam_read_data(struct qcam *qcam)
166 unsigned int idata;
168 qcam_set_ack(qcam, 0);
169 if (qcam_await_ready1(qcam, 1))
170 return -1;
171 idata = parport_read_status(qcam->pport) & 0xf0;
172 qcam_set_ack(qcam, 1);
173 if (qcam_await_ready1(qcam, 0))
174 return -1;
175 idata |= parport_read_status(qcam->pport) >> 4;
176 return idata;
179 static int qcam_write_data(struct qcam *qcam, unsigned int data)
181 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
182 unsigned int idata;
184 parport_write_data(qcam->pport, data);
185 idata = qcam_read_data(qcam);
186 if (data != idata) {
187 v4l2_warn(v4l2_dev, "sent %x but received %x\n", data,
188 idata);
189 return 1;
191 return 0;
194 static inline int qcam_set(struct qcam *qcam, unsigned int cmd, unsigned int data)
196 if (qcam_write_data(qcam, cmd))
197 return -1;
198 if (qcam_write_data(qcam, data))
199 return -1;
200 return 0;
203 static inline int qcam_get(struct qcam *qcam, unsigned int cmd)
205 if (qcam_write_data(qcam, cmd))
206 return -1;
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");
224 return 1;
227 if (probe < 2)
228 return 0;
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++) {
235 mdelay(1);
236 stat = parport_read_status(qcam->pport);
237 if (ostat != stat) {
238 if (++count >= 3)
239 return 1;
240 ostat = stat;
244 /* Reset the camera and try again */
245 parport_write_control(qcam->pport, 0xc);
246 parport_write_control(qcam->pport, 0x8);
247 mdelay(1);
248 parport_write_control(qcam->pport, 0xc);
249 mdelay(1);
250 count = 0;
252 ostat = stat = parport_read_status(qcam->pport);
253 for (i = 0; i < 250; i++) {
254 mdelay(1);
255 stat = parport_read_status(qcam->pport);
256 if (ostat != stat) {
257 if (++count >= 3)
258 return 1;
259 ostat = stat;
263 /* no (or flatline) camera, give up */
264 return 0;
267 static void qc_reset(struct qcam *qcam)
269 parport_write_control(qcam->pport, 0xc);
270 parport_write_control(qcam->pport, 0x8);
271 mdelay(1);
272 parport_write_control(qcam->pport, 0xc);
273 mdelay(1);
276 /* Reset the QuickCam and program for brightness, contrast,
277 * white-balance, and resolution. */
279 static void qc_setup(struct qcam *qcam)
281 qc_reset(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);
299 /* Set the speed. */
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))
319 return bytes;
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))
324 return bytes;
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);
331 if (force_rgb) {
332 buf[bytes++] = r;
333 buf[bytes++] = g;
334 buf[bytes++] = b;
335 } else {
336 buf[bytes++] = b;
337 buf[bytes++] = g;
338 buf[bytes++] = r;
341 } else {
342 /* It's a unidirectional port */
343 int i = 0, n = bytes;
344 unsigned char rgb[3];
346 while (bytes < nbytes) {
347 unsigned int hi, lo;
349 if (qcam_await_ready1(qcam, 1))
350 return bytes;
351 hi = (parport_read_status(qcam->pport) & 0xf0);
352 qcam_set_ack(qcam, 1);
353 if (qcam_await_ready1(qcam, 0))
354 return bytes;
355 lo = (parport_read_status(qcam->pport) & 0xf0);
356 qcam_set_ack(qcam, 0);
357 /* flip some bits */
358 rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
359 if (i >= 2) {
360 get_fragment:
361 if (force_rgb) {
362 buf[n++] = rgb[0];
363 buf[n++] = rgb[1];
364 buf[n++] = rgb[2];
365 } else {
366 buf[n++] = rgb[2];
367 buf[n++] = rgb[1];
368 buf[n++] = rgb[0];
372 if (i) {
373 i = 0;
374 goto get_fragment;
377 return bytes;
380 #define BUFSZ 150
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;
388 char tmpbuf[BUFSZ];
390 if (!access_ok(VERIFY_WRITE, buf, len))
391 return -EFAULT;
393 /* Wait for camera to become ready */
394 for (;;) {
395 int i = qcam_get(qcam, 41);
397 if (i == -1) {
398 qc_setup(qcam);
399 return -EIO;
401 if ((i & 0x80) == 0)
402 break;
403 schedule();
406 if (qcam_set(qcam, 7, (qcam->mode | (is_bi_dir ? 1 : 0)) + 1))
407 return -EIO;
409 lines = qcam->height;
410 pixelsperline = qcam->width;
412 if (is_bi_dir) {
413 /* Turn the port around */
414 parport_data_reverse(qcam->pport);
415 mdelay(3);
416 qcam_set_ack(qcam, 0);
417 if (qcam_await_ready1(qcam, 1)) {
418 qc_setup(qcam);
419 return -EIO;
421 qcam_set_ack(qcam, 1);
422 if (qcam_await_ready1(qcam, 0)) {
423 qc_setup(qcam);
424 return -EIO;
428 wantlen = lines * pixelsperline * 24 / 8;
430 while (wantlen) {
431 size_t t, s;
433 s = (wantlen > BUFSZ) ? BUFSZ : wantlen;
434 t = qcam_read_bytes(qcam, tmpbuf, s);
435 if (outptr < len) {
436 size_t sz = len - outptr;
438 if (sz > t)
439 sz = t;
440 if (__copy_to_user(buf + outptr, tmpbuf, sz))
441 break;
442 outptr += sz;
444 wantlen -= t;
445 if (t < s)
446 break;
447 cond_resched();
450 len = outptr;
452 if (wantlen) {
453 v4l2_err(v4l2_dev, "short read.\n");
454 if (is_bi_dir)
455 parport_data_forward(qcam->pport);
456 qc_setup(qcam);
457 return len;
460 if (is_bi_dir) {
461 int l;
463 do {
464 l = qcam_read_bytes(qcam, tmpbuf, 3);
465 cond_resched();
466 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
467 if (force_rgb) {
468 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
469 v4l2_err(v4l2_dev, "bad EOF\n");
470 } else {
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);
478 qc_setup(qcam);
479 return len;
481 parport_data_forward(qcam->pport);
482 mdelay(3);
483 qcam_set_ack(qcam, 1);
484 if (qcam_await_ready1(qcam, 0)) {
485 v4l2_err(v4l2_dev, "no ack to port turnaround\n");
486 qc_setup(qcam);
487 return len;
489 } else {
490 int l;
492 do {
493 l = qcam_read_bytes(qcam, tmpbuf, 1);
494 cond_resched();
495 } while (l && tmpbuf[0] == 0x7e);
496 l = qcam_read_bytes(qcam, tmpbuf + 1, 2);
497 if (force_rgb) {
498 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
499 v4l2_err(v4l2_dev, "bad EOF\n");
500 } else {
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);
507 return len;
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;
524 return 0;
527 static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
529 if (vin->index > 0)
530 return -EINVAL;
531 strlcpy(vin->name, "Camera", sizeof(vin->name));
532 vin->type = V4L2_INPUT_TYPE_CAMERA;
533 vin->audioset = 0;
534 vin->tuner = 0;
535 vin->std = 0;
536 vin->status = 0;
537 return 0;
540 static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
542 *inp = 0;
543 return 0;
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;
562 /* Just a guess */
563 pix->colorspace = V4L2_COLORSPACE_SRGB;
564 return 0;
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) {
572 pix->height = 60;
573 pix->width = 80;
574 } else if (pix->height < 120 || pix->width < 160) {
575 pix->height = 120;
576 pix->width = 160;
577 } else {
578 pix->height = 240;
579 pix->width = 320;
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;
585 /* Just a guess */
586 pix->colorspace = V4L2_COLORSPACE_SRGB;
587 return 0;
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);
596 if (ret)
597 return ret;
598 switch (pix->height) {
599 case 60:
600 qcam->mode = QC_DECIMATION_4;
601 break;
602 case 120:
603 qcam->mode = QC_DECIMATION_2;
604 break;
605 default:
606 qcam->mode = QC_DECIMATION_1;
607 break;
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);
615 qc_setup(qcam);
616 parport_release(qcam->pdev);
617 mutex_unlock(&qcam->lock);
618 return 0;
621 static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
623 static struct v4l2_fmtdesc formats[] = {
624 { 0, 0, 0,
625 "RGB 8:8:8", V4L2_PIX_FMT_RGB24,
626 { 0, 0, 0, 0 }
629 enum v4l2_buf_type type = fmt->type;
631 if (fmt->index > 0)
632 return -EINVAL;
634 *fmt = formats[fmt->index];
635 fmt->type = type;
636 return 0;
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);
643 int len;
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);
651 return len;
654 static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
656 struct qcam *qcam =
657 container_of(ctrl->handler, struct qcam, hdl);
658 int ret = 0;
660 mutex_lock(&qcam->lock);
661 switch (ctrl->id) {
662 case V4L2_CID_BRIGHTNESS:
663 qcam->brightness = ctrl->val;
664 break;
665 case V4L2_CID_CONTRAST:
666 qcam->contrast = ctrl->val;
667 break;
668 case V4L2_CID_GAMMA:
669 qcam->whitebal = ctrl->val;
670 break;
671 default:
672 ret = -EINVAL;
673 break;
675 if (ret == 0) {
676 parport_claim_or_block(qcam->pdev);
677 qc_setup(qcam);
678 parport_release(qcam->pdev);
680 mutex_unlock(&qcam->lock);
681 return ret;
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,
690 .read = qcam_read,
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)
715 struct qcam *qcam;
716 struct v4l2_device *v4l2_dev;
718 qcam = kzalloc(sizeof(*qcam), GFP_KERNEL);
719 if (qcam == NULL)
720 return NULL;
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");
727 kfree(qcam);
728 return NULL;
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);
741 kfree(qcam);
742 return NULL;
745 qcam->pport = port;
746 qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
747 NULL, 0, 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);
754 kfree(qcam);
755 return NULL;
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;
774 qcam->top = 1;
775 qcam->left = 14;
776 return qcam;
779 static int init_cqcam(struct parport *port)
781 struct qcam *qcam;
782 struct v4l2_device *v4l2_dev;
784 if (parport[0] != -1) {
785 /* The user gave specific instructions */
786 int i, found = 0;
788 for (i = 0; i < MAX_CAMS && parport[i] != -1; i++) {
789 if (parport[0] == port->number)
790 found = 1;
792 if (!found)
793 return -ENODEV;
796 if (num_cams == MAX_CAMS)
797 return -ENOSPC;
799 qcam = qcam_init(port);
800 if (qcam == NULL)
801 return -ENODEV;
803 v4l2_dev = &qcam->v4l2_dev;
805 parport_claim_or_block(qcam->pdev);
807 qc_reset(qcam);
809 if (probe && qc_detect(qcam) == 0) {
810 parport_release(qcam->pdev);
811 parport_unregister_device(qcam->pdev);
812 kfree(qcam);
813 return -ENODEV;
816 qc_setup(qcam);
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",
822 qcam->pport->name);
823 parport_unregister_device(qcam->pdev);
824 kfree(qcam);
825 return -ENODEV;
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;
833 return 0;
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);
841 kfree(qcam);
844 static void cq_attach(struct parport *port)
846 init_cqcam(port);
849 static void cq_detach(struct parport *port)
851 /* Write this some day. */
854 static struct parport_driver cqcam_driver = {
855 .name = "cqcam",
856 .attach = cq_attach,
857 .detach = cq_detach,
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)
869 unsigned int i;
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);