aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bw-qcam.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/media/video/bw-qcam.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/media/video/bw-qcam.c')
-rw-r--r--drivers/media/video/bw-qcam.c1027
1 files changed, 1027 insertions, 0 deletions
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c
new file mode 100644
index 000000000000..0065d0c240d1
--- /dev/null
+++ b/drivers/media/video/bw-qcam.c
@@ -0,0 +1,1027 @@
1/*
2 * QuickCam Driver For Video4Linux.
3 *
4 * Video4Linux conversion work by Alan Cox.
5 * Parport compatibility by Phil Blundell.
6 * Busy loop avoidance by Mark Cooke.
7 *
8 * Module parameters:
9 *
10 * maxpoll=<1 - 5000>
11 *
12 * When polling the QuickCam for a response, busy-wait for a
13 * maximum of this many loops. The default of 250 gives little
14 * impact on interactive response.
15 *
16 * NOTE: If this parameter is set too high, the processor
17 * will busy wait until this loop times out, and then
18 * slowly poll for a further 5 seconds before failing
19 * the transaction. You have been warned.
20 *
21 * yieldlines=<1 - 250>
22 *
23 * When acquiring a frame from the camera, the data gathering
24 * loop will yield back to the scheduler after completing
25 * this many lines. The default of 4 provides a trade-off
26 * between increased frame acquisition time and impact on
27 * interactive response.
28 */
29
30/* qcam-lib.c -- Library for programming with the Connectix QuickCam.
31 * See the included documentation for usage instructions and details
32 * of the protocol involved. */
33
34
35/* Version 0.5, August 4, 1996 */
36/* Version 0.7, August 27, 1996 */
37/* Version 0.9, November 17, 1996 */
38
39
40/******************************************************************
41
42Copyright (C) 1996 by Scott Laird
43
44Permission is hereby granted, free of charge, to any person obtaining
45a copy of this software and associated documentation files (the
46"Software"), to deal in the Software without restriction, including
47without limitation the rights to use, copy, modify, merge, publish,
48distribute, sublicense, and/or sell copies of the Software, and to
49permit persons to whom the Software is furnished to do so, subject to
50the following conditions:
51
52The above copyright notice and this permission notice shall be
53included in all copies or substantial portions of the Software.
54
55THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
56EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
57MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
58IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR
59OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
60ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
61OTHER DEALINGS IN THE SOFTWARE.
62
63******************************************************************/
64
65#include <linux/module.h>
66#include <linux/delay.h>
67#include <linux/errno.h>
68#include <linux/fs.h>
69#include <linux/init.h>
70#include <linux/kernel.h>
71#include <linux/slab.h>
72#include <linux/mm.h>
73#include <linux/parport.h>
74#include <linux/sched.h>
75#include <linux/videodev.h>
76#include <asm/semaphore.h>
77#include <asm/uaccess.h>
78
79#include "bw-qcam.h"
80
81static unsigned int maxpoll=250; /* Maximum busy-loop count for qcam I/O */
82static unsigned int yieldlines=4; /* Yield after this many during capture */
83static int video_nr = -1;
84
85module_param(maxpoll, int, 0);
86module_param(yieldlines, int, 0);
87module_param(video_nr, int, 0);
88
89static inline int read_lpstatus(struct qcam_device *q)
90{
91 return parport_read_status(q->pport);
92}
93
94static inline int read_lpdata(struct qcam_device *q)
95{
96 return parport_read_data(q->pport);
97}
98
99static inline void write_lpdata(struct qcam_device *q, int d)
100{
101 parport_write_data(q->pport, d);
102}
103
104static inline void write_lpcontrol(struct qcam_device *q, int d)
105{
106 parport_write_control(q->pport, d);
107}
108
109static int qc_waithand(struct qcam_device *q, int val);
110static int qc_command(struct qcam_device *q, int command);
111static int qc_readparam(struct qcam_device *q);
112static int qc_setscanmode(struct qcam_device *q);
113static int qc_readbytes(struct qcam_device *q, char buffer[]);
114
115static struct video_device qcam_template;
116
117static int qc_calibrate(struct qcam_device *q)
118{
119 /*
120 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
121 * The white balance is an individiual value for each
122 * quickcam.
123 */
124
125 int value;
126 int count = 0;
127
128 qc_command(q, 27); /* AutoAdjustOffset */
129 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
130
131 /* GetOffset (33) will read 255 until autocalibration */
132 /* is finished. After that, a value of 1-254 will be */
133 /* returned. */
134
135 do {
136 qc_command(q, 33);
137 value = qc_readparam(q);
138 mdelay(1);
139 schedule();
140 count++;
141 } while (value == 0xff && count<2048);
142
143 q->whitebal = value;
144 return value;
145}
146
147/* Initialize the QuickCam driver control structure. This is where
148 * defaults are set for people who don't have a config file.*/
149
150static struct qcam_device *qcam_init(struct parport *port)
151{
152 struct qcam_device *q;
153
154 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
155 if(q==NULL)
156 return NULL;
157
158 q->pport = port;
159 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
160 NULL, 0, NULL);
161 if (q->pdev == NULL)
162 {
163 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
164 port->name);
165 kfree(q);
166 return NULL;
167 }
168
169 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
170
171 init_MUTEX(&q->lock);
172
173 q->port_mode = (QC_ANY | QC_NOTSET);
174 q->width = 320;
175 q->height = 240;
176 q->bpp = 4;
177 q->transfer_scale = 2;
178 q->contrast = 192;
179 q->brightness = 180;
180 q->whitebal = 105;
181 q->top = 1;
182 q->left = 14;
183 q->mode = -1;
184 q->status = QC_PARAM_CHANGE;
185 return q;
186}
187
188
189/* qc_command is probably a bit of a misnomer -- it's used to send
190 * bytes *to* the camera. Generally, these bytes are either commands
191 * or arguments to commands, so the name fits, but it still bugs me a
192 * bit. See the documentation for a list of commands. */
193
194static int qc_command(struct qcam_device *q, int command)
195{
196 int n1, n2;
197 int cmd;
198
199 write_lpdata(q, command);
200 write_lpcontrol(q, 6);
201
202 n1 = qc_waithand(q, 1);
203
204 write_lpcontrol(q, 0xe);
205 n2 = qc_waithand(q, 0);
206
207 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
208 return cmd;
209}
210
211static int qc_readparam(struct qcam_device *q)
212{
213 int n1, n2;
214 int cmd;
215
216 write_lpcontrol(q, 6);
217 n1 = qc_waithand(q, 1);
218
219 write_lpcontrol(q, 0xe);
220 n2 = qc_waithand(q, 0);
221
222 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
223 return cmd;
224}
225
226/* qc_waithand busy-waits for a handshake signal from the QuickCam.
227 * Almost all communication with the camera requires handshaking. */
228
229static int qc_waithand(struct qcam_device *q, int val)
230{
231 int status;
232 int runs=0;
233
234 if (val)
235 {
236 while (!((status = read_lpstatus(q)) & 8))
237 {
238 /* 1000 is enough spins on the I/O for all normal
239 cases, at that point we start to poll slowly
240 until the camera wakes up. However, we are
241 busy blocked until the camera responds, so
242 setting it lower is much better for interactive
243 response. */
244
245 if(runs++>maxpoll)
246 {
247 msleep_interruptible(5);
248 }
249 if(runs>(maxpoll+1000)) /* 5 seconds */
250 return -1;
251 }
252 }
253 else
254 {
255 while (((status = read_lpstatus(q)) & 8))
256 {
257 /* 1000 is enough spins on the I/O for all normal
258 cases, at that point we start to poll slowly
259 until the camera wakes up. However, we are
260 busy blocked until the camera responds, so
261 setting it lower is much better for interactive
262 response. */
263
264 if(runs++>maxpoll)
265 {
266 msleep_interruptible(5);
267 }
268 if(runs++>(maxpoll+1000)) /* 5 seconds */
269 return -1;
270 }
271 }
272
273 return status;
274}
275
276/* Waithand2 is used when the qcam is in bidirectional mode, and the
277 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
278 * (bit 3 of status register). It also returns the last value read,
279 * since this data is useful. */
280
281static unsigned int qc_waithand2(struct qcam_device *q, int val)
282{
283 unsigned int status;
284 int runs=0;
285
286 do
287 {
288 status = read_lpdata(q);
289 /* 1000 is enough spins on the I/O for all normal
290 cases, at that point we start to poll slowly
291 until the camera wakes up. However, we are
292 busy blocked until the camera responds, so
293 setting it lower is much better for interactive
294 response. */
295
296 if(runs++>maxpoll)
297 {
298 msleep_interruptible(5);
299 }
300 if(runs++>(maxpoll+1000)) /* 5 seconds */
301 return 0;
302 }
303 while ((status & 1) != val);
304
305 return status;
306}
307
308
309/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
310 the status register at 5-10 Hz. This is only used in the autoprobe
311 code. Be aware that this isn't the way Connectix detects the
312 camera (they send a reset and try to handshake), but this should be
313 almost completely safe, while their method screws up my printer if
314 I plug it in before the camera. */
315
316static int qc_detect(struct qcam_device *q)
317{
318 int reg, lastreg;
319 int count = 0;
320 int i;
321
322 lastreg = reg = read_lpstatus(q) & 0xf0;
323
324 for (i = 0; i < 500; i++)
325 {
326 reg = read_lpstatus(q) & 0xf0;
327 if (reg != lastreg)
328 count++;
329 lastreg = reg;
330 mdelay(2);
331 }
332
333
334#if 0
335 /* Force camera detection during testing. Sometimes the camera
336 won't be flashing these bits. Possibly unloading the module
337 in the middle of a grab? Or some timeout condition?
338 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
339 printk("Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
340 return 1;
341#endif
342
343 /* Be (even more) liberal in what you accept... */
344
345/* if (count > 30 && count < 200) */
346 if (count > 20 && count < 300)
347 return 1; /* found */
348 else
349 return 0; /* not found */
350}
351
352
353/* Reset the QuickCam. This uses the same sequence the Windows
354 * QuickPic program uses. Someone with a bi-directional port should
355 * check that bi-directional mode is detected right, and then
356 * implement bi-directional mode in qc_readbyte(). */
357
358static void qc_reset(struct qcam_device *q)
359{
360 switch (q->port_mode & QC_FORCE_MASK)
361 {
362 case QC_FORCE_UNIDIR:
363 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
364 break;
365
366 case QC_FORCE_BIDIR:
367 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
368 break;
369
370 case QC_ANY:
371 write_lpcontrol(q, 0x20);
372 write_lpdata(q, 0x75);
373
374 if (read_lpdata(q) != 0x75) {
375 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
376 } else {
377 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
378 }
379 break;
380 }
381
382 write_lpcontrol(q, 0xb);
383 udelay(250);
384 write_lpcontrol(q, 0xe);
385 qc_setscanmode(q); /* in case port_mode changed */
386}
387
388
389/* Decide which scan mode to use. There's no real requirement that
390 * the scanmode match the resolution in q->height and q-> width -- the
391 * camera takes the picture at the resolution specified in the
392 * "scanmode" and then returns the image at the resolution specified
393 * with the resolution commands. If the scan is bigger than the
394 * requested resolution, the upper-left hand corner of the scan is
395 * returned. If the scan is smaller, then the rest of the image
396 * returned contains garbage. */
397
398static int qc_setscanmode(struct qcam_device *q)
399{
400 int old_mode = q->mode;
401
402 switch (q->transfer_scale)
403 {
404 case 1:
405 q->mode = 0;
406 break;
407 case 2:
408 q->mode = 4;
409 break;
410 case 4:
411 q->mode = 8;
412 break;
413 }
414
415 switch (q->bpp)
416 {
417 case 4:
418 break;
419 case 6:
420 q->mode += 2;
421 break;
422 }
423
424 switch (q->port_mode & QC_MODE_MASK)
425 {
426 case QC_BIDIR:
427 q->mode += 1;
428 break;
429 case QC_NOTSET:
430 case QC_UNIDIR:
431 break;
432 }
433
434 if (q->mode != old_mode)
435 q->status |= QC_PARAM_CHANGE;
436
437 return 0;
438}
439
440
441/* Reset the QuickCam and program for brightness, contrast,
442 * white-balance, and resolution. */
443
444static void qc_set(struct qcam_device *q)
445{
446 int val;
447 int val2;
448
449 qc_reset(q);
450
451 /* Set the brightness. Yes, this is repetitive, but it works.
452 * Shorter versions seem to fail subtly. Feel free to try :-). */
453 /* I think the problem was in qc_command, not here -- bls */
454
455 qc_command(q, 0xb);
456 qc_command(q, q->brightness);
457
458 val = q->height / q->transfer_scale;
459 qc_command(q, 0x11);
460 qc_command(q, val);
461 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
462 /* The normal "transfers per line" calculation doesn't seem to work
463 as expected here (and yet it works fine in qc_scan). No idea
464 why this case is the odd man out. Fortunately, Laird's original
465 working version gives me a good way to guess at working values.
466 -- bls */
467 val = q->width;
468 val2 = q->transfer_scale * 4;
469 } else {
470 val = q->width * q->bpp;
471 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
472 q->transfer_scale;
473 }
474 val = (val + val2 - 1) / val2;
475 qc_command(q, 0x13);
476 qc_command(q, val);
477
478 /* Setting top and left -- bls */
479 qc_command(q, 0xd);
480 qc_command(q, q->top);
481 qc_command(q, 0xf);
482 qc_command(q, q->left / 2);
483
484 qc_command(q, 0x19);
485 qc_command(q, q->contrast);
486 qc_command(q, 0x1f);
487 qc_command(q, q->whitebal);
488
489 /* Clear flag that we must update the grabbing parameters on the camera
490 before we grab the next frame */
491 q->status &= (~QC_PARAM_CHANGE);
492}
493
494/* Qc_readbytes reads some bytes from the QC and puts them in
495 the supplied buffer. It returns the number of bytes read,
496 or -1 on error. */
497
498static inline int qc_readbytes(struct qcam_device *q, char buffer[])
499{
500 int ret=1;
501 unsigned int hi, lo;
502 unsigned int hi2, lo2;
503 static int state = 0;
504
505 if (buffer == NULL)
506 {
507 state = 0;
508 return 0;
509 }
510
511 switch (q->port_mode & QC_MODE_MASK)
512 {
513 case QC_BIDIR: /* Bi-directional Port */
514 write_lpcontrol(q, 0x26);
515 lo = (qc_waithand2(q, 1) >> 1);
516 hi = (read_lpstatus(q) >> 3) & 0x1f;
517 write_lpcontrol(q, 0x2e);
518 lo2 = (qc_waithand2(q, 0) >> 1);
519 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
520 switch (q->bpp)
521 {
522 case 4:
523 buffer[0] = lo & 0xf;
524 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
525 buffer[2] = (hi & 0x1e) >> 1;
526 buffer[3] = lo2 & 0xf;
527 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
528 buffer[5] = (hi2 & 0x1e) >> 1;
529 ret = 6;
530 break;
531 case 6:
532 buffer[0] = lo & 0x3f;
533 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
534 buffer[2] = lo2 & 0x3f;
535 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
536 ret = 4;
537 break;
538 }
539 break;
540
541 case QC_UNIDIR: /* Unidirectional Port */
542 write_lpcontrol(q, 6);
543 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
544 write_lpcontrol(q, 0xe);
545 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
546
547 switch (q->bpp)
548 {
549 case 4:
550 buffer[0] = lo;
551 buffer[1] = hi;
552 ret = 2;
553 break;
554 case 6:
555 switch (state)
556 {
557 case 0:
558 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
559 q->saved_bits = (hi & 3) << 4;
560 state = 1;
561 ret = 1;
562 break;
563 case 1:
564 buffer[0] = lo | q->saved_bits;
565 q->saved_bits = hi << 2;
566 state = 2;
567 ret = 1;
568 break;
569 case 2:
570 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
571 buffer[1] = ((lo & 3) << 4) | hi;
572 state = 0;
573 ret = 2;
574 break;
575 }
576 break;
577 }
578 break;
579 }
580 return ret;
581}
582
583/* requests a scan from the camera. It sends the correct instructions
584 * to the camera and then reads back the correct number of bytes. In
585 * previous versions of this routine the return structure contained
586 * the raw output from the camera, and there was a 'qc_convertscan'
587 * function that converted that to a useful format. In version 0.3 I
588 * rolled qc_convertscan into qc_scan and now I only return the
589 * converted scan. The format is just an one-dimensional array of
590 * characters, one for each pixel, with 0=black up to n=white, where
591 * n=2^(bit depth)-1. Ask me for more details if you don't understand
592 * this. */
593
594static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len)
595{
596 int i, j, k, yield;
597 int bytes;
598 int linestotrans, transperline;
599 int divisor;
600 int pixels_per_line;
601 int pixels_read = 0;
602 int got=0;
603 char buffer[6];
604 int shift=8-q->bpp;
605 char invert;
606
607 if (q->mode == -1)
608 return -ENXIO;
609
610 qc_command(q, 0x7);
611 qc_command(q, q->mode);
612
613 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
614 {
615 write_lpcontrol(q, 0x2e); /* turn port around */
616 write_lpcontrol(q, 0x26);
617 (void) qc_waithand(q, 1);
618 write_lpcontrol(q, 0x2e);
619 (void) qc_waithand(q, 0);
620 }
621
622 /* strange -- should be 15:63 below, but 4bpp is odd */
623 invert = (q->bpp == 4) ? 16 : 63;
624
625 linestotrans = q->height / q->transfer_scale;
626 pixels_per_line = q->width / q->transfer_scale;
627 transperline = q->width * q->bpp;
628 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
629 q->transfer_scale;
630 transperline = (transperline + divisor - 1) / divisor;
631
632 for (i = 0, yield = yieldlines; i < linestotrans; i++)
633 {
634 for (pixels_read = j = 0; j < transperline; j++)
635 {
636 bytes = qc_readbytes(q, buffer);
637 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++)
638 {
639 int o;
640 if (buffer[k] == 0 && invert == 16)
641 {
642 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
643 must be 0-15 -- bls */
644 buffer[k] = 16;
645 }
646 o=i*pixels_per_line + pixels_read + k;
647 if(o<len)
648 {
649 got++;
650 put_user((invert - buffer[k])<<shift, buf+o);
651 }
652 }
653 pixels_read += bytes;
654 }
655 (void) qc_readbytes(q, NULL); /* reset state machine */
656
657 /* Grabbing an entire frame from the quickcam is a lengthy
658 process. We don't (usually) want to busy-block the
659 processor for the entire frame. yieldlines is a module
660 parameter. If we yield every line, the minimum frame
661 time will be 240 / 200 = 1.2 seconds. The compile-time
662 default is to yield every 4 lines. */
663 if (i >= yield) {
664 msleep_interruptible(5);
665 yield = i + yieldlines;
666 }
667 }
668
669 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
670 {
671 write_lpcontrol(q, 2);
672 write_lpcontrol(q, 6);
673 udelay(3);
674 write_lpcontrol(q, 0xe);
675 }
676 if(got<len)
677 return got;
678 return len;
679}
680
681/*
682 * Video4linux interfacing
683 */
684
685static int qcam_do_ioctl(struct inode *inode, struct file *file,
686 unsigned int cmd, void *arg)
687{
688 struct video_device *dev = video_devdata(file);
689 struct qcam_device *qcam=(struct qcam_device *)dev;
690
691 switch(cmd)
692 {
693 case VIDIOCGCAP:
694 {
695 struct video_capability *b = arg;
696 strcpy(b->name, "Quickcam");
697 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
698 b->channels = 1;
699 b->audios = 0;
700 b->maxwidth = 320;
701 b->maxheight = 240;
702 b->minwidth = 80;
703 b->minheight = 60;
704 return 0;
705 }
706 case VIDIOCGCHAN:
707 {
708 struct video_channel *v = arg;
709 if(v->channel!=0)
710 return -EINVAL;
711 v->flags=0;
712 v->tuners=0;
713 /* Good question.. its composite or SVHS so.. */
714 v->type = VIDEO_TYPE_CAMERA;
715 strcpy(v->name, "Camera");
716 return 0;
717 }
718 case VIDIOCSCHAN:
719 {
720 struct video_channel *v = arg;
721 if(v->channel!=0)
722 return -EINVAL;
723 return 0;
724 }
725 case VIDIOCGTUNER:
726 {
727 struct video_tuner *v = arg;
728 if(v->tuner)
729 return -EINVAL;
730 strcpy(v->name, "Format");
731 v->rangelow=0;
732 v->rangehigh=0;
733 v->flags= 0;
734 v->mode = VIDEO_MODE_AUTO;
735 return 0;
736 }
737 case VIDIOCSTUNER:
738 {
739 struct video_tuner *v = arg;
740 if(v->tuner)
741 return -EINVAL;
742 if(v->mode!=VIDEO_MODE_AUTO)
743 return -EINVAL;
744 return 0;
745 }
746 case VIDIOCGPICT:
747 {
748 struct video_picture *p = arg;
749 p->colour=0x8000;
750 p->hue=0x8000;
751 p->brightness=qcam->brightness<<8;
752 p->contrast=qcam->contrast<<8;
753 p->whiteness=qcam->whitebal<<8;
754 p->depth=qcam->bpp;
755 p->palette=VIDEO_PALETTE_GREY;
756 return 0;
757 }
758 case VIDIOCSPICT:
759 {
760 struct video_picture *p = arg;
761 if(p->palette!=VIDEO_PALETTE_GREY)
762 return -EINVAL;
763 if(p->depth!=4 && p->depth!=6)
764 return -EINVAL;
765
766 /*
767 * Now load the camera.
768 */
769
770 qcam->brightness = p->brightness>>8;
771 qcam->contrast = p->contrast>>8;
772 qcam->whitebal = p->whiteness>>8;
773 qcam->bpp = p->depth;
774
775 down(&qcam->lock);
776 qc_setscanmode(qcam);
777 up(&qcam->lock);
778 qcam->status |= QC_PARAM_CHANGE;
779
780 return 0;
781 }
782 case VIDIOCSWIN:
783 {
784 struct video_window *vw = arg;
785 if(vw->flags)
786 return -EINVAL;
787 if(vw->clipcount)
788 return -EINVAL;
789 if(vw->height<60||vw->height>240)
790 return -EINVAL;
791 if(vw->width<80||vw->width>320)
792 return -EINVAL;
793
794 qcam->width = 320;
795 qcam->height = 240;
796 qcam->transfer_scale = 4;
797
798 if(vw->width>=160 && vw->height>=120)
799 {
800 qcam->transfer_scale = 2;
801 }
802 if(vw->width>=320 && vw->height>=240)
803 {
804 qcam->width = 320;
805 qcam->height = 240;
806 qcam->transfer_scale = 1;
807 }
808 down(&qcam->lock);
809 qc_setscanmode(qcam);
810 up(&qcam->lock);
811
812 /* We must update the camera before we grab. We could
813 just have changed the grab size */
814 qcam->status |= QC_PARAM_CHANGE;
815
816 /* Ok we figured out what to use from our wide choice */
817 return 0;
818 }
819 case VIDIOCGWIN:
820 {
821 struct video_window *vw = arg;
822 memset(vw, 0, sizeof(*vw));
823 vw->width=qcam->width/qcam->transfer_scale;
824 vw->height=qcam->height/qcam->transfer_scale;
825 return 0;
826 }
827 case VIDIOCKEY:
828 return 0;
829 case VIDIOCCAPTURE:
830 case VIDIOCGFBUF:
831 case VIDIOCSFBUF:
832 case VIDIOCGFREQ:
833 case VIDIOCSFREQ:
834 case VIDIOCGAUDIO:
835 case VIDIOCSAUDIO:
836 return -EINVAL;
837 default:
838 return -ENOIOCTLCMD;
839 }
840 return 0;
841}
842
843static int qcam_ioctl(struct inode *inode, struct file *file,
844 unsigned int cmd, unsigned long arg)
845{
846 return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
847}
848
849static ssize_t qcam_read(struct file *file, char __user *buf,
850 size_t count, loff_t *ppos)
851{
852 struct video_device *v = video_devdata(file);
853 struct qcam_device *qcam=(struct qcam_device *)v;
854 int len;
855 parport_claim_or_block(qcam->pdev);
856
857 down(&qcam->lock);
858
859 qc_reset(qcam);
860
861 /* Update the camera parameters if we need to */
862 if (qcam->status & QC_PARAM_CHANGE)
863 qc_set(qcam);
864
865 len=qc_capture(qcam, buf,count);
866
867 up(&qcam->lock);
868
869 parport_release(qcam->pdev);
870 return len;
871}
872
873static struct file_operations qcam_fops = {
874 .owner = THIS_MODULE,
875 .open = video_exclusive_open,
876 .release = video_exclusive_release,
877 .ioctl = qcam_ioctl,
878 .read = qcam_read,
879 .llseek = no_llseek,
880};
881static struct video_device qcam_template=
882{
883 .owner = THIS_MODULE,
884 .name = "Connectix Quickcam",
885 .type = VID_TYPE_CAPTURE,
886 .hardware = VID_HARDWARE_QCAM_BW,
887 .fops = &qcam_fops,
888};
889
890#define MAX_CAMS 4
891static struct qcam_device *qcams[MAX_CAMS];
892static unsigned int num_cams = 0;
893
894static int init_bwqcam(struct parport *port)
895{
896 struct qcam_device *qcam;
897
898 if (num_cams == MAX_CAMS)
899 {
900 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
901 return -ENOSPC;
902 }
903
904 qcam=qcam_init(port);
905 if(qcam==NULL)
906 return -ENODEV;
907
908 parport_claim_or_block(qcam->pdev);
909
910 qc_reset(qcam);
911
912 if(qc_detect(qcam)==0)
913 {
914 parport_release(qcam->pdev);
915 parport_unregister_device(qcam->pdev);
916 kfree(qcam);
917 return -ENODEV;
918 }
919 qc_calibrate(qcam);
920
921 parport_release(qcam->pdev);
922
923 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
924
925 if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
926 {
927 parport_unregister_device(qcam->pdev);
928 kfree(qcam);
929 return -ENODEV;
930 }
931
932 qcams[num_cams++] = qcam;
933
934 return 0;
935}
936
937static void close_bwqcam(struct qcam_device *qcam)
938{
939 video_unregister_device(&qcam->vdev);
940 parport_unregister_device(qcam->pdev);
941 kfree(qcam);
942}
943
944/* The parport parameter controls which parports will be scanned.
945 * Scanning all parports causes some printers to print a garbage page.
946 * -- March 14, 1999 Billy Donahue <billy@escape.com> */
947#ifdef MODULE
948static char *parport[MAX_CAMS] = { NULL, };
949module_param_array(parport, charp, NULL, 0);
950#endif
951
952static int accept_bwqcam(struct parport *port)
953{
954#ifdef MODULE
955 int n;
956
957 if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
958 /* user gave parport parameters */
959 for(n=0; parport[n] && n<MAX_CAMS; n++){
960 char *ep;
961 unsigned long r;
962 r = simple_strtoul(parport[n], &ep, 0);
963 if (ep == parport[n]) {
964 printk(KERN_ERR
965 "bw-qcam: bad port specifier \"%s\"\n",
966 parport[n]);
967 continue;
968 }
969 if (r == port->number)
970 return 1;
971 }
972 return 0;
973 }
974#endif
975 return 1;
976}
977
978static void bwqcam_attach(struct parport *port)
979{
980 if (accept_bwqcam(port))
981 init_bwqcam(port);
982}
983
984static void bwqcam_detach(struct parport *port)
985{
986 int i;
987 for (i = 0; i < num_cams; i++) {
988 struct qcam_device *qcam = qcams[i];
989 if (qcam && qcam->pdev->port == port) {
990 qcams[i] = NULL;
991 close_bwqcam(qcam);
992 }
993 }
994}
995
996static struct parport_driver bwqcam_driver = {
997 .name = "bw-qcam",
998 .attach = bwqcam_attach,
999 .detach = bwqcam_detach,
1000};
1001
1002static void __exit exit_bw_qcams(void)
1003{
1004 parport_unregister_driver(&bwqcam_driver);
1005}
1006
1007static int __init init_bw_qcams(void)
1008{
1009#ifdef MODULE
1010 /* Do some sanity checks on the module parameters. */
1011 if (maxpoll > 5000) {
1012 printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
1013 maxpoll = 5000;
1014 }
1015
1016 if (yieldlines < 1) {
1017 printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
1018 yieldlines = 1;
1019 }
1020#endif
1021 return parport_register_driver(&bwqcam_driver);
1022}
1023
1024module_init(init_bw_qcams);
1025module_exit(exit_bw_qcams);
1026
1027MODULE_LICENSE("GPL");