blob: 58423525591fbce1f1e3f876713b8e47f3bced79 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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>
Mauro Carvalho Chehab5e87efa2006-06-05 10:26:32 -030076#include <media/v4l2-common.h>
Ingo Molnar3593cab2006-02-07 06:49:14 -020077#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070078#include <asm/uaccess.h>
79
80#include "bw-qcam.h"
81
82static unsigned int maxpoll=250; /* Maximum busy-loop count for qcam I/O */
83static unsigned int yieldlines=4; /* Yield after this many during capture */
84static int video_nr = -1;
85
86module_param(maxpoll, int, 0);
87module_param(yieldlines, int, 0);
88module_param(video_nr, int, 0);
89
90static inline int read_lpstatus(struct qcam_device *q)
91{
92 return parport_read_status(q->pport);
93}
94
95static inline int read_lpdata(struct qcam_device *q)
96{
97 return parport_read_data(q->pport);
98}
99
100static inline void write_lpdata(struct qcam_device *q, int d)
101{
102 parport_write_data(q->pport, d);
103}
104
105static inline void write_lpcontrol(struct qcam_device *q, int d)
106{
Brett Warden7c596fa2007-10-02 17:37:21 -0300107 if (d & 0x20) {
Brett Warden9e19db52007-09-28 03:19:04 -0300108 /* Set bidirectional mode to reverse (data in) */
109 parport_data_reverse(q->pport);
110 } else {
111 /* Set bidirectional mode to forward (data out) */
112 parport_data_forward(q->pport);
113 }
114
115 /* Now issue the regular port command, but strip out the
116 * direction flag */
117 d &= ~0x20;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118 parport_write_control(q->pport, d);
119}
120
121static int qc_waithand(struct qcam_device *q, int val);
122static int qc_command(struct qcam_device *q, int command);
123static int qc_readparam(struct qcam_device *q);
124static int qc_setscanmode(struct qcam_device *q);
125static int qc_readbytes(struct qcam_device *q, char buffer[]);
126
127static struct video_device qcam_template;
128
129static int qc_calibrate(struct qcam_device *q)
130{
131 /*
132 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
133 * The white balance is an individiual value for each
134 * quickcam.
135 */
136
137 int value;
138 int count = 0;
139
140 qc_command(q, 27); /* AutoAdjustOffset */
141 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
142
143 /* GetOffset (33) will read 255 until autocalibration */
144 /* is finished. After that, a value of 1-254 will be */
145 /* returned. */
146
147 do {
148 qc_command(q, 33);
149 value = qc_readparam(q);
150 mdelay(1);
151 schedule();
152 count++;
153 } while (value == 0xff && count<2048);
154
155 q->whitebal = value;
156 return value;
157}
158
159/* Initialize the QuickCam driver control structure. This is where
160 * defaults are set for people who don't have a config file.*/
161
162static struct qcam_device *qcam_init(struct parport *port)
163{
164 struct qcam_device *q;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300165
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
167 if(q==NULL)
168 return NULL;
169
170 q->pport = port;
171 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
172 NULL, 0, NULL);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300173 if (q->pdev == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 {
175 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
176 port->name);
177 kfree(q);
178 return NULL;
179 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300180
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300182
Ingo Molnar3593cab2006-02-07 06:49:14 -0200183 mutex_init(&q->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184
185 q->port_mode = (QC_ANY | QC_NOTSET);
186 q->width = 320;
187 q->height = 240;
188 q->bpp = 4;
189 q->transfer_scale = 2;
190 q->contrast = 192;
191 q->brightness = 180;
192 q->whitebal = 105;
193 q->top = 1;
194 q->left = 14;
195 q->mode = -1;
196 q->status = QC_PARAM_CHANGE;
197 return q;
198}
199
200
201/* qc_command is probably a bit of a misnomer -- it's used to send
202 * bytes *to* the camera. Generally, these bytes are either commands
203 * or arguments to commands, so the name fits, but it still bugs me a
204 * bit. See the documentation for a list of commands. */
205
206static int qc_command(struct qcam_device *q, int command)
207{
208 int n1, n2;
209 int cmd;
210
211 write_lpdata(q, command);
212 write_lpcontrol(q, 6);
213
214 n1 = qc_waithand(q, 1);
215
216 write_lpcontrol(q, 0xe);
217 n2 = qc_waithand(q, 0);
218
219 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
220 return cmd;
221}
222
223static int qc_readparam(struct qcam_device *q)
224{
225 int n1, n2;
226 int cmd;
227
228 write_lpcontrol(q, 6);
229 n1 = qc_waithand(q, 1);
230
231 write_lpcontrol(q, 0xe);
232 n2 = qc_waithand(q, 0);
233
234 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
235 return cmd;
236}
237
238/* qc_waithand busy-waits for a handshake signal from the QuickCam.
239 * Almost all communication with the camera requires handshaking. */
240
241static int qc_waithand(struct qcam_device *q, int val)
242{
243 int status;
244 int runs=0;
245
246 if (val)
247 {
248 while (!((status = read_lpstatus(q)) & 8))
249 {
250 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300251 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 until the camera wakes up. However, we are
253 busy blocked until the camera responds, so
254 setting it lower is much better for interactive
255 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300256
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 if(runs++>maxpoll)
258 {
259 msleep_interruptible(5);
260 }
261 if(runs>(maxpoll+1000)) /* 5 seconds */
262 return -1;
263 }
264 }
265 else
266 {
267 while (((status = read_lpstatus(q)) & 8))
268 {
269 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300270 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271 until the camera wakes up. However, we are
272 busy blocked until the camera responds, so
273 setting it lower is much better for interactive
274 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300275
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 if(runs++>maxpoll)
277 {
278 msleep_interruptible(5);
279 }
280 if(runs++>(maxpoll+1000)) /* 5 seconds */
281 return -1;
282 }
283 }
284
285 return status;
286}
287
288/* Waithand2 is used when the qcam is in bidirectional mode, and the
289 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
290 * (bit 3 of status register). It also returns the last value read,
291 * since this data is useful. */
292
293static unsigned int qc_waithand2(struct qcam_device *q, int val)
294{
295 unsigned int status;
296 int runs=0;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300297
298 do
Linus Torvalds1da177e2005-04-16 15:20:36 -0700299 {
300 status = read_lpdata(q);
301 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300302 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 until the camera wakes up. However, we are
304 busy blocked until the camera responds, so
305 setting it lower is much better for interactive
306 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300307
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308 if(runs++>maxpoll)
309 {
310 msleep_interruptible(5);
311 }
312 if(runs++>(maxpoll+1000)) /* 5 seconds */
313 return 0;
314 }
315 while ((status & 1) != val);
316
317 return status;
318}
319
320
321/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
322 the status register at 5-10 Hz. This is only used in the autoprobe
323 code. Be aware that this isn't the way Connectix detects the
324 camera (they send a reset and try to handshake), but this should be
325 almost completely safe, while their method screws up my printer if
326 I plug it in before the camera. */
327
328static int qc_detect(struct qcam_device *q)
329{
330 int reg, lastreg;
331 int count = 0;
332 int i;
333
334 lastreg = reg = read_lpstatus(q) & 0xf0;
335
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300336 for (i = 0; i < 500; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337 {
338 reg = read_lpstatus(q) & 0xf0;
339 if (reg != lastreg)
340 count++;
341 lastreg = reg;
342 mdelay(2);
343 }
344
345
346#if 0
347 /* Force camera detection during testing. Sometimes the camera
348 won't be flashing these bits. Possibly unloading the module
349 in the middle of a grab? Or some timeout condition?
350 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
351 printk("Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
352 return 1;
353#endif
354
355 /* Be (even more) liberal in what you accept... */
356
357/* if (count > 30 && count < 200) */
Brett Warden7c596fa2007-10-02 17:37:21 -0300358 if (count > 20 && count < 400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 return 1; /* found */
Brett Warden9e19db52007-09-28 03:19:04 -0300360 } else {
Brett Warden7c596fa2007-10-02 17:37:21 -0300361 printk(KERN_ERR "No Quickcam found on port %s\n",
362 q->pport->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 return 0; /* not found */
Brett Warden9e19db52007-09-28 03:19:04 -0300364 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365}
366
367
368/* Reset the QuickCam. This uses the same sequence the Windows
369 * QuickPic program uses. Someone with a bi-directional port should
370 * check that bi-directional mode is detected right, and then
371 * implement bi-directional mode in qc_readbyte(). */
372
373static void qc_reset(struct qcam_device *q)
374{
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300375 switch (q->port_mode & QC_FORCE_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376 {
377 case QC_FORCE_UNIDIR:
378 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
379 break;
380
381 case QC_FORCE_BIDIR:
382 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
383 break;
384
385 case QC_ANY:
386 write_lpcontrol(q, 0x20);
387 write_lpdata(q, 0x75);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300388
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389 if (read_lpdata(q) != 0x75) {
390 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
391 } else {
392 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
393 }
394 break;
395 }
396
397 write_lpcontrol(q, 0xb);
398 udelay(250);
399 write_lpcontrol(q, 0xe);
400 qc_setscanmode(q); /* in case port_mode changed */
401}
402
403
404/* Decide which scan mode to use. There's no real requirement that
405 * the scanmode match the resolution in q->height and q-> width -- the
406 * camera takes the picture at the resolution specified in the
407 * "scanmode" and then returns the image at the resolution specified
408 * with the resolution commands. If the scan is bigger than the
409 * requested resolution, the upper-left hand corner of the scan is
410 * returned. If the scan is smaller, then the rest of the image
411 * returned contains garbage. */
412
413static int qc_setscanmode(struct qcam_device *q)
414{
415 int old_mode = q->mode;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300416
417 switch (q->transfer_scale)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418 {
419 case 1:
420 q->mode = 0;
421 break;
422 case 2:
423 q->mode = 4;
424 break;
425 case 4:
426 q->mode = 8;
427 break;
428 }
429
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300430 switch (q->bpp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431 {
432 case 4:
433 break;
434 case 6:
435 q->mode += 2;
436 break;
437 }
438
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300439 switch (q->port_mode & QC_MODE_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440 {
441 case QC_BIDIR:
442 q->mode += 1;
443 break;
444 case QC_NOTSET:
445 case QC_UNIDIR:
446 break;
447 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300448
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 if (q->mode != old_mode)
450 q->status |= QC_PARAM_CHANGE;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300451
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 return 0;
453}
454
455
456/* Reset the QuickCam and program for brightness, contrast,
457 * white-balance, and resolution. */
458
459static void qc_set(struct qcam_device *q)
460{
461 int val;
462 int val2;
463
464 qc_reset(q);
465
466 /* Set the brightness. Yes, this is repetitive, but it works.
467 * Shorter versions seem to fail subtly. Feel free to try :-). */
468 /* I think the problem was in qc_command, not here -- bls */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300469
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 qc_command(q, 0xb);
471 qc_command(q, q->brightness);
472
473 val = q->height / q->transfer_scale;
474 qc_command(q, 0x11);
475 qc_command(q, val);
476 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
477 /* The normal "transfers per line" calculation doesn't seem to work
478 as expected here (and yet it works fine in qc_scan). No idea
479 why this case is the odd man out. Fortunately, Laird's original
480 working version gives me a good way to guess at working values.
481 -- bls */
482 val = q->width;
483 val2 = q->transfer_scale * 4;
484 } else {
485 val = q->width * q->bpp;
486 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
487 q->transfer_scale;
488 }
489 val = (val + val2 - 1) / val2;
490 qc_command(q, 0x13);
491 qc_command(q, val);
492
493 /* Setting top and left -- bls */
494 qc_command(q, 0xd);
495 qc_command(q, q->top);
496 qc_command(q, 0xf);
497 qc_command(q, q->left / 2);
498
499 qc_command(q, 0x19);
500 qc_command(q, q->contrast);
501 qc_command(q, 0x1f);
502 qc_command(q, q->whitebal);
503
504 /* Clear flag that we must update the grabbing parameters on the camera
505 before we grab the next frame */
506 q->status &= (~QC_PARAM_CHANGE);
507}
508
509/* Qc_readbytes reads some bytes from the QC and puts them in
510 the supplied buffer. It returns the number of bytes read,
511 or -1 on error. */
512
513static inline int qc_readbytes(struct qcam_device *q, char buffer[])
514{
515 int ret=1;
516 unsigned int hi, lo;
517 unsigned int hi2, lo2;
518 static int state = 0;
519
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300520 if (buffer == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521 {
522 state = 0;
523 return 0;
524 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300525
526 switch (q->port_mode & QC_MODE_MASK)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527 {
528 case QC_BIDIR: /* Bi-directional Port */
529 write_lpcontrol(q, 0x26);
530 lo = (qc_waithand2(q, 1) >> 1);
531 hi = (read_lpstatus(q) >> 3) & 0x1f;
532 write_lpcontrol(q, 0x2e);
533 lo2 = (qc_waithand2(q, 0) >> 1);
534 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300535 switch (q->bpp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700536 {
537 case 4:
538 buffer[0] = lo & 0xf;
539 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
540 buffer[2] = (hi & 0x1e) >> 1;
541 buffer[3] = lo2 & 0xf;
542 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
543 buffer[5] = (hi2 & 0x1e) >> 1;
544 ret = 6;
545 break;
546 case 6:
547 buffer[0] = lo & 0x3f;
548 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
549 buffer[2] = lo2 & 0x3f;
550 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
551 ret = 4;
552 break;
553 }
554 break;
555
556 case QC_UNIDIR: /* Unidirectional Port */
557 write_lpcontrol(q, 6);
558 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
559 write_lpcontrol(q, 0xe);
560 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
561
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300562 switch (q->bpp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700563 {
564 case 4:
565 buffer[0] = lo;
566 buffer[1] = hi;
567 ret = 2;
568 break;
569 case 6:
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300570 switch (state)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 {
572 case 0:
573 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
574 q->saved_bits = (hi & 3) << 4;
575 state = 1;
576 ret = 1;
577 break;
578 case 1:
579 buffer[0] = lo | q->saved_bits;
580 q->saved_bits = hi << 2;
581 state = 2;
582 ret = 1;
583 break;
584 case 2:
585 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
586 buffer[1] = ((lo & 3) << 4) | hi;
587 state = 0;
588 ret = 2;
589 break;
590 }
591 break;
592 }
593 break;
594 }
595 return ret;
596}
597
598/* requests a scan from the camera. It sends the correct instructions
599 * to the camera and then reads back the correct number of bytes. In
600 * previous versions of this routine the return structure contained
601 * the raw output from the camera, and there was a 'qc_convertscan'
602 * function that converted that to a useful format. In version 0.3 I
603 * rolled qc_convertscan into qc_scan and now I only return the
604 * converted scan. The format is just an one-dimensional array of
605 * characters, one for each pixel, with 0=black up to n=white, where
606 * n=2^(bit depth)-1. Ask me for more details if you don't understand
607 * this. */
608
609static long qc_capture(struct qcam_device * q, char __user *buf, unsigned long len)
610{
611 int i, j, k, yield;
612 int bytes;
613 int linestotrans, transperline;
614 int divisor;
615 int pixels_per_line;
616 int pixels_read = 0;
617 int got=0;
618 char buffer[6];
619 int shift=8-q->bpp;
620 char invert;
621
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300622 if (q->mode == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 return -ENXIO;
624
625 qc_command(q, 0x7);
626 qc_command(q, q->mode);
627
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300628 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 {
630 write_lpcontrol(q, 0x2e); /* turn port around */
631 write_lpcontrol(q, 0x26);
632 (void) qc_waithand(q, 1);
633 write_lpcontrol(q, 0x2e);
634 (void) qc_waithand(q, 0);
635 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300636
Linus Torvalds1da177e2005-04-16 15:20:36 -0700637 /* strange -- should be 15:63 below, but 4bpp is odd */
638 invert = (q->bpp == 4) ? 16 : 63;
639
640 linestotrans = q->height / q->transfer_scale;
641 pixels_per_line = q->width / q->transfer_scale;
642 transperline = q->width * q->bpp;
643 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
644 q->transfer_scale;
645 transperline = (transperline + divisor - 1) / divisor;
646
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300647 for (i = 0, yield = yieldlines; i < linestotrans; i++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 {
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300649 for (pixels_read = j = 0; j < transperline; j++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 {
651 bytes = qc_readbytes(q, buffer);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300652 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700653 {
654 int o;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300655 if (buffer[k] == 0 && invert == 16)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 {
657 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
658 must be 0-15 -- bls */
659 buffer[k] = 16;
660 }
661 o=i*pixels_per_line + pixels_read + k;
662 if(o<len)
663 {
664 got++;
665 put_user((invert - buffer[k])<<shift, buf+o);
666 }
667 }
668 pixels_read += bytes;
669 }
670 (void) qc_readbytes(q, NULL); /* reset state machine */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300671
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 /* Grabbing an entire frame from the quickcam is a lengthy
673 process. We don't (usually) want to busy-block the
674 processor for the entire frame. yieldlines is a module
675 parameter. If we yield every line, the minimum frame
676 time will be 240 / 200 = 1.2 seconds. The compile-time
677 default is to yield every 4 lines. */
678 if (i >= yield) {
679 msleep_interruptible(5);
680 yield = i + yieldlines;
681 }
682 }
683
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300684 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 {
686 write_lpcontrol(q, 2);
687 write_lpcontrol(q, 6);
688 udelay(3);
689 write_lpcontrol(q, 0xe);
690 }
691 if(got<len)
692 return got;
693 return len;
694}
695
696/*
697 * Video4linux interfacing
698 */
699
700static int qcam_do_ioctl(struct inode *inode, struct file *file,
701 unsigned int cmd, void *arg)
702{
703 struct video_device *dev = video_devdata(file);
704 struct qcam_device *qcam=(struct qcam_device *)dev;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300705
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706 switch(cmd)
707 {
708 case VIDIOCGCAP:
709 {
710 struct video_capability *b = arg;
711 strcpy(b->name, "Quickcam");
712 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
713 b->channels = 1;
714 b->audios = 0;
715 b->maxwidth = 320;
716 b->maxheight = 240;
717 b->minwidth = 80;
718 b->minheight = 60;
719 return 0;
720 }
721 case VIDIOCGCHAN:
722 {
723 struct video_channel *v = arg;
724 if(v->channel!=0)
725 return -EINVAL;
726 v->flags=0;
727 v->tuners=0;
728 /* Good question.. its composite or SVHS so.. */
729 v->type = VIDEO_TYPE_CAMERA;
730 strcpy(v->name, "Camera");
731 return 0;
732 }
733 case VIDIOCSCHAN:
734 {
735 struct video_channel *v = arg;
736 if(v->channel!=0)
737 return -EINVAL;
738 return 0;
739 }
740 case VIDIOCGTUNER:
741 {
742 struct video_tuner *v = arg;
743 if(v->tuner)
744 return -EINVAL;
745 strcpy(v->name, "Format");
746 v->rangelow=0;
747 v->rangehigh=0;
748 v->flags= 0;
749 v->mode = VIDEO_MODE_AUTO;
750 return 0;
751 }
752 case VIDIOCSTUNER:
753 {
754 struct video_tuner *v = arg;
755 if(v->tuner)
756 return -EINVAL;
757 if(v->mode!=VIDEO_MODE_AUTO)
758 return -EINVAL;
759 return 0;
760 }
761 case VIDIOCGPICT:
762 {
763 struct video_picture *p = arg;
764 p->colour=0x8000;
765 p->hue=0x8000;
766 p->brightness=qcam->brightness<<8;
767 p->contrast=qcam->contrast<<8;
768 p->whiteness=qcam->whitebal<<8;
769 p->depth=qcam->bpp;
770 p->palette=VIDEO_PALETTE_GREY;
771 return 0;
772 }
773 case VIDIOCSPICT:
774 {
775 struct video_picture *p = arg;
776 if(p->palette!=VIDEO_PALETTE_GREY)
Trent Piepho657de3c2006-06-20 00:30:57 -0300777 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 if(p->depth!=4 && p->depth!=6)
779 return -EINVAL;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300780
Linus Torvalds1da177e2005-04-16 15:20:36 -0700781 /*
782 * Now load the camera.
783 */
784
785 qcam->brightness = p->brightness>>8;
786 qcam->contrast = p->contrast>>8;
787 qcam->whitebal = p->whiteness>>8;
788 qcam->bpp = p->depth;
789
Ingo Molnar3593cab2006-02-07 06:49:14 -0200790 mutex_lock(&qcam->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 qc_setscanmode(qcam);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200792 mutex_unlock(&qcam->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793 qcam->status |= QC_PARAM_CHANGE;
794
795 return 0;
796 }
797 case VIDIOCSWIN:
798 {
799 struct video_window *vw = arg;
800 if(vw->flags)
801 return -EINVAL;
802 if(vw->clipcount)
803 return -EINVAL;
804 if(vw->height<60||vw->height>240)
805 return -EINVAL;
806 if(vw->width<80||vw->width>320)
807 return -EINVAL;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300808
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809 qcam->width = 320;
810 qcam->height = 240;
811 qcam->transfer_scale = 4;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300812
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 if(vw->width>=160 && vw->height>=120)
814 {
815 qcam->transfer_scale = 2;
816 }
817 if(vw->width>=320 && vw->height>=240)
818 {
819 qcam->width = 320;
820 qcam->height = 240;
821 qcam->transfer_scale = 1;
822 }
Ingo Molnar3593cab2006-02-07 06:49:14 -0200823 mutex_lock(&qcam->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 qc_setscanmode(qcam);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200825 mutex_unlock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300826
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 /* We must update the camera before we grab. We could
828 just have changed the grab size */
829 qcam->status |= QC_PARAM_CHANGE;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300830
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 /* Ok we figured out what to use from our wide choice */
832 return 0;
833 }
834 case VIDIOCGWIN:
835 {
836 struct video_window *vw = arg;
837 memset(vw, 0, sizeof(*vw));
838 vw->width=qcam->width/qcam->transfer_scale;
839 vw->height=qcam->height/qcam->transfer_scale;
840 return 0;
841 }
842 case VIDIOCKEY:
843 return 0;
844 case VIDIOCCAPTURE:
845 case VIDIOCGFBUF:
846 case VIDIOCSFBUF:
847 case VIDIOCGFREQ:
848 case VIDIOCSFREQ:
849 case VIDIOCGAUDIO:
850 case VIDIOCSAUDIO:
851 return -EINVAL;
852 default:
853 return -ENOIOCTLCMD;
854 }
855 return 0;
856}
857
858static int qcam_ioctl(struct inode *inode, struct file *file,
859 unsigned int cmd, unsigned long arg)
860{
861 return video_usercopy(inode, file, cmd, arg, qcam_do_ioctl);
862}
863
864static ssize_t qcam_read(struct file *file, char __user *buf,
865 size_t count, loff_t *ppos)
866{
867 struct video_device *v = video_devdata(file);
868 struct qcam_device *qcam=(struct qcam_device *)v;
869 int len;
870 parport_claim_or_block(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300871
Ingo Molnar3593cab2006-02-07 06:49:14 -0200872 mutex_lock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300873
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 qc_reset(qcam);
875
876 /* Update the camera parameters if we need to */
877 if (qcam->status & QC_PARAM_CHANGE)
878 qc_set(qcam);
879
880 len=qc_capture(qcam, buf,count);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300881
Ingo Molnar3593cab2006-02-07 06:49:14 -0200882 mutex_unlock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300883
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 parport_release(qcam->pdev);
885 return len;
886}
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300887
Arjan van de Venfa027c22007-02-12 00:55:33 -0800888static const struct file_operations qcam_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 .owner = THIS_MODULE,
890 .open = video_exclusive_open,
891 .release = video_exclusive_release,
892 .ioctl = qcam_ioctl,
Arnd Bergmann0d0fbf82006-01-09 15:24:57 -0200893 .compat_ioctl = v4l_compat_ioctl32,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894 .read = qcam_read,
895 .llseek = no_llseek,
896};
897static struct video_device qcam_template=
898{
899 .owner = THIS_MODULE,
900 .name = "Connectix Quickcam",
901 .type = VID_TYPE_CAPTURE,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 .fops = &qcam_fops,
903};
904
905#define MAX_CAMS 4
906static struct qcam_device *qcams[MAX_CAMS];
907static unsigned int num_cams = 0;
908
909static int init_bwqcam(struct parport *port)
910{
911 struct qcam_device *qcam;
912
913 if (num_cams == MAX_CAMS)
914 {
915 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
916 return -ENOSPC;
917 }
918
919 qcam=qcam_init(port);
920 if(qcam==NULL)
921 return -ENODEV;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300922
Linus Torvalds1da177e2005-04-16 15:20:36 -0700923 parport_claim_or_block(qcam->pdev);
924
925 qc_reset(qcam);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300926
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927 if(qc_detect(qcam)==0)
928 {
929 parport_release(qcam->pdev);
930 parport_unregister_device(qcam->pdev);
931 kfree(qcam);
932 return -ENODEV;
933 }
934 qc_calibrate(qcam);
935
936 parport_release(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300937
Linus Torvalds1da177e2005-04-16 15:20:36 -0700938 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300939
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940 if(video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr)==-1)
941 {
942 parport_unregister_device(qcam->pdev);
943 kfree(qcam);
944 return -ENODEV;
945 }
946
947 qcams[num_cams++] = qcam;
948
949 return 0;
950}
951
952static void close_bwqcam(struct qcam_device *qcam)
953{
954 video_unregister_device(&qcam->vdev);
955 parport_unregister_device(qcam->pdev);
956 kfree(qcam);
957}
958
959/* The parport parameter controls which parports will be scanned.
960 * Scanning all parports causes some printers to print a garbage page.
961 * -- March 14, 1999 Billy Donahue <billy@escape.com> */
962#ifdef MODULE
963static char *parport[MAX_CAMS] = { NULL, };
964module_param_array(parport, charp, NULL, 0);
965#endif
966
967static int accept_bwqcam(struct parport *port)
968{
969#ifdef MODULE
970 int n;
971
972 if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
973 /* user gave parport parameters */
974 for(n=0; parport[n] && n<MAX_CAMS; n++){
975 char *ep;
976 unsigned long r;
977 r = simple_strtoul(parport[n], &ep, 0);
978 if (ep == parport[n]) {
979 printk(KERN_ERR
980 "bw-qcam: bad port specifier \"%s\"\n",
981 parport[n]);
982 continue;
983 }
984 if (r == port->number)
985 return 1;
986 }
987 return 0;
988 }
989#endif
990 return 1;
991}
992
993static void bwqcam_attach(struct parport *port)
994{
995 if (accept_bwqcam(port))
996 init_bwqcam(port);
997}
998
999static void bwqcam_detach(struct parport *port)
1000{
1001 int i;
1002 for (i = 0; i < num_cams; i++) {
1003 struct qcam_device *qcam = qcams[i];
1004 if (qcam && qcam->pdev->port == port) {
1005 qcams[i] = NULL;
1006 close_bwqcam(qcam);
1007 }
1008 }
1009}
1010
1011static struct parport_driver bwqcam_driver = {
1012 .name = "bw-qcam",
1013 .attach = bwqcam_attach,
1014 .detach = bwqcam_detach,
1015};
1016
1017static void __exit exit_bw_qcams(void)
1018{
1019 parport_unregister_driver(&bwqcam_driver);
1020}
1021
1022static int __init init_bw_qcams(void)
1023{
1024#ifdef MODULE
1025 /* Do some sanity checks on the module parameters. */
1026 if (maxpoll > 5000) {
1027 printk("Connectix Quickcam max-poll was above 5000. Using 5000.\n");
1028 maxpoll = 5000;
1029 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001030
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031 if (yieldlines < 1) {
1032 printk("Connectix Quickcam yieldlines was less than 1. Using 1.\n");
1033 yieldlines = 1;
1034 }
1035#endif
1036 return parport_register_driver(&bwqcam_driver);
1037}
1038
1039module_init(init_bw_qcams);
1040module_exit(exit_bw_qcams);
1041
1042MODULE_LICENSE("GPL");