blob: 3c9e754d73a053199376098170ee5e80b9a86f37 [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>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030077#include <media/v4l2-ioctl.h>
Ingo Molnar3593cab2006-02-07 06:49:14 -020078#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070079#include <asm/uaccess.h>
80
81#include "bw-qcam.h"
82
Hans Verkuil1d61aac2010-03-22 04:36:04 -030083static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
84static unsigned int yieldlines = 4; /* Yield after this many during capture */
Linus Torvalds1da177e2005-04-16 15:20:36 -070085static int video_nr = -1;
Brett T. Wardend685a482008-01-10 04:33:31 -030086static unsigned int force_init; /* Whether to probe aggressively */
Linus Torvalds1da177e2005-04-16 15:20:36 -070087
88module_param(maxpoll, int, 0);
89module_param(yieldlines, int, 0);
90module_param(video_nr, int, 0);
91
Brett T. Wardend685a482008-01-10 04:33:31 -030092/* Set force_init=1 to avoid detection by polling status register and
93 * immediately attempt to initialize qcam */
94module_param(force_init, int, 0);
95
Linus Torvalds1da177e2005-04-16 15:20:36 -070096static inline int read_lpstatus(struct qcam_device *q)
97{
98 return parport_read_status(q->pport);
99}
100
101static inline int read_lpdata(struct qcam_device *q)
102{
103 return parport_read_data(q->pport);
104}
105
106static inline void write_lpdata(struct qcam_device *q, int d)
107{
108 parport_write_data(q->pport, d);
109}
110
111static inline void write_lpcontrol(struct qcam_device *q, int d)
112{
Brett Warden7c596fa2007-10-02 17:37:21 -0300113 if (d & 0x20) {
Brett Warden9e19db52007-09-28 03:19:04 -0300114 /* Set bidirectional mode to reverse (data in) */
115 parport_data_reverse(q->pport);
116 } else {
117 /* Set bidirectional mode to forward (data out) */
118 parport_data_forward(q->pport);
119 }
120
121 /* Now issue the regular port command, but strip out the
122 * direction flag */
123 d &= ~0x20;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 parport_write_control(q->pport, d);
125}
126
127static int qc_waithand(struct qcam_device *q, int val);
128static int qc_command(struct qcam_device *q, int command);
129static int qc_readparam(struct qcam_device *q);
130static int qc_setscanmode(struct qcam_device *q);
131static int qc_readbytes(struct qcam_device *q, char buffer[]);
132
133static struct video_device qcam_template;
134
135static int qc_calibrate(struct qcam_device *q)
136{
137 /*
138 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
139 * The white balance is an individiual value for each
140 * quickcam.
141 */
142
143 int value;
144 int count = 0;
145
146 qc_command(q, 27); /* AutoAdjustOffset */
147 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
148
149 /* GetOffset (33) will read 255 until autocalibration */
150 /* is finished. After that, a value of 1-254 will be */
151 /* returned. */
152
153 do {
154 qc_command(q, 33);
155 value = qc_readparam(q);
156 mdelay(1);
157 schedule();
158 count++;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300159 } while (value == 0xff && count < 2048);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700160
161 q->whitebal = value;
162 return value;
163}
164
165/* Initialize the QuickCam driver control structure. This is where
166 * defaults are set for people who don't have a config file.*/
167
168static struct qcam_device *qcam_init(struct parport *port)
169{
170 struct qcam_device *q;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300171
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172 q = kmalloc(sizeof(struct qcam_device), GFP_KERNEL);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300173 if (q == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174 return NULL;
175
176 q->pport = port;
177 q->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300178 NULL, 0, NULL);
179 if (q->pdev == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 printk(KERN_ERR "bw-qcam: couldn't register for %s.\n",
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300181 port->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 kfree(q);
183 return NULL;
184 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300185
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 memcpy(&q->vdev, &qcam_template, sizeof(qcam_template));
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300187
Ingo Molnar3593cab2006-02-07 06:49:14 -0200188 mutex_init(&q->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189
190 q->port_mode = (QC_ANY | QC_NOTSET);
191 q->width = 320;
192 q->height = 240;
193 q->bpp = 4;
194 q->transfer_scale = 2;
195 q->contrast = 192;
196 q->brightness = 180;
197 q->whitebal = 105;
198 q->top = 1;
199 q->left = 14;
200 q->mode = -1;
201 q->status = QC_PARAM_CHANGE;
202 return q;
203}
204
205
206/* qc_command is probably a bit of a misnomer -- it's used to send
207 * bytes *to* the camera. Generally, these bytes are either commands
208 * or arguments to commands, so the name fits, but it still bugs me a
209 * bit. See the documentation for a list of commands. */
210
211static int qc_command(struct qcam_device *q, int command)
212{
213 int n1, n2;
214 int cmd;
215
216 write_lpdata(q, command);
217 write_lpcontrol(q, 6);
218
219 n1 = qc_waithand(q, 1);
220
221 write_lpcontrol(q, 0xe);
222 n2 = qc_waithand(q, 0);
223
224 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
225 return cmd;
226}
227
228static int qc_readparam(struct qcam_device *q)
229{
230 int n1, n2;
231 int cmd;
232
233 write_lpcontrol(q, 6);
234 n1 = qc_waithand(q, 1);
235
236 write_lpcontrol(q, 0xe);
237 n2 = qc_waithand(q, 0);
238
239 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
240 return cmd;
241}
242
243/* qc_waithand busy-waits for a handshake signal from the QuickCam.
244 * Almost all communication with the camera requires handshaking. */
245
246static int qc_waithand(struct qcam_device *q, int val)
247{
248 int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300249 int runs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700250
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300251 if (val) {
252 while (!((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700253 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300254 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 until the camera wakes up. However, we are
256 busy blocked until the camera responds, so
257 setting it lower is much better for interactive
258 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300259
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300260 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300262 if (runs > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263 return -1;
264 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300265 } else {
266 while (((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300268 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269 until the camera wakes up. However, we are
270 busy blocked until the camera responds, so
271 setting it lower is much better for interactive
272 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300273
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300274 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700275 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300276 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 return -1;
278 }
279 }
280
281 return status;
282}
283
284/* Waithand2 is used when the qcam is in bidirectional mode, and the
285 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
286 * (bit 3 of status register). It also returns the last value read,
287 * since this data is useful. */
288
289static unsigned int qc_waithand2(struct qcam_device *q, int val)
290{
291 unsigned int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300292 int runs = 0;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300293
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300294 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700295 status = read_lpdata(q);
296 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300297 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 until the camera wakes up. However, we are
299 busy blocked until the camera responds, so
300 setting it lower is much better for interactive
301 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300302
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300303 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300305 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700306 return 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300307 } while ((status & 1) != val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308
309 return status;
310}
311
312
313/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
314 the status register at 5-10 Hz. This is only used in the autoprobe
315 code. Be aware that this isn't the way Connectix detects the
316 camera (they send a reset and try to handshake), but this should be
317 almost completely safe, while their method screws up my printer if
318 I plug it in before the camera. */
319
320static int qc_detect(struct qcam_device *q)
321{
322 int reg, lastreg;
323 int count = 0;
324 int i;
325
Brett T. Wardend685a482008-01-10 04:33:31 -0300326 if (force_init)
327 return 1;
328
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 lastreg = reg = read_lpstatus(q) & 0xf0;
330
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300331 for (i = 0; i < 500; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332 reg = read_lpstatus(q) & 0xf0;
333 if (reg != lastreg)
334 count++;
335 lastreg = reg;
336 mdelay(2);
337 }
338
339
340#if 0
341 /* Force camera detection during testing. Sometimes the camera
342 won't be flashing these bits. Possibly unloading the module
343 in the middle of a grab? Or some timeout condition?
344 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300345 printk(KERN_DEBUG "Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 return 1;
347#endif
348
349 /* Be (even more) liberal in what you accept... */
350
Brett Warden7c596fa2007-10-02 17:37:21 -0300351 if (count > 20 && count < 400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 return 1; /* found */
Brett Warden9e19db52007-09-28 03:19:04 -0300353 } else {
Brett Warden7c596fa2007-10-02 17:37:21 -0300354 printk(KERN_ERR "No Quickcam found on port %s\n",
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300355 q->pport->name);
Brett T. Wardend685a482008-01-10 04:33:31 -0300356 printk(KERN_DEBUG "Quickcam detection counter: %u\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 return 0; /* not found */
Brett Warden9e19db52007-09-28 03:19:04 -0300358 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359}
360
361
362/* Reset the QuickCam. This uses the same sequence the Windows
363 * QuickPic program uses. Someone with a bi-directional port should
364 * check that bi-directional mode is detected right, and then
365 * implement bi-directional mode in qc_readbyte(). */
366
367static void qc_reset(struct qcam_device *q)
368{
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300369 switch (q->port_mode & QC_FORCE_MASK) {
370 case QC_FORCE_UNIDIR:
371 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
372 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300374 case QC_FORCE_BIDIR:
375 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
376 break;
377
378 case QC_ANY:
379 write_lpcontrol(q, 0x20);
380 write_lpdata(q, 0x75);
381
382 if (read_lpdata(q) != 0x75)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300384 else
385 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
386 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387 }
388
389 write_lpcontrol(q, 0xb);
390 udelay(250);
391 write_lpcontrol(q, 0xe);
392 qc_setscanmode(q); /* in case port_mode changed */
393}
394
395
396/* Decide which scan mode to use. There's no real requirement that
397 * the scanmode match the resolution in q->height and q-> width -- the
398 * camera takes the picture at the resolution specified in the
399 * "scanmode" and then returns the image at the resolution specified
400 * with the resolution commands. If the scan is bigger than the
401 * requested resolution, the upper-left hand corner of the scan is
402 * returned. If the scan is smaller, then the rest of the image
403 * returned contains garbage. */
404
405static int qc_setscanmode(struct qcam_device *q)
406{
407 int old_mode = q->mode;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300408
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300409 switch (q->transfer_scale) {
410 case 1:
411 q->mode = 0;
412 break;
413 case 2:
414 q->mode = 4;
415 break;
416 case 4:
417 q->mode = 8;
418 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 }
420
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300421 switch (q->bpp) {
422 case 4:
423 break;
424 case 6:
425 q->mode += 2;
426 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 }
428
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300429 switch (q->port_mode & QC_MODE_MASK) {
430 case QC_BIDIR:
431 q->mode += 1;
432 break;
433 case QC_NOTSET:
434 case QC_UNIDIR:
435 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300437
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 if (q->mode != old_mode)
439 q->status |= QC_PARAM_CHANGE;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300440
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 return 0;
442}
443
444
445/* Reset the QuickCam and program for brightness, contrast,
446 * white-balance, and resolution. */
447
448static void qc_set(struct qcam_device *q)
449{
450 int val;
451 int val2;
452
453 qc_reset(q);
454
455 /* Set the brightness. Yes, this is repetitive, but it works.
456 * Shorter versions seem to fail subtly. Feel free to try :-). */
457 /* I think the problem was in qc_command, not here -- bls */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300458
Linus Torvalds1da177e2005-04-16 15:20:36 -0700459 qc_command(q, 0xb);
460 qc_command(q, q->brightness);
461
462 val = q->height / q->transfer_scale;
463 qc_command(q, 0x11);
464 qc_command(q, val);
465 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
466 /* The normal "transfers per line" calculation doesn't seem to work
467 as expected here (and yet it works fine in qc_scan). No idea
468 why this case is the odd man out. Fortunately, Laird's original
469 working version gives me a good way to guess at working values.
470 -- bls */
471 val = q->width;
472 val2 = q->transfer_scale * 4;
473 } else {
474 val = q->width * q->bpp;
475 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300476 q->transfer_scale;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700477 }
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300478 val = DIV_ROUND_UP(val, val2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 qc_command(q, 0x13);
480 qc_command(q, val);
481
482 /* Setting top and left -- bls */
483 qc_command(q, 0xd);
484 qc_command(q, q->top);
485 qc_command(q, 0xf);
486 qc_command(q, q->left / 2);
487
488 qc_command(q, 0x19);
489 qc_command(q, q->contrast);
490 qc_command(q, 0x1f);
491 qc_command(q, q->whitebal);
492
493 /* Clear flag that we must update the grabbing parameters on the camera
494 before we grab the next frame */
495 q->status &= (~QC_PARAM_CHANGE);
496}
497
498/* Qc_readbytes reads some bytes from the QC and puts them in
499 the supplied buffer. It returns the number of bytes read,
500 or -1 on error. */
501
502static inline int qc_readbytes(struct qcam_device *q, char buffer[])
503{
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300504 int ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505 unsigned int hi, lo;
506 unsigned int hi2, lo2;
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300507 static int state;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300509 if (buffer == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 state = 0;
511 return 0;
512 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300513
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300514 switch (q->port_mode & QC_MODE_MASK) {
515 case QC_BIDIR: /* Bi-directional Port */
516 write_lpcontrol(q, 0x26);
517 lo = (qc_waithand2(q, 1) >> 1);
518 hi = (read_lpstatus(q) >> 3) & 0x1f;
519 write_lpcontrol(q, 0x2e);
520 lo2 = (qc_waithand2(q, 0) >> 1);
521 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
522 switch (q->bpp) {
523 case 4:
524 buffer[0] = lo & 0xf;
525 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
526 buffer[2] = (hi & 0x1e) >> 1;
527 buffer[3] = lo2 & 0xf;
528 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
529 buffer[5] = (hi2 & 0x1e) >> 1;
530 ret = 6;
531 break;
532 case 6:
533 buffer[0] = lo & 0x3f;
534 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
535 buffer[2] = lo2 & 0x3f;
536 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
537 ret = 4;
538 break;
539 }
540 break;
541
542 case QC_UNIDIR: /* Unidirectional Port */
543 write_lpcontrol(q, 6);
544 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
545 write_lpcontrol(q, 0xe);
546 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
547
548 switch (q->bpp) {
549 case 4:
550 buffer[0] = lo;
551 buffer[1] = hi;
552 ret = 2;
553 break;
554 case 6:
555 switch (state) {
556 case 0:
557 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
558 q->saved_bits = (hi & 3) << 4;
559 state = 1;
560 ret = 1;
561 break;
562 case 1:
563 buffer[0] = lo | q->saved_bits;
564 q->saved_bits = hi << 2;
565 state = 2;
566 ret = 1;
567 break;
568 case 2:
569 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
570 buffer[1] = ((lo & 3) << 4) | hi;
571 state = 0;
572 ret = 2;
573 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574 }
575 break;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300576 }
577 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 }
579 return ret;
580}
581
582/* requests a scan from the camera. It sends the correct instructions
583 * to the camera and then reads back the correct number of bytes. In
584 * previous versions of this routine the return structure contained
585 * the raw output from the camera, and there was a 'qc_convertscan'
586 * function that converted that to a useful format. In version 0.3 I
587 * rolled qc_convertscan into qc_scan and now I only return the
588 * converted scan. The format is just an one-dimensional array of
589 * characters, one for each pixel, with 0=black up to n=white, where
590 * n=2^(bit depth)-1. Ask me for more details if you don't understand
591 * this. */
592
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300593static long qc_capture(struct qcam_device *q, char __user *buf, unsigned long len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594{
595 int i, j, k, yield;
596 int bytes;
597 int linestotrans, transperline;
598 int divisor;
599 int pixels_per_line;
600 int pixels_read = 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300601 int got = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 char buffer[6];
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300603 int shift = 8 - q->bpp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 char invert;
605
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300606 if (q->mode == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 return -ENXIO;
608
609 qc_command(q, 0x7);
610 qc_command(q, q->mode);
611
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300612 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 write_lpcontrol(q, 0x2e); /* turn port around */
614 write_lpcontrol(q, 0x26);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300615 qc_waithand(q, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 write_lpcontrol(q, 0x2e);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300617 qc_waithand(q, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 /* strange -- should be 15:63 below, but 4bpp is odd */
621 invert = (q->bpp == 4) ? 16 : 63;
622
623 linestotrans = q->height / q->transfer_scale;
624 pixels_per_line = q->width / q->transfer_scale;
625 transperline = q->width * q->bpp;
626 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300627 q->transfer_scale;
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300628 transperline = DIV_ROUND_UP(transperline, divisor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300630 for (i = 0, yield = yieldlines; i < linestotrans; i++) {
631 for (pixels_read = j = 0; j < transperline; j++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 bytes = qc_readbytes(q, buffer);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300633 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 int o;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300635 if (buffer[k] == 0 && invert == 16) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
637 must be 0-15 -- bls */
638 buffer[k] = 16;
639 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300640 o = i * pixels_per_line + pixels_read + k;
641 if (o < len) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700642 got++;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300643 put_user((invert - buffer[k]) << shift, buf + o);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 }
645 }
646 pixels_read += bytes;
647 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300648 qc_readbytes(q, NULL); /* reset state machine */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300649
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 /* Grabbing an entire frame from the quickcam is a lengthy
651 process. We don't (usually) want to busy-block the
652 processor for the entire frame. yieldlines is a module
653 parameter. If we yield every line, the minimum frame
654 time will be 240 / 200 = 1.2 seconds. The compile-time
655 default is to yield every 4 lines. */
656 if (i >= yield) {
657 msleep_interruptible(5);
658 yield = i + yieldlines;
659 }
660 }
661
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300662 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663 write_lpcontrol(q, 2);
664 write_lpcontrol(q, 6);
665 udelay(3);
666 write_lpcontrol(q, 0xe);
667 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300668 if (got < len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700669 return got;
670 return len;
671}
672
673/*
674 * Video4linux interfacing
675 */
676
Hans Verkuil069b7472008-12-30 07:04:34 -0300677static long qcam_do_ioctl(struct file *file, unsigned int cmd, void *arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678{
679 struct video_device *dev = video_devdata(file);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300680 struct qcam_device *qcam = (struct qcam_device *)dev;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300681
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300682 switch (cmd) {
683 case VIDIOCGCAP:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 {
685 struct video_capability *b = arg;
686 strcpy(b->name, "Quickcam");
687 b->type = VID_TYPE_CAPTURE|VID_TYPE_SCALES|VID_TYPE_MONOCHROME;
688 b->channels = 1;
689 b->audios = 0;
690 b->maxwidth = 320;
691 b->maxheight = 240;
692 b->minwidth = 80;
693 b->minheight = 60;
694 return 0;
695 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300696 case VIDIOCGCHAN:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700697 {
698 struct video_channel *v = arg;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300699 if (v->channel != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 return -EINVAL;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300701 v->flags = 0;
702 v->tuners = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 /* Good question.. its composite or SVHS so.. */
704 v->type = VIDEO_TYPE_CAMERA;
705 strcpy(v->name, "Camera");
706 return 0;
707 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300708 case VIDIOCSCHAN:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 {
710 struct video_channel *v = arg;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300711 if (v->channel != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 return -EINVAL;
713 return 0;
714 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300715 case VIDIOCGTUNER:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 {
717 struct video_tuner *v = arg;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300718 if (v->tuner)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700719 return -EINVAL;
720 strcpy(v->name, "Format");
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300721 v->rangelow = 0;
722 v->rangehigh = 0;
723 v->flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 v->mode = VIDEO_MODE_AUTO;
725 return 0;
726 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300727 case VIDIOCSTUNER:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 {
729 struct video_tuner *v = arg;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300730 if (v->tuner)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 return -EINVAL;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300732 if (v->mode != VIDEO_MODE_AUTO)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 return -EINVAL;
734 return 0;
735 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300736 case VIDIOCGPICT:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 {
738 struct video_picture *p = arg;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300739 p->colour = 0x8000;
740 p->hue = 0x8000;
741 p->brightness = qcam->brightness << 8;
742 p->contrast = qcam->contrast << 8;
743 p->whiteness = qcam->whitebal << 8;
744 p->depth = qcam->bpp;
745 p->palette = VIDEO_PALETTE_GREY;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 return 0;
747 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300748 case VIDIOCSPICT:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 {
750 struct video_picture *p = arg;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300751 if (p->palette != VIDEO_PALETTE_GREY)
Trent Piepho657de3c2006-06-20 00:30:57 -0300752 return -EINVAL;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300753 if (p->depth != 4 && p->depth != 6)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700754 return -EINVAL;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300755
Linus Torvalds1da177e2005-04-16 15:20:36 -0700756 /*
757 * Now load the camera.
758 */
759
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300760 qcam->brightness = p->brightness >> 8;
761 qcam->contrast = p->contrast >> 8;
762 qcam->whitebal = p->whiteness >> 8;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700763 qcam->bpp = p->depth;
764
Ingo Molnar3593cab2006-02-07 06:49:14 -0200765 mutex_lock(&qcam->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766 qc_setscanmode(qcam);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200767 mutex_unlock(&qcam->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 qcam->status |= QC_PARAM_CHANGE;
769
770 return 0;
771 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300772 case VIDIOCSWIN:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700773 {
774 struct video_window *vw = arg;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300775 if (vw->flags)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776 return -EINVAL;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300777 if (vw->clipcount)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778 return -EINVAL;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300779 if (vw->height < 60 || vw->height > 240)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780 return -EINVAL;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300781 if (vw->width < 80 || vw->width > 320)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 return -EINVAL;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300783
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 qcam->width = 320;
785 qcam->height = 240;
786 qcam->transfer_scale = 4;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300787
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300788 if (vw->width >= 160 && vw->height >= 120)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 qcam->transfer_scale = 2;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300790 if (vw->width >= 320 && vw->height >= 240) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700791 qcam->width = 320;
792 qcam->height = 240;
793 qcam->transfer_scale = 1;
794 }
Ingo Molnar3593cab2006-02-07 06:49:14 -0200795 mutex_lock(&qcam->lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 qc_setscanmode(qcam);
Ingo Molnar3593cab2006-02-07 06:49:14 -0200797 mutex_unlock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300798
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 /* We must update the camera before we grab. We could
800 just have changed the grab size */
801 qcam->status |= QC_PARAM_CHANGE;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300802
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 /* Ok we figured out what to use from our wide choice */
804 return 0;
805 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300806 case VIDIOCGWIN:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 {
808 struct video_window *vw = arg;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300809
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 memset(vw, 0, sizeof(*vw));
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300811 vw->width = qcam->width / qcam->transfer_scale;
812 vw->height = qcam->height / qcam->transfer_scale;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 return 0;
814 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300815 case VIDIOCKEY:
816 return 0;
817 case VIDIOCCAPTURE:
818 case VIDIOCGFBUF:
819 case VIDIOCSFBUF:
820 case VIDIOCGFREQ:
821 case VIDIOCSFREQ:
822 case VIDIOCGAUDIO:
823 case VIDIOCSAUDIO:
824 return -EINVAL;
825 default:
826 return -ENOIOCTLCMD;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 }
828 return 0;
829}
830
Hans Verkuil069b7472008-12-30 07:04:34 -0300831static long qcam_ioctl(struct file *file,
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300832 unsigned int cmd, unsigned long arg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700833{
Hans Verkuilf473bf72008-11-01 08:25:11 -0300834 return video_usercopy(file, cmd, arg, qcam_do_ioctl);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835}
836
837static ssize_t qcam_read(struct file *file, char __user *buf,
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300838 size_t count, loff_t *ppos)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839{
840 struct video_device *v = video_devdata(file);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300841 struct qcam_device *qcam = (struct qcam_device *)v;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 int len;
843 parport_claim_or_block(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300844
Ingo Molnar3593cab2006-02-07 06:49:14 -0200845 mutex_lock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300846
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847 qc_reset(qcam);
848
849 /* Update the camera parameters if we need to */
850 if (qcam->status & QC_PARAM_CHANGE)
851 qc_set(qcam);
852
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300853 len = qc_capture(qcam, buf, count);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300854
Ingo Molnar3593cab2006-02-07 06:49:14 -0200855 mutex_unlock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300856
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 parport_release(qcam->pdev);
858 return len;
859}
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300860
Hans Verkuilbec43662008-12-30 06:58:20 -0300861static int qcam_exclusive_open(struct file *file)
Hans Verkuil7d43cd52008-08-23 05:31:47 -0300862{
863 struct video_device *dev = video_devdata(file);
864 struct qcam_device *qcam = (struct qcam_device *)dev;
865
866 return test_and_set_bit(0, &qcam->in_use) ? -EBUSY : 0;
867}
868
Hans Verkuilbec43662008-12-30 06:58:20 -0300869static int qcam_exclusive_release(struct file *file)
Hans Verkuil7d43cd52008-08-23 05:31:47 -0300870{
871 struct video_device *dev = video_devdata(file);
872 struct qcam_device *qcam = (struct qcam_device *)dev;
873
874 clear_bit(0, &qcam->in_use);
875 return 0;
876}
877
Hans Verkuilbec43662008-12-30 06:58:20 -0300878static const struct v4l2_file_operations qcam_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 .owner = THIS_MODULE,
Hans Verkuil7d43cd52008-08-23 05:31:47 -0300880 .open = qcam_exclusive_open,
881 .release = qcam_exclusive_release,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 .ioctl = qcam_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 .read = qcam_read,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884};
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300885static struct video_device qcam_template = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886 .name = "Connectix Quickcam",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 .fops = &qcam_fops,
Hans Verkuilaa5e90a2008-08-23 06:23:55 -0300888 .release = video_device_release_empty,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889};
890
891#define MAX_CAMS 4
892static struct qcam_device *qcams[MAX_CAMS];
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300893static unsigned int num_cams;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700894
895static int init_bwqcam(struct parport *port)
896{
897 struct qcam_device *qcam;
898
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300899 if (num_cams == MAX_CAMS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
901 return -ENOSPC;
902 }
903
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300904 qcam = qcam_init(port);
905 if (qcam == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906 return -ENODEV;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300907
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 parport_claim_or_block(qcam->pdev);
909
910 qc_reset(qcam);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300911
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300912 if (qc_detect(qcam) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913 parport_release(qcam->pdev);
914 parport_unregister_device(qcam->pdev);
915 kfree(qcam);
916 return -ENODEV;
917 }
918 qc_calibrate(qcam);
919
920 parport_release(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300921
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 printk(KERN_INFO "Connectix Quickcam on %s\n", qcam->pport->name);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300923
Hans Verkuildc60de32008-09-03 17:11:58 -0300924 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 parport_unregister_device(qcam->pdev);
926 kfree(qcam);
927 return -ENODEV;
928 }
929
930 qcams[num_cams++] = qcam;
931
932 return 0;
933}
934
935static void close_bwqcam(struct qcam_device *qcam)
936{
937 video_unregister_device(&qcam->vdev);
938 parport_unregister_device(qcam->pdev);
939 kfree(qcam);
940}
941
942/* The parport parameter controls which parports will be scanned.
943 * Scanning all parports causes some printers to print a garbage page.
944 * -- March 14, 1999 Billy Donahue <billy@escape.com> */
945#ifdef MODULE
946static char *parport[MAX_CAMS] = { NULL, };
947module_param_array(parport, charp, NULL, 0);
948#endif
949
950static int accept_bwqcam(struct parport *port)
951{
952#ifdef MODULE
953 int n;
954
955 if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
956 /* user gave parport parameters */
Roel Kluinbb2b4542009-08-10 22:07:54 -0300957 for (n = 0; n < MAX_CAMS && parport[n]; n++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 char *ep;
959 unsigned long r;
960 r = simple_strtoul(parport[n], &ep, 0);
961 if (ep == parport[n]) {
962 printk(KERN_ERR
963 "bw-qcam: bad port specifier \"%s\"\n",
964 parport[n]);
965 continue;
966 }
967 if (r == port->number)
968 return 1;
969 }
970 return 0;
971 }
972#endif
973 return 1;
974}
975
976static void bwqcam_attach(struct parport *port)
977{
978 if (accept_bwqcam(port))
979 init_bwqcam(port);
980}
981
982static void bwqcam_detach(struct parport *port)
983{
984 int i;
985 for (i = 0; i < num_cams; i++) {
986 struct qcam_device *qcam = qcams[i];
987 if (qcam && qcam->pdev->port == port) {
988 qcams[i] = NULL;
989 close_bwqcam(qcam);
990 }
991 }
992}
993
994static struct parport_driver bwqcam_driver = {
995 .name = "bw-qcam",
996 .attach = bwqcam_attach,
997 .detach = bwqcam_detach,
998};
999
1000static void __exit exit_bw_qcams(void)
1001{
1002 parport_unregister_driver(&bwqcam_driver);
1003}
1004
1005static int __init init_bw_qcams(void)
1006{
1007#ifdef MODULE
1008 /* Do some sanity checks on the module parameters. */
1009 if (maxpoll > 5000) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001010 printk(KERN_INFO "Connectix Quickcam max-poll was above 5000. Using 5000.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 maxpoll = 5000;
1012 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001013
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 if (yieldlines < 1) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001015 printk(KERN_INFO "Connectix Quickcam yieldlines was less than 1. Using 1.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 yieldlines = 1;
1017 }
1018#endif
1019 return parport_register_driver(&bwqcam_driver);
1020}
1021
1022module_init(init_bw_qcams);
1023module_exit(exit_bw_qcams);
1024
1025MODULE_LICENSE("GPL");