Merge branch 'v6v7' into devel
[linux/fpc-iii.git] / drivers / media / video / c-qcam.c
blob24fc00965a12d048be055498230b734b794283fa
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/version.h>
39 #include <linux/videodev2.h>
40 #include <asm/uaccess.h>
41 #include <media/v4l2-device.h>
42 #include <media/v4l2-common.h>
43 #include <media/v4l2-ioctl.h>
45 struct qcam {
46 struct v4l2_device v4l2_dev;
47 struct video_device vdev;
48 struct pardevice *pdev;
49 struct parport *pport;
50 int width, height;
51 int ccd_width, ccd_height;
52 int mode;
53 int contrast, brightness, whitebal;
54 int top, left;
55 unsigned int bidirectional;
56 struct mutex lock;
59 /* cameras maximum */
60 #define MAX_CAMS 4
62 /* The three possible QuickCam modes */
63 #define QC_MILLIONS 0x18
64 #define QC_BILLIONS 0x10
65 #define QC_THOUSANDS 0x08 /* with VIDEC compression (not supported) */
67 /* The three possible decimations */
68 #define QC_DECIMATION_1 0
69 #define QC_DECIMATION_2 2
70 #define QC_DECIMATION_4 4
72 #define BANNER "Colour QuickCam for Video4Linux v0.06"
74 static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
75 static int probe = 2;
76 static int force_rgb;
77 static int video_nr = -1;
79 /* FIXME: parport=auto would never have worked, surely? --RR */
80 MODULE_PARM_DESC(parport, "parport=<auto|n[,n]...> for port detection method\n"
81 "probe=<0|1|2> for camera detection method\n"
82 "force_rgb=<0|1> for RGB data format (default BGR)");
83 module_param_array(parport, int, NULL, 0);
84 module_param(probe, int, 0);
85 module_param(force_rgb, bool, 0);
86 module_param(video_nr, int, 0);
88 static struct qcam *qcams[MAX_CAMS];
89 static unsigned int num_cams;
91 static inline void qcam_set_ack(struct qcam *qcam, unsigned int i)
93 /* note: the QC specs refer to the PCAck pin by voltage, not
94 software level. PC ports have builtin inverters. */
95 parport_frob_control(qcam->pport, 8, i ? 8 : 0);
98 static inline unsigned int qcam_ready1(struct qcam *qcam)
100 return (parport_read_status(qcam->pport) & 0x8) ? 1 : 0;
103 static inline unsigned int qcam_ready2(struct qcam *qcam)
105 return (parport_read_data(qcam->pport) & 0x1) ? 1 : 0;
108 static unsigned int qcam_await_ready1(struct qcam *qcam, int value)
110 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
111 unsigned long oldjiffies = jiffies;
112 unsigned int i;
114 for (oldjiffies = jiffies;
115 time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
116 if (qcam_ready1(qcam) == value)
117 return 0;
119 /* If the camera didn't respond within 1/25 second, poll slowly
120 for a while. */
121 for (i = 0; i < 50; i++) {
122 if (qcam_ready1(qcam) == value)
123 return 0;
124 msleep_interruptible(100);
127 /* Probably somebody pulled the plug out. Not much we can do. */
128 v4l2_err(v4l2_dev, "ready1 timeout (%d) %x %x\n", value,
129 parport_read_status(qcam->pport),
130 parport_read_control(qcam->pport));
131 return 1;
134 static unsigned int qcam_await_ready2(struct qcam *qcam, int value)
136 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
137 unsigned long oldjiffies = jiffies;
138 unsigned int i;
140 for (oldjiffies = jiffies;
141 time_before(jiffies, oldjiffies + msecs_to_jiffies(40));)
142 if (qcam_ready2(qcam) == value)
143 return 0;
145 /* If the camera didn't respond within 1/25 second, poll slowly
146 for a while. */
147 for (i = 0; i < 50; i++) {
148 if (qcam_ready2(qcam) == value)
149 return 0;
150 msleep_interruptible(100);
153 /* Probably somebody pulled the plug out. Not much we can do. */
154 v4l2_err(v4l2_dev, "ready2 timeout (%d) %x %x %x\n", value,
155 parport_read_status(qcam->pport),
156 parport_read_control(qcam->pport),
157 parport_read_data(qcam->pport));
158 return 1;
161 static int qcam_read_data(struct qcam *qcam)
163 unsigned int idata;
165 qcam_set_ack(qcam, 0);
166 if (qcam_await_ready1(qcam, 1))
167 return -1;
168 idata = parport_read_status(qcam->pport) & 0xf0;
169 qcam_set_ack(qcam, 1);
170 if (qcam_await_ready1(qcam, 0))
171 return -1;
172 idata |= parport_read_status(qcam->pport) >> 4;
173 return idata;
176 static int qcam_write_data(struct qcam *qcam, unsigned int data)
178 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
179 unsigned int idata;
181 parport_write_data(qcam->pport, data);
182 idata = qcam_read_data(qcam);
183 if (data != idata) {
184 v4l2_warn(v4l2_dev, "sent %x but received %x\n", data,
185 idata);
186 return 1;
188 return 0;
191 static inline int qcam_set(struct qcam *qcam, unsigned int cmd, unsigned int data)
193 if (qcam_write_data(qcam, cmd))
194 return -1;
195 if (qcam_write_data(qcam, data))
196 return -1;
197 return 0;
200 static inline int qcam_get(struct qcam *qcam, unsigned int cmd)
202 if (qcam_write_data(qcam, cmd))
203 return -1;
204 return qcam_read_data(qcam);
207 static int qc_detect(struct qcam *qcam)
209 unsigned int stat, ostat, i, count = 0;
211 /* The probe routine below is not very reliable. The IEEE-1284
212 probe takes precedence. */
213 /* XXX Currently parport provides no way to distinguish between
214 "the IEEE probe was not done" and "the probe was done, but
215 no device was found". Fix this one day. */
216 if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
217 && qcam->pport->probe_info[0].model
218 && !strcmp(qcam->pdev->port->probe_info[0].model,
219 "Color QuickCam 2.0")) {
220 printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
221 return 1;
224 if (probe < 2)
225 return 0;
227 parport_write_control(qcam->pport, 0xc);
229 /* look for a heartbeat */
230 ostat = stat = parport_read_status(qcam->pport);
231 for (i = 0; i < 250; i++) {
232 mdelay(1);
233 stat = parport_read_status(qcam->pport);
234 if (ostat != stat) {
235 if (++count >= 3)
236 return 1;
237 ostat = stat;
241 /* Reset the camera and try again */
242 parport_write_control(qcam->pport, 0xc);
243 parport_write_control(qcam->pport, 0x8);
244 mdelay(1);
245 parport_write_control(qcam->pport, 0xc);
246 mdelay(1);
247 count = 0;
249 ostat = stat = parport_read_status(qcam->pport);
250 for (i = 0; i < 250; i++) {
251 mdelay(1);
252 stat = parport_read_status(qcam->pport);
253 if (ostat != stat) {
254 if (++count >= 3)
255 return 1;
256 ostat = stat;
260 /* no (or flatline) camera, give up */
261 return 0;
264 static void qc_reset(struct qcam *qcam)
266 parport_write_control(qcam->pport, 0xc);
267 parport_write_control(qcam->pport, 0x8);
268 mdelay(1);
269 parport_write_control(qcam->pport, 0xc);
270 mdelay(1);
273 /* Reset the QuickCam and program for brightness, contrast,
274 * white-balance, and resolution. */
276 static void qc_setup(struct qcam *qcam)
278 qc_reset(qcam);
280 /* Set the brightness. */
281 qcam_set(qcam, 11, qcam->brightness);
283 /* Set the height and width. These refer to the actual
284 CCD area *before* applying the selected decimation. */
285 qcam_set(qcam, 17, qcam->ccd_height);
286 qcam_set(qcam, 19, qcam->ccd_width / 2);
288 /* Set top and left. */
289 qcam_set(qcam, 0xd, qcam->top);
290 qcam_set(qcam, 0xf, qcam->left);
292 /* Set contrast and white balance. */
293 qcam_set(qcam, 0x19, qcam->contrast);
294 qcam_set(qcam, 0x1f, qcam->whitebal);
296 /* Set the speed. */
297 qcam_set(qcam, 45, 2);
300 /* Read some bytes from the camera and put them in the buffer.
301 nbytes should be a multiple of 3, because bidirectional mode gives
302 us three bytes at a time. */
304 static unsigned int qcam_read_bytes(struct qcam *qcam, unsigned char *buf, unsigned int nbytes)
306 unsigned int bytes = 0;
308 qcam_set_ack(qcam, 0);
309 if (qcam->bidirectional) {
310 /* It's a bidirectional port */
311 while (bytes < nbytes) {
312 unsigned int lo1, hi1, lo2, hi2;
313 unsigned char r, g, b;
315 if (qcam_await_ready2(qcam, 1))
316 return bytes;
317 lo1 = parport_read_data(qcam->pport) >> 1;
318 hi1 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
319 qcam_set_ack(qcam, 1);
320 if (qcam_await_ready2(qcam, 0))
321 return bytes;
322 lo2 = parport_read_data(qcam->pport) >> 1;
323 hi2 = ((parport_read_status(qcam->pport) >> 3) & 0x1f) ^ 0x10;
324 qcam_set_ack(qcam, 0);
325 r = lo1 | ((hi1 & 1) << 7);
326 g = ((hi1 & 0x1e) << 3) | ((hi2 & 0x1e) >> 1);
327 b = lo2 | ((hi2 & 1) << 7);
328 if (force_rgb) {
329 buf[bytes++] = r;
330 buf[bytes++] = g;
331 buf[bytes++] = b;
332 } else {
333 buf[bytes++] = b;
334 buf[bytes++] = g;
335 buf[bytes++] = r;
338 } else {
339 /* It's a unidirectional port */
340 int i = 0, n = bytes;
341 unsigned char rgb[3];
343 while (bytes < nbytes) {
344 unsigned int hi, lo;
346 if (qcam_await_ready1(qcam, 1))
347 return bytes;
348 hi = (parport_read_status(qcam->pport) & 0xf0);
349 qcam_set_ack(qcam, 1);
350 if (qcam_await_ready1(qcam, 0))
351 return bytes;
352 lo = (parport_read_status(qcam->pport) & 0xf0);
353 qcam_set_ack(qcam, 0);
354 /* flip some bits */
355 rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
356 if (i >= 2) {
357 get_fragment:
358 if (force_rgb) {
359 buf[n++] = rgb[0];
360 buf[n++] = rgb[1];
361 buf[n++] = rgb[2];
362 } else {
363 buf[n++] = rgb[2];
364 buf[n++] = rgb[1];
365 buf[n++] = rgb[0];
369 if (i) {
370 i = 0;
371 goto get_fragment;
374 return bytes;
377 #define BUFSZ 150
379 static long qc_capture(struct qcam *qcam, char __user *buf, unsigned long len)
381 struct v4l2_device *v4l2_dev = &qcam->v4l2_dev;
382 unsigned lines, pixelsperline, bitsperxfer;
383 unsigned int is_bi_dir = qcam->bidirectional;
384 size_t wantlen, outptr = 0;
385 char tmpbuf[BUFSZ];
387 if (!access_ok(VERIFY_WRITE, buf, len))
388 return -EFAULT;
390 /* Wait for camera to become ready */
391 for (;;) {
392 int i = qcam_get(qcam, 41);
394 if (i == -1) {
395 qc_setup(qcam);
396 return -EIO;
398 if ((i & 0x80) == 0)
399 break;
400 schedule();
403 if (qcam_set(qcam, 7, (qcam->mode | (is_bi_dir ? 1 : 0)) + 1))
404 return -EIO;
406 lines = qcam->height;
407 pixelsperline = qcam->width;
408 bitsperxfer = (is_bi_dir) ? 24 : 8;
410 if (is_bi_dir) {
411 /* Turn the port around */
412 parport_data_reverse(qcam->pport);
413 mdelay(3);
414 qcam_set_ack(qcam, 0);
415 if (qcam_await_ready1(qcam, 1)) {
416 qc_setup(qcam);
417 return -EIO;
419 qcam_set_ack(qcam, 1);
420 if (qcam_await_ready1(qcam, 0)) {
421 qc_setup(qcam);
422 return -EIO;
426 wantlen = lines * pixelsperline * 24 / 8;
428 while (wantlen) {
429 size_t t, s;
431 s = (wantlen > BUFSZ) ? BUFSZ : wantlen;
432 t = qcam_read_bytes(qcam, tmpbuf, s);
433 if (outptr < len) {
434 size_t sz = len - outptr;
436 if (sz > t)
437 sz = t;
438 if (__copy_to_user(buf + outptr, tmpbuf, sz))
439 break;
440 outptr += sz;
442 wantlen -= t;
443 if (t < s)
444 break;
445 cond_resched();
448 len = outptr;
450 if (wantlen) {
451 v4l2_err(v4l2_dev, "short read.\n");
452 if (is_bi_dir)
453 parport_data_forward(qcam->pport);
454 qc_setup(qcam);
455 return len;
458 if (is_bi_dir) {
459 int l;
461 do {
462 l = qcam_read_bytes(qcam, tmpbuf, 3);
463 cond_resched();
464 } while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
465 if (force_rgb) {
466 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
467 v4l2_err(v4l2_dev, "bad EOF\n");
468 } else {
469 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
470 v4l2_err(v4l2_dev, "bad EOF\n");
472 qcam_set_ack(qcam, 0);
473 if (qcam_await_ready1(qcam, 1)) {
474 v4l2_err(v4l2_dev, "no ack after EOF\n");
475 parport_data_forward(qcam->pport);
476 qc_setup(qcam);
477 return len;
479 parport_data_forward(qcam->pport);
480 mdelay(3);
481 qcam_set_ack(qcam, 1);
482 if (qcam_await_ready1(qcam, 0)) {
483 v4l2_err(v4l2_dev, "no ack to port turnaround\n");
484 qc_setup(qcam);
485 return len;
487 } else {
488 int l;
490 do {
491 l = qcam_read_bytes(qcam, tmpbuf, 1);
492 cond_resched();
493 } while (l && tmpbuf[0] == 0x7e);
494 l = qcam_read_bytes(qcam, tmpbuf + 1, 2);
495 if (force_rgb) {
496 if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
497 v4l2_err(v4l2_dev, "bad EOF\n");
498 } else {
499 if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
500 v4l2_err(v4l2_dev, "bad EOF\n");
504 qcam_write_data(qcam, 0);
505 return len;
509 * Video4linux interfacing
512 static int qcam_querycap(struct file *file, void *priv,
513 struct v4l2_capability *vcap)
515 struct qcam *qcam = video_drvdata(file);
517 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
518 strlcpy(vcap->card, "Color Quickcam", sizeof(vcap->card));
519 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
520 vcap->version = KERNEL_VERSION(0, 0, 3);
521 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
522 return 0;
525 static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
527 if (vin->index > 0)
528 return -EINVAL;
529 strlcpy(vin->name, "Camera", sizeof(vin->name));
530 vin->type = V4L2_INPUT_TYPE_CAMERA;
531 vin->audioset = 0;
532 vin->tuner = 0;
533 vin->std = 0;
534 vin->status = 0;
535 return 0;
538 static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
540 *inp = 0;
541 return 0;
544 static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
546 return (inp > 0) ? -EINVAL : 0;
549 static int qcam_queryctrl(struct file *file, void *priv,
550 struct v4l2_queryctrl *qc)
552 switch (qc->id) {
553 case V4L2_CID_BRIGHTNESS:
554 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 240);
555 case V4L2_CID_CONTRAST:
556 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
557 case V4L2_CID_GAMMA:
558 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
560 return -EINVAL;
563 static int qcam_g_ctrl(struct file *file, void *priv,
564 struct v4l2_control *ctrl)
566 struct qcam *qcam = video_drvdata(file);
567 int ret = 0;
569 switch (ctrl->id) {
570 case V4L2_CID_BRIGHTNESS:
571 ctrl->value = qcam->brightness;
572 break;
573 case V4L2_CID_CONTRAST:
574 ctrl->value = qcam->contrast;
575 break;
576 case V4L2_CID_GAMMA:
577 ctrl->value = qcam->whitebal;
578 break;
579 default:
580 ret = -EINVAL;
581 break;
583 return ret;
586 static int qcam_s_ctrl(struct file *file, void *priv,
587 struct v4l2_control *ctrl)
589 struct qcam *qcam = video_drvdata(file);
590 int ret = 0;
592 mutex_lock(&qcam->lock);
593 switch (ctrl->id) {
594 case V4L2_CID_BRIGHTNESS:
595 qcam->brightness = ctrl->value;
596 break;
597 case V4L2_CID_CONTRAST:
598 qcam->contrast = ctrl->value;
599 break;
600 case V4L2_CID_GAMMA:
601 qcam->whitebal = ctrl->value;
602 break;
603 default:
604 ret = -EINVAL;
605 break;
607 if (ret == 0) {
608 parport_claim_or_block(qcam->pdev);
609 qc_setup(qcam);
610 parport_release(qcam->pdev);
612 mutex_unlock(&qcam->lock);
613 return ret;
616 static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
618 struct qcam *qcam = video_drvdata(file);
619 struct v4l2_pix_format *pix = &fmt->fmt.pix;
621 pix->width = qcam->width;
622 pix->height = qcam->height;
623 pix->pixelformat = V4L2_PIX_FMT_RGB24;
624 pix->field = V4L2_FIELD_NONE;
625 pix->bytesperline = 3 * qcam->width;
626 pix->sizeimage = 3 * qcam->width * qcam->height;
627 /* Just a guess */
628 pix->colorspace = V4L2_COLORSPACE_SRGB;
629 return 0;
632 static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
634 struct v4l2_pix_format *pix = &fmt->fmt.pix;
636 if (pix->height < 60 || pix->width < 80) {
637 pix->height = 60;
638 pix->width = 80;
639 } else if (pix->height < 120 || pix->width < 160) {
640 pix->height = 120;
641 pix->width = 160;
642 } else {
643 pix->height = 240;
644 pix->width = 320;
646 pix->pixelformat = V4L2_PIX_FMT_RGB24;
647 pix->field = V4L2_FIELD_NONE;
648 pix->bytesperline = 3 * pix->width;
649 pix->sizeimage = 3 * pix->width * pix->height;
650 /* Just a guess */
651 pix->colorspace = V4L2_COLORSPACE_SRGB;
652 return 0;
655 static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
657 struct qcam *qcam = video_drvdata(file);
658 struct v4l2_pix_format *pix = &fmt->fmt.pix;
659 int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
661 if (ret)
662 return ret;
663 switch (pix->height) {
664 case 60:
665 qcam->mode = QC_DECIMATION_4;
666 break;
667 case 120:
668 qcam->mode = QC_DECIMATION_2;
669 break;
670 default:
671 qcam->mode = QC_DECIMATION_1;
672 break;
675 mutex_lock(&qcam->lock);
676 qcam->mode |= QC_MILLIONS;
677 qcam->height = pix->height;
678 qcam->width = pix->width;
679 parport_claim_or_block(qcam->pdev);
680 qc_setup(qcam);
681 parport_release(qcam->pdev);
682 mutex_unlock(&qcam->lock);
683 return 0;
686 static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
688 static struct v4l2_fmtdesc formats[] = {
689 { 0, 0, 0,
690 "RGB 8:8:8", V4L2_PIX_FMT_RGB24,
691 { 0, 0, 0, 0 }
694 enum v4l2_buf_type type = fmt->type;
696 if (fmt->index > 0)
697 return -EINVAL;
699 *fmt = formats[fmt->index];
700 fmt->type = type;
701 return 0;
704 static ssize_t qcam_read(struct file *file, char __user *buf,
705 size_t count, loff_t *ppos)
707 struct qcam *qcam = video_drvdata(file);
708 int len;
710 mutex_lock(&qcam->lock);
711 parport_claim_or_block(qcam->pdev);
712 /* Probably should have a semaphore against multiple users */
713 len = qc_capture(qcam, buf, count);
714 parport_release(qcam->pdev);
715 mutex_unlock(&qcam->lock);
716 return len;
719 static const struct v4l2_file_operations qcam_fops = {
720 .owner = THIS_MODULE,
721 .unlocked_ioctl = video_ioctl2,
722 .read = qcam_read,
725 static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
726 .vidioc_querycap = qcam_querycap,
727 .vidioc_g_input = qcam_g_input,
728 .vidioc_s_input = qcam_s_input,
729 .vidioc_enum_input = qcam_enum_input,
730 .vidioc_queryctrl = qcam_queryctrl,
731 .vidioc_g_ctrl = qcam_g_ctrl,
732 .vidioc_s_ctrl = qcam_s_ctrl,
733 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
734 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
735 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
736 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
739 /* Initialize the QuickCam driver control structure. */
741 static struct qcam *qcam_init(struct parport *port)
743 struct qcam *qcam;
744 struct v4l2_device *v4l2_dev;
746 qcam = kzalloc(sizeof(*qcam), GFP_KERNEL);
747 if (qcam == NULL)
748 return NULL;
750 v4l2_dev = &qcam->v4l2_dev;
751 strlcpy(v4l2_dev->name, "c-qcam", sizeof(v4l2_dev->name));
753 if (v4l2_device_register(NULL, v4l2_dev) < 0) {
754 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
755 return NULL;
758 qcam->pport = port;
759 qcam->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
760 NULL, 0, NULL);
762 qcam->bidirectional = (qcam->pport->modes & PARPORT_MODE_TRISTATE) ? 1 : 0;
764 if (qcam->pdev == NULL) {
765 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
766 kfree(qcam);
767 return NULL;
770 strlcpy(qcam->vdev.name, "Colour QuickCam", sizeof(qcam->vdev.name));
771 qcam->vdev.v4l2_dev = v4l2_dev;
772 qcam->vdev.fops = &qcam_fops;
773 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
774 qcam->vdev.release = video_device_release_empty;
775 video_set_drvdata(&qcam->vdev, qcam);
777 mutex_init(&qcam->lock);
778 qcam->width = qcam->ccd_width = 320;
779 qcam->height = qcam->ccd_height = 240;
780 qcam->mode = QC_MILLIONS | QC_DECIMATION_1;
781 qcam->contrast = 192;
782 qcam->brightness = 240;
783 qcam->whitebal = 128;
784 qcam->top = 1;
785 qcam->left = 14;
786 return qcam;
789 static int init_cqcam(struct parport *port)
791 struct qcam *qcam;
792 struct v4l2_device *v4l2_dev;
794 if (parport[0] != -1) {
795 /* The user gave specific instructions */
796 int i, found = 0;
798 for (i = 0; i < MAX_CAMS && parport[i] != -1; i++) {
799 if (parport[0] == port->number)
800 found = 1;
802 if (!found)
803 return -ENODEV;
806 if (num_cams == MAX_CAMS)
807 return -ENOSPC;
809 qcam = qcam_init(port);
810 if (qcam == NULL)
811 return -ENODEV;
813 v4l2_dev = &qcam->v4l2_dev;
815 parport_claim_or_block(qcam->pdev);
817 qc_reset(qcam);
819 if (probe && qc_detect(qcam) == 0) {
820 parport_release(qcam->pdev);
821 parport_unregister_device(qcam->pdev);
822 kfree(qcam);
823 return -ENODEV;
826 qc_setup(qcam);
828 parport_release(qcam->pdev);
830 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
831 v4l2_err(v4l2_dev, "Unable to register Colour QuickCam on %s\n",
832 qcam->pport->name);
833 parport_unregister_device(qcam->pdev);
834 kfree(qcam);
835 return -ENODEV;
838 v4l2_info(v4l2_dev, "%s: Colour QuickCam found on %s\n",
839 video_device_node_name(&qcam->vdev), qcam->pport->name);
841 qcams[num_cams++] = qcam;
843 return 0;
846 static void close_cqcam(struct qcam *qcam)
848 video_unregister_device(&qcam->vdev);
849 parport_unregister_device(qcam->pdev);
850 kfree(qcam);
853 static void cq_attach(struct parport *port)
855 init_cqcam(port);
858 static void cq_detach(struct parport *port)
860 /* Write this some day. */
863 static struct parport_driver cqcam_driver = {
864 .name = "cqcam",
865 .attach = cq_attach,
866 .detach = cq_detach,
869 static int __init cqcam_init(void)
871 printk(KERN_INFO BANNER "\n");
873 return parport_register_driver(&cqcam_driver);
876 static void __exit cqcam_cleanup(void)
878 unsigned int i;
880 for (i = 0; i < num_cams; i++)
881 close_cqcam(qcams[i]);
883 parport_unregister_driver(&cqcam_driver);
886 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
887 MODULE_DESCRIPTION(BANNER);
888 MODULE_LICENSE("GPL");
890 module_init(cqcam_init);
891 module_exit(cqcam_cleanup);