• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *	Video4Linux Colour QuickCam driver
3  *	Copyright 1997-2000 Philip Blundell <philb@gnu.org>
4  *
5  *    Module parameters:
6  *
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
10  *
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
14  *
15  *	force_rgb=1       -- force data format to RGB (default is BGR)
16  *
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>
20  *
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>
24  */
25 
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/videodev.h>
37 #include <media/v4l2-common.h>
38 #include <media/v4l2-ioctl.h>
39 #include <linux/mutex.h>
40 #include <linux/jiffies.h>
41 
42 #include <asm/uaccess.h>
43 
44 struct qcam_device {
45 	struct video_device vdev;
46 	struct pardevice *pdev;
47 	struct parport *pport;
48 	int width, height;
49 	int ccd_width, ccd_height;
50 	int mode;
51 	int contrast, brightness, whitebal;
52 	int top, left;
53 	unsigned int bidirectional;
54 	unsigned long in_use;
55 	struct mutex lock;
56 };
57 
58 /* cameras maximum */
59 #define MAX_CAMS 4
60 
61 /* The three possible QuickCam modes */
62 #define QC_MILLIONS	0x18
63 #define QC_BILLIONS	0x10
64 #define QC_THOUSANDS	0x08	/* with VIDEC compression (not supported) */
65 
66 /* The three possible decimations */
67 #define QC_DECIMATION_1		0
68 #define QC_DECIMATION_2		2
69 #define QC_DECIMATION_4		4
70 
71 #define BANNER "Colour QuickCam for Video4Linux v0.05"
72 
73 static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
74 static int probe = 2;
75 static int force_rgb;
76 static int video_nr = -1;
77 
qcam_set_ack(struct qcam_device * qcam,unsigned int i)78 static inline void qcam_set_ack(struct qcam_device *qcam, unsigned int i)
79 {
80 	/* note: the QC specs refer to the PCAck pin by voltage, not
81 	   software level.  PC ports have builtin inverters. */
82 	parport_frob_control(qcam->pport, 8, i?8:0);
83 }
84 
qcam_ready1(struct qcam_device * qcam)85 static inline unsigned int qcam_ready1(struct qcam_device *qcam)
86 {
87 	return (parport_read_status(qcam->pport) & 0x8)?1:0;
88 }
89 
qcam_ready2(struct qcam_device * qcam)90 static inline unsigned int qcam_ready2(struct qcam_device *qcam)
91 {
92 	return (parport_read_data(qcam->pport) & 0x1)?1:0;
93 }
94 
qcam_await_ready1(struct qcam_device * qcam,int value)95 static unsigned int qcam_await_ready1(struct qcam_device *qcam,
96 					     int value)
97 {
98 	unsigned long oldjiffies = jiffies;
99 	unsigned int i;
100 
101 	for (oldjiffies = jiffies;
102 	     time_before(jiffies, oldjiffies + msecs_to_jiffies(40)); )
103 		if (qcam_ready1(qcam) == value)
104 			return 0;
105 
106 	/* If the camera didn't respond within 1/25 second, poll slowly
107 	   for a while. */
108 	for (i = 0; i < 50; i++)
109 	{
110 		if (qcam_ready1(qcam) == value)
111 			return 0;
112 		msleep_interruptible(100);
113 	}
114 
115 	/* Probably somebody pulled the plug out.  Not much we can do. */
116 	printk(KERN_ERR "c-qcam: ready1 timeout (%d) %x %x\n", value,
117 	       parport_read_status(qcam->pport),
118 	       parport_read_control(qcam->pport));
119 	return 1;
120 }
121 
qcam_await_ready2(struct qcam_device * qcam,int value)122 static unsigned int qcam_await_ready2(struct qcam_device *qcam, int value)
123 {
124 	unsigned long oldjiffies = jiffies;
125 	unsigned int i;
126 
127 	for (oldjiffies = jiffies;
128 	     time_before(jiffies, oldjiffies + msecs_to_jiffies(40)); )
129 		if (qcam_ready2(qcam) == value)
130 			return 0;
131 
132 	/* If the camera didn't respond within 1/25 second, poll slowly
133 	   for a while. */
134 	for (i = 0; i < 50; i++)
135 	{
136 		if (qcam_ready2(qcam) == value)
137 			return 0;
138 		msleep_interruptible(100);
139 	}
140 
141 	/* Probably somebody pulled the plug out.  Not much we can do. */
142 	printk(KERN_ERR "c-qcam: ready2 timeout (%d) %x %x %x\n", value,
143 	       parport_read_status(qcam->pport),
144 	       parport_read_control(qcam->pport),
145 	       parport_read_data(qcam->pport));
146 	return 1;
147 }
148 
qcam_read_data(struct qcam_device * qcam)149 static int qcam_read_data(struct qcam_device *qcam)
150 {
151 	unsigned int idata;
152 	qcam_set_ack(qcam, 0);
153 	if (qcam_await_ready1(qcam, 1)) return -1;
154 	idata = parport_read_status(qcam->pport) & 0xf0;
155 	qcam_set_ack(qcam, 1);
156 	if (qcam_await_ready1(qcam, 0)) return -1;
157 	idata |= (parport_read_status(qcam->pport) >> 4);
158 	return idata;
159 }
160 
qcam_write_data(struct qcam_device * qcam,unsigned int data)161 static int qcam_write_data(struct qcam_device *qcam, unsigned int data)
162 {
163 	unsigned int idata;
164 	parport_write_data(qcam->pport, data);
165 	idata = qcam_read_data(qcam);
166 	if (data != idata)
167 	{
168 		printk(KERN_WARNING "cqcam: sent %x but received %x\n", data,
169 		       idata);
170 		return 1;
171 	}
172 	return 0;
173 }
174 
qcam_set(struct qcam_device * qcam,unsigned int cmd,unsigned int data)175 static inline int qcam_set(struct qcam_device *qcam, unsigned int cmd, unsigned int data)
176 {
177 	if (qcam_write_data(qcam, cmd))
178 		return -1;
179 	if (qcam_write_data(qcam, data))
180 		return -1;
181 	return 0;
182 }
183 
qcam_get(struct qcam_device * qcam,unsigned int cmd)184 static inline int qcam_get(struct qcam_device *qcam, unsigned int cmd)
185 {
186 	if (qcam_write_data(qcam, cmd))
187 		return -1;
188 	return qcam_read_data(qcam);
189 }
190 
qc_detect(struct qcam_device * qcam)191 static int qc_detect(struct qcam_device *qcam)
192 {
193 	unsigned int stat, ostat, i, count = 0;
194 
195 	/* The probe routine below is not very reliable.  The IEEE-1284
196 	   probe takes precedence. */
197 	/* XXX Currently parport provides no way to distinguish between
198 	   "the IEEE probe was not done" and "the probe was done, but
199 	   no device was found".  Fix this one day. */
200 	if (qcam->pport->probe_info[0].class == PARPORT_CLASS_MEDIA
201 	    && qcam->pport->probe_info[0].model
202 	    && !strcmp(qcam->pdev->port->probe_info[0].model,
203 		       "Color QuickCam 2.0")) {
204 		printk(KERN_DEBUG "QuickCam: Found by IEEE1284 probe.\n");
205 		return 1;
206 	}
207 
208 	if (probe < 2)
209 		return 0;
210 
211 	parport_write_control(qcam->pport, 0xc);
212 
213 	/* look for a heartbeat */
214 	ostat = stat = parport_read_status(qcam->pport);
215 	for (i=0; i<250; i++)
216 	{
217 		mdelay(1);
218 		stat = parport_read_status(qcam->pport);
219 		if (ostat != stat)
220 		{
221 			if (++count >= 3) return 1;
222 			ostat = stat;
223 		}
224 	}
225 
226 	/* Reset the camera and try again */
227 	parport_write_control(qcam->pport, 0xc);
228 	parport_write_control(qcam->pport, 0x8);
229 	mdelay(1);
230 	parport_write_control(qcam->pport, 0xc);
231 	mdelay(1);
232 	count = 0;
233 
234 	ostat = stat = parport_read_status(qcam->pport);
235 	for (i=0; i<250; i++)
236 	{
237 		mdelay(1);
238 		stat = parport_read_status(qcam->pport);
239 		if (ostat != stat)
240 		{
241 			if (++count >= 3) return 1;
242 			ostat = stat;
243 		}
244 	}
245 
246 	/* no (or flatline) camera, give up */
247 	return 0;
248 }
249 
qc_reset(struct qcam_device * qcam)250 static void qc_reset(struct qcam_device *qcam)
251 {
252 	parport_write_control(qcam->pport, 0xc);
253 	parport_write_control(qcam->pport, 0x8);
254 	mdelay(1);
255 	parport_write_control(qcam->pport, 0xc);
256 	mdelay(1);
257 }
258 
259 /* Reset the QuickCam and program for brightness, contrast,
260  * white-balance, and resolution. */
261 
qc_setup(struct qcam_device * q)262 static void qc_setup(struct qcam_device *q)
263 {
264 	qc_reset(q);
265 
266 	/* Set the brightness.  */
267 	qcam_set(q, 11, q->brightness);
268 
269 	/* Set the height and width.  These refer to the actual
270 	   CCD area *before* applying the selected decimation.  */
271 	qcam_set(q, 17, q->ccd_height);
272 	qcam_set(q, 19, q->ccd_width / 2);
273 
274 	/* Set top and left.  */
275 	qcam_set(q, 0xd, q->top);
276 	qcam_set(q, 0xf, q->left);
277 
278 	/* Set contrast and white balance.  */
279 	qcam_set(q, 0x19, q->contrast);
280 	qcam_set(q, 0x1f, q->whitebal);
281 
282 	/* Set the speed.  */
283 	qcam_set(q, 45, 2);
284 }
285 
286 /* Read some bytes from the camera and put them in the buffer.
287    nbytes should be a multiple of 3, because bidirectional mode gives
288    us three bytes at a time.  */
289 
qcam_read_bytes(struct qcam_device * q,unsigned char * buf,unsigned int nbytes)290 static unsigned int qcam_read_bytes(struct qcam_device *q, unsigned char *buf, unsigned int nbytes)
291 {
292 	unsigned int bytes = 0;
293 
294 	qcam_set_ack(q, 0);
295 	if (q->bidirectional)
296 	{
297 		/* It's a bidirectional port */
298 		while (bytes < nbytes)
299 		{
300 			unsigned int lo1, hi1, lo2, hi2;
301 			unsigned char r, g, b;
302 
303 			if (qcam_await_ready2(q, 1)) return bytes;
304 			lo1 = parport_read_data(q->pport) >> 1;
305 			hi1 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
306 			qcam_set_ack(q, 1);
307 			if (qcam_await_ready2(q, 0)) return bytes;
308 			lo2 = parport_read_data(q->pport) >> 1;
309 			hi2 = ((parport_read_status(q->pport) >> 3) & 0x1f) ^ 0x10;
310 			qcam_set_ack(q, 0);
311 			r = (lo1 | ((hi1 & 1)<<7));
312 			g = ((hi1 & 0x1e)<<3) | ((hi2 & 0x1e)>>1);
313 			b = (lo2 | ((hi2 & 1)<<7));
314 			if (force_rgb) {
315 				buf[bytes++] = r;
316 				buf[bytes++] = g;
317 				buf[bytes++] = b;
318 			} else {
319 				buf[bytes++] = b;
320 				buf[bytes++] = g;
321 				buf[bytes++] = r;
322 			}
323 		}
324 	}
325 	else
326 	{
327 		/* It's a unidirectional port */
328 		int i = 0, n = bytes;
329 		unsigned char rgb[3];
330 
331 		while (bytes < nbytes)
332 		{
333 			unsigned int hi, lo;
334 
335 			if (qcam_await_ready1(q, 1)) return bytes;
336 			hi = (parport_read_status(q->pport) & 0xf0);
337 			qcam_set_ack(q, 1);
338 			if (qcam_await_ready1(q, 0)) return bytes;
339 			lo = (parport_read_status(q->pport) & 0xf0);
340 			qcam_set_ack(q, 0);
341 			/* flip some bits */
342 			rgb[(i = bytes++ % 3)] = (hi | (lo >> 4)) ^ 0x88;
343 			if (i >= 2) {
344 get_fragment:
345 				if (force_rgb) {
346 					buf[n++] = rgb[0];
347 					buf[n++] = rgb[1];
348 					buf[n++] = rgb[2];
349 				} else {
350 					buf[n++] = rgb[2];
351 					buf[n++] = rgb[1];
352 					buf[n++] = rgb[0];
353 				}
354 			}
355 		}
356 		if (i) {
357 			i = 0;
358 			goto get_fragment;
359 		}
360 	}
361 	return bytes;
362 }
363 
364 #define BUFSZ	150
365 
qc_capture(struct qcam_device * q,char __user * buf,unsigned long len)366 static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len)
367 {
368 	unsigned lines, pixelsperline, bitsperxfer;
369 	unsigned int is_bi_dir = q->bidirectional;
370 	size_t wantlen, outptr = 0;
371 	char tmpbuf[BUFSZ];
372 
373 	if (!access_ok(VERIFY_WRITE, buf, len))
374 		return -EFAULT;
375 
376 	/* Wait for camera to become ready */
377 	for (;;)
378 	{
379 		int i = qcam_get(q, 41);
380 		if (i == -1) {
381 			qc_setup(q);
382 			return -EIO;
383 		}
384 		if ((i & 0x80) == 0)
385 			break;
386 		else
387 			schedule();
388 	}
389 
390 	if (qcam_set(q, 7, (q->mode | (is_bi_dir?1:0)) + 1))
391 		return -EIO;
392 
393 	lines = q->height;
394 	pixelsperline = q->width;
395 	bitsperxfer = (is_bi_dir) ? 24 : 8;
396 
397 	if (is_bi_dir)
398 	{
399 		/* Turn the port around */
400 		parport_data_reverse(q->pport);
401 		mdelay(3);
402 		qcam_set_ack(q, 0);
403 		if (qcam_await_ready1(q, 1)) {
404 			qc_setup(q);
405 			return -EIO;
406 		}
407 		qcam_set_ack(q, 1);
408 		if (qcam_await_ready1(q, 0)) {
409 			qc_setup(q);
410 			return -EIO;
411 		}
412 	}
413 
414 	wantlen = lines * pixelsperline * 24 / 8;
415 
416 	while (wantlen)
417 	{
418 		size_t t, s;
419 		s = (wantlen > BUFSZ)?BUFSZ:wantlen;
420 		t = qcam_read_bytes(q, tmpbuf, s);
421 		if (outptr < len)
422 		{
423 			size_t sz = len - outptr;
424 			if (sz > t) sz = t;
425 			if (__copy_to_user(buf+outptr, tmpbuf, sz))
426 				break;
427 			outptr += sz;
428 		}
429 		wantlen -= t;
430 		if (t < s)
431 			break;
432 		cond_resched();
433 	}
434 
435 	len = outptr;
436 
437 	if (wantlen)
438 	{
439 		printk("qcam: short read.\n");
440 		if (is_bi_dir)
441 			parport_data_forward(q->pport);
442 		qc_setup(q);
443 		return len;
444 	}
445 
446 	if (is_bi_dir)
447 	{
448 		int l;
449 		do {
450 			l = qcam_read_bytes(q, tmpbuf, 3);
451 			cond_resched();
452 		} while (l && (tmpbuf[0] == 0x7e || tmpbuf[1] == 0x7e || tmpbuf[2] == 0x7e));
453 		if (force_rgb) {
454 			if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
455 				printk("qcam: bad EOF\n");
456 		} else {
457 			if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
458 				printk("qcam: bad EOF\n");
459 		}
460 		qcam_set_ack(q, 0);
461 		if (qcam_await_ready1(q, 1))
462 		{
463 			printk("qcam: no ack after EOF\n");
464 			parport_data_forward(q->pport);
465 			qc_setup(q);
466 			return len;
467 		}
468 		parport_data_forward(q->pport);
469 		mdelay(3);
470 		qcam_set_ack(q, 1);
471 		if (qcam_await_ready1(q, 0))
472 		{
473 			printk("qcam: no ack to port turnaround\n");
474 			qc_setup(q);
475 			return len;
476 		}
477 	}
478 	else
479 	{
480 		int l;
481 		do {
482 			l = qcam_read_bytes(q, tmpbuf, 1);
483 			cond_resched();
484 		} while (l && tmpbuf[0] == 0x7e);
485 		l = qcam_read_bytes(q, tmpbuf+1, 2);
486 		if (force_rgb) {
487 			if (tmpbuf[0] != 0xe || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xf)
488 				printk("qcam: bad EOF\n");
489 		} else {
490 			if (tmpbuf[0] != 0xf || tmpbuf[1] != 0x0 || tmpbuf[2] != 0xe)
491 				printk("qcam: bad EOF\n");
492 		}
493 	}
494 
495 	qcam_write_data(q, 0);
496 	return len;
497 }
498 
499 /*
500  *	Video4linux interfacing
501  */
502 
qcam_do_ioctl(struct file * file,unsigned int cmd,void * arg)503 static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
504 {
505 	struct video_device *dev = video_devdata(file);
506 	struct qcam_device *qcam=(struct qcam_device *)dev;
507 
508 	switch(cmd)
509 	{
510 		case VIDIOCGCAP:
511 		{
512 			struct video_capability *b = arg;
513 			strcpy(b->name, "Quickcam");
514 			b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES;
515 			b->channels = 1;
516 			b->audios = 0;
517 			b->maxwidth = 320;
518 			b->maxheight = 240;
519 			b->minwidth = 80;
520 			b->minheight = 60;
521 			return 0;
522 		}
523 		case VIDIOCGCHAN:
524 		{
525 			struct video_channel *v = arg;
526 			if(v->channel!=0)
527 				return -EINVAL;
528 			v->flags=0;
529 			v->tuners=0;
530 			/* Good question.. its composite or SVHS so.. */
531 			v->type = VIDEO_TYPE_CAMERA;
532 			strcpy(v->name, "Camera");
533 			return 0;
534 		}
535 		case VIDIOCSCHAN:
536 		{
537 			struct video_channel *v = arg;
538 			if(v->channel!=0)
539 				return -EINVAL;
540 			return 0;
541 		}
542 		case VIDIOCGTUNER:
543 		{
544 			struct video_tuner *v = arg;
545 			if(v->tuner)
546 				return -EINVAL;
547 			memset(v,0,sizeof(*v));
548 			strcpy(v->name, "Format");
549 			v->mode = VIDEO_MODE_AUTO;
550 			return 0;
551 		}
552 		case VIDIOCSTUNER:
553 		{
554 			struct video_tuner *v = arg;
555 			if(v->tuner)
556 				return -EINVAL;
557 			if(v->mode!=VIDEO_MODE_AUTO)
558 				return -EINVAL;
559 			return 0;
560 		}
561 		case VIDIOCGPICT:
562 		{
563 			struct video_picture *p = arg;
564 			p->colour=0x8000;
565 			p->hue=0x8000;
566 			p->brightness=qcam->brightness<<8;
567 			p->contrast=qcam->contrast<<8;
568 			p->whiteness=qcam->whitebal<<8;
569 			p->depth=24;
570 			p->palette=VIDEO_PALETTE_RGB24;
571 			return 0;
572 		}
573 		case VIDIOCSPICT:
574 		{
575 			struct video_picture *p = arg;
576 
577 			/*
578 			 *	Sanity check args
579 			 */
580 			if (p->depth != 24 || p->palette != VIDEO_PALETTE_RGB24)
581 				return -EINVAL;
582 
583 			/*
584 			 *	Now load the camera.
585 			 */
586 			qcam->brightness = p->brightness>>8;
587 			qcam->contrast = p->contrast>>8;
588 			qcam->whitebal = p->whiteness>>8;
589 
590 			mutex_lock(&qcam->lock);
591 			parport_claim_or_block(qcam->pdev);
592 			qc_setup(qcam);
593 			parport_release(qcam->pdev);
594 			mutex_unlock(&qcam->lock);
595 			return 0;
596 		}
597 		case VIDIOCSWIN:
598 		{
599 			struct video_window *vw = arg;
600 
601 			if(vw->flags)
602 				return -EINVAL;
603 			if(vw->clipcount)
604 				return -EINVAL;
605 			if(vw->height<60||vw->height>240)
606 				return -EINVAL;
607 			if(vw->width<80||vw->width>320)
608 				return -EINVAL;
609 
610 			qcam->width = 80;
611 			qcam->height = 60;
612 			qcam->mode = QC_DECIMATION_4;
613 
614 			if(vw->width>=160 && vw->height>=120)
615 			{
616 				qcam->width = 160;
617 				qcam->height = 120;
618 				qcam->mode = QC_DECIMATION_2;
619 			}
620 			if(vw->width>=320 && vw->height>=240)
621 			{
622 				qcam->width = 320;
623 				qcam->height = 240;
624 				qcam->mode = QC_DECIMATION_1;
625 			}
626 			qcam->mode |= QC_MILLIONS;
627 #if 0
628 			if(vw->width>=640 && vw->height>=480)
629 			{
630 				qcam->width = 640;
631 				qcam->height = 480;
632 				qcam->mode = QC_BILLIONS | QC_DECIMATION_1;
633 			}
634 #endif
635 			/* Ok we figured out what to use from our
636 			   wide choice */
637 			mutex_lock(&qcam->lock);
638 			parport_claim_or_block(qcam->pdev);
639 			qc_setup(qcam);
640 			parport_release(qcam->pdev);
641 			mutex_unlock(&qcam->lock);
642 			return 0;
643 		}
644 		case VIDIOCGWIN:
645 		{
646 			struct video_window *vw = arg;
647 			memset(vw, 0, sizeof(*vw));
648 			vw->width=qcam->width;
649 			vw->height=qcam->height;
650 			return 0;
651 		}
652 		case VIDIOCKEY:
653 			return 0;
654 		case VIDIOCCAPTURE:
655 		case VIDIOCGFBUF:
656 		case VIDIOCSFBUF:
657 		case VIDIOCGFREQ:
658 		case VIDIOCSFREQ:
659 		case VIDIOCGAUDIO:
660 		case VIDIOCSAUDIO:
661 			return -EINVAL;
662 		default:
663 			return -ENOIOCTLCMD;
664 	}
665 	return 0;
666 }
667 
qcam_ioctl(struct file * file,unsigned int cmd,unsigned long arg)668 static long qcam_ioctl(struct file *file,
669 		      unsigned int cmd, unsigned long arg)
670 {
671 	return video_usercopy(file, cmd, arg, qcam_do_ioctl);
672 }
673 
qcam_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)674 static ssize_t qcam_read(struct file *file, char __user *buf,
675 			 size_t count, loff_t *ppos)
676 {
677 	struct video_device *v = video_devdata(file);
678 	struct qcam_device *qcam=(struct qcam_device *)v;
679 	int len;
680 
681 	mutex_lock(&qcam->lock);
682 	parport_claim_or_block(qcam->pdev);
683 	/* Probably should have a semaphore against multiple users */
684 	len = qc_capture(qcam, buf,count);
685 	parport_release(qcam->pdev);
686 	mutex_unlock(&qcam->lock);
687 	return len;
688 }
689 
qcam_exclusive_open(struct file * file)690 static int qcam_exclusive_open(struct file *file)
691 {
692 	struct video_device *dev = video_devdata(file);
693 	struct qcam_device *qcam = (struct qcam_device *)dev;
694 
695 	return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0;
696 }
697 
qcam_exclusive_release(struct file * file)698 static int qcam_exclusive_release(struct file *file)
699 {
700 	struct video_device *dev = video_devdata(file);
701 	struct qcam_device *qcam = (struct qcam_device *)dev;
702 
703 	clear_bit(0, &qcam->in_use);
704 	return 0;
705 }
706 
707 /* video device template */
708 static const struct v4l2_file_operations qcam_fops = {
709 	.owner		= THIS_MODULE,
710 	.open           = qcam_exclusive_open,
711 	.release        = qcam_exclusive_release,
712 	.ioctl          = qcam_ioctl,
713 	.read		= qcam_read,
714 };
715 
716 static struct video_device qcam_template=
717 {
718 	.name		= "Colour QuickCam",
719 	.fops           = &qcam_fops,
720 	.release 	= video_device_release_empty,
721 };
722 
723 /* Initialize the QuickCam driver control structure. */
724 
qcam_init(struct parport * port)725 static struct qcam_device *qcam_init(struct parport *port)
726 {
727 	struct qcam_device *q;
728 
729 	q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
730 	if(q==NULL)
731 		return NULL;
732 
733 	q->pport = port;
734 	q->pdev = parport_register_device(port, "c-qcam", NULL, NULL,
735 					  NULL, 0, NULL);
736 
737 	q->bidirectional = (q->pport->modes & PARPORT_MODE_TRISTATE)?1:0;
738 
739 	if (q->pdev == NULL)
740 	{
741 		printk(KERN_ERR "c-qcam: couldn't register for %s.\n",
742 		       port->name);
743 		kfree(q);
744 		return NULL;
745 	}
746 
747 	memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
748 
749 	mutex_init(&q->lock);
750 	q->width = q->ccd_width = 320;
751 	q->height = q->ccd_height = 240;
752 	q->mode = QC_MILLIONS | QC_DECIMATION_1;
753 	q->contrast = 192;
754 	q->brightness = 240;
755 	q->whitebal = 128;
756 	q->top = 1;
757 	q->left = 14;
758 	return q;
759 }
760 
761 static struct qcam_device *qcams[MAX_CAMS];
762 static unsigned int num_cams;
763 
init_cqcam(struct parport * port)764 static int init_cqcam(struct parport *port)
765 {
766 	struct qcam_device *qcam;
767 
768 	if (parport[0] != -1)
769 	{
770 		/* The user gave specific instructions */
771 		int i, found = 0;
772 		for (i = 0; i < MAX_CAMS && parport[i] != -1; i++)
773 		{
774 			if (parport[0] == port->number)
775 				found = 1;
776 		}
777 		if (!found)
778 			return -ENODEV;
779 	}
780 
781 	if (num_cams == MAX_CAMS)
782 		return -ENOSPC;
783 
784 	qcam = qcam_init(port);
785 	if (qcam==NULL)
786 		return -ENODEV;
787 
788 	parport_claim_or_block(qcam->pdev);
789 
790 	qc_reset(qcam);
791 
792 	if (probe && qc_detect(qcam)==0)
793 	{
794 		parport_release(qcam->pdev);
795 		parport_unregister_device(qcam->pdev);
796 		kfree(qcam);
797 		return -ENODEV;
798 	}
799 
800 	qc_setup(qcam);
801 
802 	parport_release(qcam->pdev);
803 
804 	if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
805 		printk(KERN_ERR "Unable to register Colour QuickCam on %s\n",
806 		       qcam->pport->name);
807 		parport_unregister_device(qcam->pdev);
808 		kfree(qcam);
809 		return -ENODEV;
810 	}
811 
812 	printk(KERN_INFO "video%d: Colour QuickCam found on %s\n",
813 	       qcam->vdev.num, qcam->pport->name);
814 
815 	qcams[num_cams++] = qcam;
816 
817 	return 0;
818 }
819 
close_cqcam(struct qcam_device * qcam)820 static void close_cqcam(struct qcam_device *qcam)
821 {
822 	video_unregister_device(&qcam->vdev);
823 	parport_unregister_device(qcam->pdev);
824 	kfree(qcam);
825 }
826 
cq_attach(struct parport * port)827 static void cq_attach(struct parport *port)
828 {
829 	init_cqcam(port);
830 }
831 
cq_detach(struct parport * port)832 static void cq_detach(struct parport *port)
833 {
834 	/* Write this some day. */
835 }
836 
837 static struct parport_driver cqcam_driver = {
838 	.name = "cqcam",
839 	.attach = cq_attach,
840 	.detach = cq_detach,
841 };
842 
cqcam_init(void)843 static int __init cqcam_init (void)
844 {
845 	printk(BANNER "\n");
846 
847 	return parport_register_driver(&cqcam_driver);
848 }
849 
cqcam_cleanup(void)850 static void __exit cqcam_cleanup (void)
851 {
852 	unsigned int i;
853 
854 	for (i = 0; i < num_cams; i++)
855 		close_cqcam(qcams[i]);
856 
857 	parport_unregister_driver(&cqcam_driver);
858 }
859 
860 MODULE_AUTHOR("Philip Blundell <philb@gnu.org>");
861 MODULE_DESCRIPTION(BANNER);
862 MODULE_LICENSE("GPL");
863 
864 /* FIXME: parport=auto would never have worked, surely? --RR */
865 MODULE_PARM_DESC(parport ,"parport=<auto|n[,n]...> for port detection method\n\
866 probe=<0|1|2> for camera detection method\n\
867 force_rgb=<0|1> for RGB data format (default BGR)");
868 module_param_array(parport, int, NULL, 0);
869 module_param(probe, int, 0);
870 module_param(force_rgb, bool, 0);
871 module_param(video_nr, int, 0);
872 
873 module_init(cqcam_init);
874 module_exit(cqcam_cleanup);
875