blob: c1193506131c3a37e3c347a8703771a98f3938af [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070069#include <linux/kernel.h>
70#include <linux/slab.h>
71#include <linux/mm.h>
72#include <linux/parport.h>
73#include <linux/sched.h>
Hans Verkuil483d67f2010-05-10 03:51:02 -030074#include <linux/version.h>
75#include <linux/videodev2.h>
Ingo Molnar3593cab2006-02-07 06:49:14 -020076#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070077#include <asm/uaccess.h>
Hans Verkuil483d67f2010-05-10 03:51:02 -030078#include <media/v4l2-common.h>
79#include <media/v4l2-ioctl.h>
80#include <media/v4l2-device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
Hans Verkuil483d67f2010-05-10 03:51:02 -030082/* One from column A... */
83#define QC_NOTSET 0
84#define QC_UNIDIR 1
85#define QC_BIDIR 2
86#define QC_SERIAL 3
87
88/* ... and one from column B */
89#define QC_ANY 0x00
90#define QC_FORCE_UNIDIR 0x10
91#define QC_FORCE_BIDIR 0x20
92#define QC_FORCE_SERIAL 0x30
93/* in the port_mode member */
94
95#define QC_MODE_MASK 0x07
96#define QC_FORCE_MASK 0x70
97
98#define MAX_HEIGHT 243
99#define MAX_WIDTH 336
100
101/* Bit fields for status flags */
102#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
103
104struct qcam {
105 struct v4l2_device v4l2_dev;
106 struct video_device vdev;
107 struct pardevice *pdev;
108 struct parport *pport;
109 struct mutex lock;
110 int width, height;
111 int bpp;
112 int mode;
113 int contrast, brightness, whitebal;
114 int port_mode;
115 int transfer_scale;
116 int top, left;
117 int status;
118 unsigned int saved_bits;
119 unsigned long in_use;
120};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300122static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
123static unsigned int yieldlines = 4; /* Yield after this many during capture */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124static int video_nr = -1;
Brett T. Wardend685a482008-01-10 04:33:31 -0300125static unsigned int force_init; /* Whether to probe aggressively */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126
127module_param(maxpoll, int, 0);
128module_param(yieldlines, int, 0);
129module_param(video_nr, int, 0);
130
Brett T. Wardend685a482008-01-10 04:33:31 -0300131/* Set force_init=1 to avoid detection by polling status register and
132 * immediately attempt to initialize qcam */
133module_param(force_init, int, 0);
134
Hans Verkuil483d67f2010-05-10 03:51:02 -0300135#define MAX_CAMS 4
136static struct qcam *qcams[MAX_CAMS];
137static unsigned int num_cams;
138
139static inline int read_lpstatus(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700140{
141 return parport_read_status(q->pport);
142}
143
Hans Verkuil483d67f2010-05-10 03:51:02 -0300144static inline int read_lpdata(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145{
146 return parport_read_data(q->pport);
147}
148
Hans Verkuil483d67f2010-05-10 03:51:02 -0300149static inline void write_lpdata(struct qcam *q, int d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150{
151 parport_write_data(q->pport, d);
152}
153
Hans Verkuil483d67f2010-05-10 03:51:02 -0300154static void write_lpcontrol(struct qcam *q, int d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155{
Brett Warden7c596fa2007-10-02 17:37:21 -0300156 if (d & 0x20) {
Brett Warden9e19db52007-09-28 03:19:04 -0300157 /* Set bidirectional mode to reverse (data in) */
158 parport_data_reverse(q->pport);
159 } else {
160 /* Set bidirectional mode to forward (data out) */
161 parport_data_forward(q->pport);
162 }
163
164 /* Now issue the regular port command, but strip out the
165 * direction flag */
166 d &= ~0x20;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 parport_write_control(q->pport, d);
168}
169
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170
171/* qc_waithand busy-waits for a handshake signal from the QuickCam.
172 * Almost all communication with the camera requires handshaking. */
173
Hans Verkuil483d67f2010-05-10 03:51:02 -0300174static int qc_waithand(struct qcam *q, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175{
176 int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300177 int runs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300179 if (val) {
180 while (!((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300182 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 until the camera wakes up. However, we are
184 busy blocked until the camera responds, so
185 setting it lower is much better for interactive
186 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300187
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300188 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300190 if (runs > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 return -1;
192 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300193 } else {
194 while (((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300196 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 until the camera wakes up. However, we are
198 busy blocked until the camera responds, so
199 setting it lower is much better for interactive
200 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300201
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300202 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300204 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 return -1;
206 }
207 }
208
209 return status;
210}
211
212/* Waithand2 is used when the qcam is in bidirectional mode, and the
213 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
214 * (bit 3 of status register). It also returns the last value read,
215 * since this data is useful. */
216
Hans Verkuil483d67f2010-05-10 03:51:02 -0300217static unsigned int qc_waithand2(struct qcam *q, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218{
219 unsigned int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300220 int runs = 0;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300221
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300222 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223 status = read_lpdata(q);
224 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300225 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 until the camera wakes up. However, we are
227 busy blocked until the camera responds, so
228 setting it lower is much better for interactive
229 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300230
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300231 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300233 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700234 return 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300235 } while ((status & 1) != val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700236
237 return status;
238}
239
Hans Verkuil483d67f2010-05-10 03:51:02 -0300240/* qc_command is probably a bit of a misnomer -- it's used to send
241 * bytes *to* the camera. Generally, these bytes are either commands
242 * or arguments to commands, so the name fits, but it still bugs me a
243 * bit. See the documentation for a list of commands. */
244
245static int qc_command(struct qcam *q, int command)
246{
247 int n1, n2;
248 int cmd;
249
250 write_lpdata(q, command);
251 write_lpcontrol(q, 6);
252
253 n1 = qc_waithand(q, 1);
254
255 write_lpcontrol(q, 0xe);
256 n2 = qc_waithand(q, 0);
257
258 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
259 return cmd;
260}
261
262static int qc_readparam(struct qcam *q)
263{
264 int n1, n2;
265 int cmd;
266
267 write_lpcontrol(q, 6);
268 n1 = qc_waithand(q, 1);
269
270 write_lpcontrol(q, 0xe);
271 n2 = qc_waithand(q, 0);
272
273 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
274 return cmd;
275}
276
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277
278/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
279 the status register at 5-10 Hz. This is only used in the autoprobe
280 code. Be aware that this isn't the way Connectix detects the
281 camera (they send a reset and try to handshake), but this should be
282 almost completely safe, while their method screws up my printer if
283 I plug it in before the camera. */
284
Hans Verkuil483d67f2010-05-10 03:51:02 -0300285static int qc_detect(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286{
287 int reg, lastreg;
288 int count = 0;
289 int i;
290
Brett T. Wardend685a482008-01-10 04:33:31 -0300291 if (force_init)
292 return 1;
293
Linus Torvalds1da177e2005-04-16 15:20:36 -0700294 lastreg = reg = read_lpstatus(q) & 0xf0;
295
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300296 for (i = 0; i < 500; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 reg = read_lpstatus(q) & 0xf0;
298 if (reg != lastreg)
299 count++;
300 lastreg = reg;
301 mdelay(2);
302 }
303
304
305#if 0
306 /* Force camera detection during testing. Sometimes the camera
307 won't be flashing these bits. Possibly unloading the module
308 in the middle of a grab? Or some timeout condition?
309 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300310 printk(KERN_DEBUG "Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700311 return 1;
312#endif
313
314 /* Be (even more) liberal in what you accept... */
315
Brett Warden7c596fa2007-10-02 17:37:21 -0300316 if (count > 20 && count < 400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 return 1; /* found */
Brett Warden9e19db52007-09-28 03:19:04 -0300318 } else {
Brett Warden7c596fa2007-10-02 17:37:21 -0300319 printk(KERN_ERR "No Quickcam found on port %s\n",
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300320 q->pport->name);
Brett T. Wardend685a482008-01-10 04:33:31 -0300321 printk(KERN_DEBUG "Quickcam detection counter: %u\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700322 return 0; /* not found */
Brett Warden9e19db52007-09-28 03:19:04 -0300323 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324}
325
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326/* Decide which scan mode to use. There's no real requirement that
327 * the scanmode match the resolution in q->height and q-> width -- the
328 * camera takes the picture at the resolution specified in the
329 * "scanmode" and then returns the image at the resolution specified
330 * with the resolution commands. If the scan is bigger than the
331 * requested resolution, the upper-left hand corner of the scan is
332 * returned. If the scan is smaller, then the rest of the image
333 * returned contains garbage. */
334
Hans Verkuil483d67f2010-05-10 03:51:02 -0300335static int qc_setscanmode(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336{
337 int old_mode = q->mode;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300338
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300339 switch (q->transfer_scale) {
340 case 1:
341 q->mode = 0;
342 break;
343 case 2:
344 q->mode = 4;
345 break;
346 case 4:
347 q->mode = 8;
348 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 }
350
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300351 switch (q->bpp) {
352 case 4:
353 break;
354 case 6:
355 q->mode += 2;
356 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 }
358
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300359 switch (q->port_mode & QC_MODE_MASK) {
360 case QC_BIDIR:
361 q->mode += 1;
362 break;
363 case QC_NOTSET:
364 case QC_UNIDIR:
365 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300367
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 if (q->mode != old_mode)
369 q->status |= QC_PARAM_CHANGE;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300370
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 return 0;
372}
373
374
Hans Verkuil483d67f2010-05-10 03:51:02 -0300375/* Reset the QuickCam. This uses the same sequence the Windows
376 * QuickPic program uses. Someone with a bi-directional port should
377 * check that bi-directional mode is detected right, and then
378 * implement bi-directional mode in qc_readbyte(). */
379
380static void qc_reset(struct qcam *q)
381{
382 switch (q->port_mode & QC_FORCE_MASK) {
383 case QC_FORCE_UNIDIR:
384 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
385 break;
386
387 case QC_FORCE_BIDIR:
388 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
389 break;
390
391 case QC_ANY:
392 write_lpcontrol(q, 0x20);
393 write_lpdata(q, 0x75);
394
395 if (read_lpdata(q) != 0x75)
396 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
397 else
398 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
399 break;
400 }
401
402 write_lpcontrol(q, 0xb);
403 udelay(250);
404 write_lpcontrol(q, 0xe);
405 qc_setscanmode(q); /* in case port_mode changed */
406}
407
408
409
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410/* Reset the QuickCam and program for brightness, contrast,
411 * white-balance, and resolution. */
412
Hans Verkuil483d67f2010-05-10 03:51:02 -0300413static void qc_set(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414{
415 int val;
416 int val2;
417
418 qc_reset(q);
419
420 /* Set the brightness. Yes, this is repetitive, but it works.
421 * Shorter versions seem to fail subtly. Feel free to try :-). */
422 /* I think the problem was in qc_command, not here -- bls */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300423
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 qc_command(q, 0xb);
425 qc_command(q, q->brightness);
426
427 val = q->height / q->transfer_scale;
428 qc_command(q, 0x11);
429 qc_command(q, val);
430 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
431 /* The normal "transfers per line" calculation doesn't seem to work
432 as expected here (and yet it works fine in qc_scan). No idea
433 why this case is the odd man out. Fortunately, Laird's original
434 working version gives me a good way to guess at working values.
435 -- bls */
436 val = q->width;
437 val2 = q->transfer_scale * 4;
438 } else {
439 val = q->width * q->bpp;
440 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300441 q->transfer_scale;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700442 }
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300443 val = DIV_ROUND_UP(val, val2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 qc_command(q, 0x13);
445 qc_command(q, val);
446
447 /* Setting top and left -- bls */
448 qc_command(q, 0xd);
449 qc_command(q, q->top);
450 qc_command(q, 0xf);
451 qc_command(q, q->left / 2);
452
453 qc_command(q, 0x19);
454 qc_command(q, q->contrast);
455 qc_command(q, 0x1f);
456 qc_command(q, q->whitebal);
457
458 /* Clear flag that we must update the grabbing parameters on the camera
459 before we grab the next frame */
460 q->status &= (~QC_PARAM_CHANGE);
461}
462
463/* Qc_readbytes reads some bytes from the QC and puts them in
464 the supplied buffer. It returns the number of bytes read,
465 or -1 on error. */
466
Hans Verkuil483d67f2010-05-10 03:51:02 -0300467static inline int qc_readbytes(struct qcam *q, char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700468{
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300469 int ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700470 unsigned int hi, lo;
471 unsigned int hi2, lo2;
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300472 static int state;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300474 if (buffer == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700475 state = 0;
476 return 0;
477 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300478
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300479 switch (q->port_mode & QC_MODE_MASK) {
480 case QC_BIDIR: /* Bi-directional Port */
481 write_lpcontrol(q, 0x26);
482 lo = (qc_waithand2(q, 1) >> 1);
483 hi = (read_lpstatus(q) >> 3) & 0x1f;
484 write_lpcontrol(q, 0x2e);
485 lo2 = (qc_waithand2(q, 0) >> 1);
486 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
487 switch (q->bpp) {
488 case 4:
489 buffer[0] = lo & 0xf;
490 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
491 buffer[2] = (hi & 0x1e) >> 1;
492 buffer[3] = lo2 & 0xf;
493 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
494 buffer[5] = (hi2 & 0x1e) >> 1;
495 ret = 6;
496 break;
497 case 6:
498 buffer[0] = lo & 0x3f;
499 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
500 buffer[2] = lo2 & 0x3f;
501 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
502 ret = 4;
503 break;
504 }
505 break;
506
507 case QC_UNIDIR: /* Unidirectional Port */
508 write_lpcontrol(q, 6);
509 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
510 write_lpcontrol(q, 0xe);
511 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
512
513 switch (q->bpp) {
514 case 4:
515 buffer[0] = lo;
516 buffer[1] = hi;
517 ret = 2;
518 break;
519 case 6:
520 switch (state) {
521 case 0:
522 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
523 q->saved_bits = (hi & 3) << 4;
524 state = 1;
525 ret = 1;
526 break;
527 case 1:
528 buffer[0] = lo | q->saved_bits;
529 q->saved_bits = hi << 2;
530 state = 2;
531 ret = 1;
532 break;
533 case 2:
534 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
535 buffer[1] = ((lo & 3) << 4) | hi;
536 state = 0;
537 ret = 2;
538 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 }
540 break;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300541 }
542 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 }
544 return ret;
545}
546
547/* requests a scan from the camera. It sends the correct instructions
548 * to the camera and then reads back the correct number of bytes. In
549 * previous versions of this routine the return structure contained
550 * the raw output from the camera, and there was a 'qc_convertscan'
551 * function that converted that to a useful format. In version 0.3 I
552 * rolled qc_convertscan into qc_scan and now I only return the
553 * converted scan. The format is just an one-dimensional array of
554 * characters, one for each pixel, with 0=black up to n=white, where
555 * n=2^(bit depth)-1. Ask me for more details if you don't understand
556 * this. */
557
Hans Verkuil483d67f2010-05-10 03:51:02 -0300558static long qc_capture(struct qcam *q, char __user *buf, unsigned long len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559{
560 int i, j, k, yield;
561 int bytes;
562 int linestotrans, transperline;
563 int divisor;
564 int pixels_per_line;
565 int pixels_read = 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300566 int got = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 char buffer[6];
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300568 int shift = 8 - q->bpp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700569 char invert;
570
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300571 if (q->mode == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 return -ENXIO;
573
574 qc_command(q, 0x7);
575 qc_command(q, q->mode);
576
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300577 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 write_lpcontrol(q, 0x2e); /* turn port around */
579 write_lpcontrol(q, 0x26);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300580 qc_waithand(q, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 write_lpcontrol(q, 0x2e);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300582 qc_waithand(q, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300584
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 /* strange -- should be 15:63 below, but 4bpp is odd */
586 invert = (q->bpp == 4) ? 16 : 63;
587
588 linestotrans = q->height / q->transfer_scale;
589 pixels_per_line = q->width / q->transfer_scale;
590 transperline = q->width * q->bpp;
591 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300592 q->transfer_scale;
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300593 transperline = DIV_ROUND_UP(transperline, divisor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300595 for (i = 0, yield = yieldlines; i < linestotrans; i++) {
596 for (pixels_read = j = 0; j < transperline; j++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 bytes = qc_readbytes(q, buffer);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300598 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 int o;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300600 if (buffer[k] == 0 && invert == 16) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700601 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
602 must be 0-15 -- bls */
603 buffer[k] = 16;
604 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300605 o = i * pixels_per_line + pixels_read + k;
606 if (o < len) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 got++;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300608 put_user((invert - buffer[k]) << shift, buf + o);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 }
610 }
611 pixels_read += bytes;
612 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300613 qc_readbytes(q, NULL); /* reset state machine */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300614
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 /* Grabbing an entire frame from the quickcam is a lengthy
616 process. We don't (usually) want to busy-block the
617 processor for the entire frame. yieldlines is a module
618 parameter. If we yield every line, the minimum frame
619 time will be 240 / 200 = 1.2 seconds. The compile-time
620 default is to yield every 4 lines. */
621 if (i >= yield) {
622 msleep_interruptible(5);
623 yield = i + yieldlines;
624 }
625 }
626
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300627 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 write_lpcontrol(q, 2);
629 write_lpcontrol(q, 6);
630 udelay(3);
631 write_lpcontrol(q, 0xe);
632 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300633 if (got < len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634 return got;
635 return len;
636}
637
638/*
639 * Video4linux interfacing
640 */
641
Hans Verkuil483d67f2010-05-10 03:51:02 -0300642static int qcam_querycap(struct file *file, void *priv,
643 struct v4l2_capability *vcap)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300645 struct qcam *qcam = video_drvdata(file);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300646
Hans Verkuil483d67f2010-05-10 03:51:02 -0300647 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
648 strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card));
649 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
650 vcap->version = KERNEL_VERSION(0, 0, 2);
651 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 return 0;
653}
654
Hans Verkuil483d67f2010-05-10 03:51:02 -0300655static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300657 if (vin->index > 0)
658 return -EINVAL;
659 strlcpy(vin->name, "Camera", sizeof(vin->name));
660 vin->type = V4L2_INPUT_TYPE_CAMERA;
661 vin->audioset = 0;
662 vin->tuner = 0;
663 vin->std = 0;
664 vin->status = 0;
665 return 0;
666}
667
668static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
669{
670 *inp = 0;
671 return 0;
672}
673
674static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
675{
676 return (inp > 0) ? -EINVAL : 0;
677}
678
679static int qcam_queryctrl(struct file *file, void *priv,
680 struct v4l2_queryctrl *qc)
681{
682 switch (qc->id) {
683 case V4L2_CID_BRIGHTNESS:
684 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180);
685 case V4L2_CID_CONTRAST:
686 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
687 case V4L2_CID_GAMMA:
688 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105);
689 }
690 return -EINVAL;
691}
692
693static int qcam_g_ctrl(struct file *file, void *priv,
694 struct v4l2_control *ctrl)
695{
696 struct qcam *qcam = video_drvdata(file);
697 int ret = 0;
698
699 switch (ctrl->id) {
700 case V4L2_CID_BRIGHTNESS:
701 ctrl->value = qcam->brightness;
702 break;
703 case V4L2_CID_CONTRAST:
704 ctrl->value = qcam->contrast;
705 break;
706 case V4L2_CID_GAMMA:
707 ctrl->value = qcam->whitebal;
708 break;
709 default:
710 ret = -EINVAL;
711 break;
712 }
713 return ret;
714}
715
716static int qcam_s_ctrl(struct file *file, void *priv,
717 struct v4l2_control *ctrl)
718{
719 struct qcam *qcam = video_drvdata(file);
720 int ret = 0;
721
722 mutex_lock(&qcam->lock);
723 switch (ctrl->id) {
724 case V4L2_CID_BRIGHTNESS:
725 qcam->brightness = ctrl->value;
726 break;
727 case V4L2_CID_CONTRAST:
728 qcam->contrast = ctrl->value;
729 break;
730 case V4L2_CID_GAMMA:
731 qcam->whitebal = ctrl->value;
732 break;
733 default:
734 ret = -EINVAL;
735 break;
736 }
737 if (ret == 0) {
738 qc_setscanmode(qcam);
739 qcam->status |= QC_PARAM_CHANGE;
740 }
741 mutex_unlock(&qcam->lock);
742 return ret;
743}
744
745static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
746{
747 struct qcam *qcam = video_drvdata(file);
748 struct v4l2_pix_format *pix = &fmt->fmt.pix;
749
750 pix->width = qcam->width / qcam->transfer_scale;
751 pix->height = qcam->height / qcam->transfer_scale;
752 pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6;
753 pix->field = V4L2_FIELD_NONE;
754 pix->bytesperline = qcam->width;
755 pix->sizeimage = qcam->width * qcam->height;
756 /* Just a guess */
757 pix->colorspace = V4L2_COLORSPACE_SRGB;
758 return 0;
759}
760
761static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
762{
763 struct v4l2_pix_format *pix = &fmt->fmt.pix;
764
765 if (pix->height <= 60 || pix->width <= 80) {
766 pix->height = 60;
767 pix->width = 80;
768 } else if (pix->height <= 120 || pix->width <= 160) {
769 pix->height = 120;
770 pix->width = 160;
771 } else {
772 pix->height = 240;
773 pix->width = 320;
774 }
775 if (pix->pixelformat != V4L2_PIX_FMT_Y4 &&
776 pix->pixelformat != V4L2_PIX_FMT_Y6)
777 pix->pixelformat = V4L2_PIX_FMT_Y4;
778 pix->field = V4L2_FIELD_NONE;
779 pix->bytesperline = pix->width;
780 pix->sizeimage = pix->width * pix->height;
781 /* Just a guess */
782 pix->colorspace = V4L2_COLORSPACE_SRGB;
783 return 0;
784}
785
786static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
787{
788 struct qcam *qcam = video_drvdata(file);
789 struct v4l2_pix_format *pix = &fmt->fmt.pix;
790 int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
791
792 if (ret)
793 return ret;
794 qcam->width = 320;
795 qcam->height = 240;
796 if (pix->height == 60)
797 qcam->transfer_scale = 4;
798 else if (pix->height == 120)
799 qcam->transfer_scale = 2;
800 else
801 qcam->transfer_scale = 1;
802 if (pix->pixelformat == V4L2_PIX_FMT_Y6)
803 qcam->bpp = 6;
804 else
805 qcam->bpp = 4;
806
807 mutex_lock(&qcam->lock);
808 qc_setscanmode(qcam);
809 /* We must update the camera before we grab. We could
810 just have changed the grab size */
811 qcam->status |= QC_PARAM_CHANGE;
812 mutex_unlock(&qcam->lock);
813 return 0;
814}
815
816static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
817{
818 static struct v4l2_fmtdesc formats[] = {
819 { 0, 0, 0,
820 "4-Bit Monochrome", V4L2_PIX_FMT_Y4,
821 { 0, 0, 0, 0 }
822 },
823 { 0, 0, 0,
824 "6-Bit Monochrome", V4L2_PIX_FMT_Y6,
825 { 0, 0, 0, 0 }
826 },
827 };
828 enum v4l2_buf_type type = fmt->type;
829
830 if (fmt->index > 1)
831 return -EINVAL;
832
833 *fmt = formats[fmt->index];
834 fmt->type = type;
835 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836}
837
838static ssize_t qcam_read(struct file *file, char __user *buf,
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300839 size_t count, loff_t *ppos)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300841 struct qcam *qcam = video_drvdata(file);
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 const struct v4l2_file_operations qcam_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 .owner = THIS_MODULE,
Hans Verkuil61df3c92010-11-14 10:09:38 -0300863 .unlocked_ioctl = video_ioctl2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 .read = qcam_read,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865};
Hans Verkuil483d67f2010-05-10 03:51:02 -0300866
867static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
868 .vidioc_querycap = qcam_querycap,
869 .vidioc_g_input = qcam_g_input,
870 .vidioc_s_input = qcam_s_input,
871 .vidioc_enum_input = qcam_enum_input,
872 .vidioc_queryctrl = qcam_queryctrl,
873 .vidioc_g_ctrl = qcam_g_ctrl,
874 .vidioc_s_ctrl = qcam_s_ctrl,
875 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
876 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
877 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
878 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879};
880
Hans Verkuil483d67f2010-05-10 03:51:02 -0300881/* Initialize the QuickCam driver control structure. This is where
882 * defaults are set for people who don't have a config file.*/
883
884static struct qcam *qcam_init(struct parport *port)
885{
886 struct qcam *qcam;
887 struct v4l2_device *v4l2_dev;
888
889 qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL);
890 if (qcam == NULL)
891 return NULL;
892
893 v4l2_dev = &qcam->v4l2_dev;
894 strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name));
895
896 if (v4l2_device_register(NULL, v4l2_dev) < 0) {
897 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
898 return NULL;
899 }
900
901 qcam->pport = port;
902 qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
903 NULL, 0, NULL);
904 if (qcam->pdev == NULL) {
905 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
906 kfree(qcam);
907 return NULL;
908 }
909
910 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
911 qcam->vdev.v4l2_dev = v4l2_dev;
912 qcam->vdev.fops = &qcam_fops;
913 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
914 qcam->vdev.release = video_device_release_empty;
915 video_set_drvdata(&qcam->vdev, qcam);
916
917 mutex_init(&qcam->lock);
918
919 qcam->port_mode = (QC_ANY | QC_NOTSET);
920 qcam->width = 320;
921 qcam->height = 240;
922 qcam->bpp = 4;
923 qcam->transfer_scale = 2;
924 qcam->contrast = 192;
925 qcam->brightness = 180;
926 qcam->whitebal = 105;
927 qcam->top = 1;
928 qcam->left = 14;
929 qcam->mode = -1;
930 qcam->status = QC_PARAM_CHANGE;
931 return qcam;
932}
933
934static int qc_calibrate(struct qcam *q)
935{
936 /*
937 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
938 * The white balance is an individual value for each
939 * quickcam.
940 */
941
942 int value;
943 int count = 0;
944
945 qc_command(q, 27); /* AutoAdjustOffset */
946 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
947
948 /* GetOffset (33) will read 255 until autocalibration */
949 /* is finished. After that, a value of 1-254 will be */
950 /* returned. */
951
952 do {
953 qc_command(q, 33);
954 value = qc_readparam(q);
955 mdelay(1);
956 schedule();
957 count++;
958 } while (value == 0xff && count < 2048);
959
960 q->whitebal = value;
961 return value;
962}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963
964static int init_bwqcam(struct parport *port)
965{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300966 struct qcam *qcam;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700967
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300968 if (num_cams == MAX_CAMS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
970 return -ENOSPC;
971 }
972
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300973 qcam = qcam_init(port);
974 if (qcam == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 return -ENODEV;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300976
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 parport_claim_or_block(qcam->pdev);
978
979 qc_reset(qcam);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300980
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300981 if (qc_detect(qcam) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982 parport_release(qcam->pdev);
983 parport_unregister_device(qcam->pdev);
984 kfree(qcam);
985 return -ENODEV;
986 }
987 qc_calibrate(qcam);
988
989 parport_release(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300990
Hans Verkuil483d67f2010-05-10 03:51:02 -0300991 v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300992
Hans Verkuildc60de32008-09-03 17:11:58 -0300993 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994 parport_unregister_device(qcam->pdev);
995 kfree(qcam);
996 return -ENODEV;
997 }
998
999 qcams[num_cams++] = qcam;
1000
1001 return 0;
1002}
1003
Hans Verkuil483d67f2010-05-10 03:51:02 -03001004static void close_bwqcam(struct qcam *qcam)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005{
1006 video_unregister_device(&qcam->vdev);
1007 parport_unregister_device(qcam->pdev);
1008 kfree(qcam);
1009}
1010
1011/* The parport parameter controls which parports will be scanned.
1012 * Scanning all parports causes some printers to print a garbage page.
1013 * -- March 14, 1999 Billy Donahue <billy@escape.com> */
1014#ifdef MODULE
1015static char *parport[MAX_CAMS] = { NULL, };
1016module_param_array(parport, charp, NULL, 0);
1017#endif
1018
1019static int accept_bwqcam(struct parport *port)
1020{
1021#ifdef MODULE
1022 int n;
1023
1024 if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
1025 /* user gave parport parameters */
Roel Kluinbb2b4542009-08-10 22:07:54 -03001026 for (n = 0; n < MAX_CAMS && parport[n]; n++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 char *ep;
1028 unsigned long r;
1029 r = simple_strtoul(parport[n], &ep, 0);
1030 if (ep == parport[n]) {
1031 printk(KERN_ERR
1032 "bw-qcam: bad port specifier \"%s\"\n",
1033 parport[n]);
1034 continue;
1035 }
1036 if (r == port->number)
1037 return 1;
1038 }
1039 return 0;
1040 }
1041#endif
1042 return 1;
1043}
1044
1045static void bwqcam_attach(struct parport *port)
1046{
1047 if (accept_bwqcam(port))
1048 init_bwqcam(port);
1049}
1050
1051static void bwqcam_detach(struct parport *port)
1052{
1053 int i;
1054 for (i = 0; i < num_cams; i++) {
Hans Verkuil483d67f2010-05-10 03:51:02 -03001055 struct qcam *qcam = qcams[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 if (qcam && qcam->pdev->port == port) {
1057 qcams[i] = NULL;
1058 close_bwqcam(qcam);
1059 }
1060 }
1061}
1062
1063static struct parport_driver bwqcam_driver = {
1064 .name = "bw-qcam",
1065 .attach = bwqcam_attach,
1066 .detach = bwqcam_detach,
1067};
1068
1069static void __exit exit_bw_qcams(void)
1070{
1071 parport_unregister_driver(&bwqcam_driver);
1072}
1073
1074static int __init init_bw_qcams(void)
1075{
1076#ifdef MODULE
1077 /* Do some sanity checks on the module parameters. */
1078 if (maxpoll > 5000) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001079 printk(KERN_INFO "Connectix Quickcam max-poll was above 5000. Using 5000.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001080 maxpoll = 5000;
1081 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001082
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 if (yieldlines < 1) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001084 printk(KERN_INFO "Connectix Quickcam yieldlines was less than 1. Using 1.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085 yieldlines = 1;
1086 }
1087#endif
1088 return parport_register_driver(&bwqcam_driver);
1089}
1090
1091module_init(init_bw_qcams);
1092module_exit(exit_bw_qcams);
1093
1094MODULE_LICENSE("GPL");