blob: f09df9dffaae50d3db2ac887757e53d4fb2ff61d [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/videodev2.h>
Ingo Molnar3593cab2006-02-07 06:49:14 -020075#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070076#include <asm/uaccess.h>
Hans Verkuil483d67f2010-05-10 03:51:02 -030077#include <media/v4l2-common.h>
78#include <media/v4l2-ioctl.h>
79#include <media/v4l2-device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070080
Hans Verkuil483d67f2010-05-10 03:51:02 -030081/* One from column A... */
82#define QC_NOTSET 0
83#define QC_UNIDIR 1
84#define QC_BIDIR 2
85#define QC_SERIAL 3
86
87/* ... and one from column B */
88#define QC_ANY 0x00
89#define QC_FORCE_UNIDIR 0x10
90#define QC_FORCE_BIDIR 0x20
91#define QC_FORCE_SERIAL 0x30
92/* in the port_mode member */
93
94#define QC_MODE_MASK 0x07
95#define QC_FORCE_MASK 0x70
96
97#define MAX_HEIGHT 243
98#define MAX_WIDTH 336
99
100/* Bit fields for status flags */
101#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
102
103struct qcam {
104 struct v4l2_device v4l2_dev;
105 struct video_device vdev;
106 struct pardevice *pdev;
107 struct parport *pport;
108 struct mutex lock;
109 int width, height;
110 int bpp;
111 int mode;
112 int contrast, brightness, whitebal;
113 int port_mode;
114 int transfer_scale;
115 int top, left;
116 int status;
117 unsigned int saved_bits;
118 unsigned long in_use;
119};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300121static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
122static unsigned int yieldlines = 4; /* Yield after this many during capture */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123static int video_nr = -1;
Brett T. Wardend685a482008-01-10 04:33:31 -0300124static unsigned int force_init; /* Whether to probe aggressively */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125
126module_param(maxpoll, int, 0);
127module_param(yieldlines, int, 0);
128module_param(video_nr, int, 0);
129
Brett T. Wardend685a482008-01-10 04:33:31 -0300130/* Set force_init=1 to avoid detection by polling status register and
131 * immediately attempt to initialize qcam */
132module_param(force_init, int, 0);
133
Hans Verkuil483d67f2010-05-10 03:51:02 -0300134#define MAX_CAMS 4
135static struct qcam *qcams[MAX_CAMS];
136static unsigned int num_cams;
137
138static inline int read_lpstatus(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139{
140 return parport_read_status(q->pport);
141}
142
Hans Verkuil483d67f2010-05-10 03:51:02 -0300143static inline int read_lpdata(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144{
145 return parport_read_data(q->pport);
146}
147
Hans Verkuil483d67f2010-05-10 03:51:02 -0300148static inline void write_lpdata(struct qcam *q, int d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149{
150 parport_write_data(q->pport, d);
151}
152
Hans Verkuil483d67f2010-05-10 03:51:02 -0300153static void write_lpcontrol(struct qcam *q, int d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154{
Brett Warden7c596fa2007-10-02 17:37:21 -0300155 if (d & 0x20) {
Brett Warden9e19db52007-09-28 03:19:04 -0300156 /* Set bidirectional mode to reverse (data in) */
157 parport_data_reverse(q->pport);
158 } else {
159 /* Set bidirectional mode to forward (data out) */
160 parport_data_forward(q->pport);
161 }
162
163 /* Now issue the regular port command, but strip out the
164 * direction flag */
165 d &= ~0x20;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 parport_write_control(q->pport, d);
167}
168
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169
170/* qc_waithand busy-waits for a handshake signal from the QuickCam.
171 * Almost all communication with the camera requires handshaking. */
172
Hans Verkuil483d67f2010-05-10 03:51:02 -0300173static int qc_waithand(struct qcam *q, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700174{
175 int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300176 int runs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300178 if (val) {
179 while (!((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700180 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300181 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182 until the camera wakes up. However, we are
183 busy blocked until the camera responds, so
184 setting it lower is much better for interactive
185 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300186
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300187 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300189 if (runs > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 return -1;
191 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300192 } else {
193 while (((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300195 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196 until the camera wakes up. However, we are
197 busy blocked until the camera responds, so
198 setting it lower is much better for interactive
199 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300200
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300201 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300203 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 return -1;
205 }
206 }
207
208 return status;
209}
210
211/* Waithand2 is used when the qcam is in bidirectional mode, and the
212 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
213 * (bit 3 of status register). It also returns the last value read,
214 * since this data is useful. */
215
Hans Verkuil483d67f2010-05-10 03:51:02 -0300216static unsigned int qc_waithand2(struct qcam *q, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217{
218 unsigned int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300219 int runs = 0;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300220
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300221 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 status = read_lpdata(q);
223 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300224 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225 until the camera wakes up. However, we are
226 busy blocked until the camera responds, so
227 setting it lower is much better for interactive
228 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300229
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300230 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700231 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300232 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700233 return 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300234 } while ((status & 1) != val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235
236 return status;
237}
238
Hans Verkuil483d67f2010-05-10 03:51:02 -0300239/* qc_command is probably a bit of a misnomer -- it's used to send
240 * bytes *to* the camera. Generally, these bytes are either commands
241 * or arguments to commands, so the name fits, but it still bugs me a
242 * bit. See the documentation for a list of commands. */
243
244static int qc_command(struct qcam *q, int command)
245{
246 int n1, n2;
247 int cmd;
248
249 write_lpdata(q, command);
250 write_lpcontrol(q, 6);
251
252 n1 = qc_waithand(q, 1);
253
254 write_lpcontrol(q, 0xe);
255 n2 = qc_waithand(q, 0);
256
257 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
258 return cmd;
259}
260
261static int qc_readparam(struct qcam *q)
262{
263 int n1, n2;
264 int cmd;
265
266 write_lpcontrol(q, 6);
267 n1 = qc_waithand(q, 1);
268
269 write_lpcontrol(q, 0xe);
270 n2 = qc_waithand(q, 0);
271
272 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
273 return cmd;
274}
275
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276
277/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
278 the status register at 5-10 Hz. This is only used in the autoprobe
279 code. Be aware that this isn't the way Connectix detects the
280 camera (they send a reset and try to handshake), but this should be
281 almost completely safe, while their method screws up my printer if
282 I plug it in before the camera. */
283
Hans Verkuil483d67f2010-05-10 03:51:02 -0300284static int qc_detect(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700285{
286 int reg, lastreg;
287 int count = 0;
288 int i;
289
Brett T. Wardend685a482008-01-10 04:33:31 -0300290 if (force_init)
291 return 1;
292
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 lastreg = reg = read_lpstatus(q) & 0xf0;
294
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300295 for (i = 0; i < 500; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 reg = read_lpstatus(q) & 0xf0;
297 if (reg != lastreg)
298 count++;
299 lastreg = reg;
300 mdelay(2);
301 }
302
303
304#if 0
305 /* Force camera detection during testing. Sometimes the camera
306 won't be flashing these bits. Possibly unloading the module
307 in the middle of a grab? Or some timeout condition?
308 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300309 printk(KERN_DEBUG "Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310 return 1;
311#endif
312
313 /* Be (even more) liberal in what you accept... */
314
Brett Warden7c596fa2007-10-02 17:37:21 -0300315 if (count > 20 && count < 400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700316 return 1; /* found */
Brett Warden9e19db52007-09-28 03:19:04 -0300317 } else {
Brett Warden7c596fa2007-10-02 17:37:21 -0300318 printk(KERN_ERR "No Quickcam found on port %s\n",
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300319 q->pport->name);
Brett T. Wardend685a482008-01-10 04:33:31 -0300320 printk(KERN_DEBUG "Quickcam detection counter: %u\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321 return 0; /* not found */
Brett Warden9e19db52007-09-28 03:19:04 -0300322 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323}
324
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325/* Decide which scan mode to use. There's no real requirement that
326 * the scanmode match the resolution in q->height and q-> width -- the
327 * camera takes the picture at the resolution specified in the
328 * "scanmode" and then returns the image at the resolution specified
329 * with the resolution commands. If the scan is bigger than the
330 * requested resolution, the upper-left hand corner of the scan is
331 * returned. If the scan is smaller, then the rest of the image
332 * returned contains garbage. */
333
Hans Verkuil483d67f2010-05-10 03:51:02 -0300334static int qc_setscanmode(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335{
336 int old_mode = q->mode;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300337
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300338 switch (q->transfer_scale) {
339 case 1:
340 q->mode = 0;
341 break;
342 case 2:
343 q->mode = 4;
344 break;
345 case 4:
346 q->mode = 8;
347 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 }
349
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300350 switch (q->bpp) {
351 case 4:
352 break;
353 case 6:
354 q->mode += 2;
355 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 }
357
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300358 switch (q->port_mode & QC_MODE_MASK) {
359 case QC_BIDIR:
360 q->mode += 1;
361 break;
362 case QC_NOTSET:
363 case QC_UNIDIR:
364 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300366
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 if (q->mode != old_mode)
368 q->status |= QC_PARAM_CHANGE;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300369
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 return 0;
371}
372
373
Hans Verkuil483d67f2010-05-10 03:51:02 -0300374/* Reset the QuickCam. This uses the same sequence the Windows
375 * QuickPic program uses. Someone with a bi-directional port should
376 * check that bi-directional mode is detected right, and then
377 * implement bi-directional mode in qc_readbyte(). */
378
379static void qc_reset(struct qcam *q)
380{
381 switch (q->port_mode & QC_FORCE_MASK) {
382 case QC_FORCE_UNIDIR:
383 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
384 break;
385
386 case QC_FORCE_BIDIR:
387 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
388 break;
389
390 case QC_ANY:
391 write_lpcontrol(q, 0x20);
392 write_lpdata(q, 0x75);
393
394 if (read_lpdata(q) != 0x75)
395 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
396 else
397 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
398 break;
399 }
400
401 write_lpcontrol(q, 0xb);
402 udelay(250);
403 write_lpcontrol(q, 0xe);
404 qc_setscanmode(q); /* in case port_mode changed */
405}
406
407
408
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409/* Reset the QuickCam and program for brightness, contrast,
410 * white-balance, and resolution. */
411
Hans Verkuil483d67f2010-05-10 03:51:02 -0300412static void qc_set(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413{
414 int val;
415 int val2;
416
417 qc_reset(q);
418
419 /* Set the brightness. Yes, this is repetitive, but it works.
420 * Shorter versions seem to fail subtly. Feel free to try :-). */
421 /* I think the problem was in qc_command, not here -- bls */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300422
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 qc_command(q, 0xb);
424 qc_command(q, q->brightness);
425
426 val = q->height / q->transfer_scale;
427 qc_command(q, 0x11);
428 qc_command(q, val);
429 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
430 /* The normal "transfers per line" calculation doesn't seem to work
431 as expected here (and yet it works fine in qc_scan). No idea
432 why this case is the odd man out. Fortunately, Laird's original
433 working version gives me a good way to guess at working values.
434 -- bls */
435 val = q->width;
436 val2 = q->transfer_scale * 4;
437 } else {
438 val = q->width * q->bpp;
439 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300440 q->transfer_scale;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 }
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300442 val = DIV_ROUND_UP(val, val2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 qc_command(q, 0x13);
444 qc_command(q, val);
445
446 /* Setting top and left -- bls */
447 qc_command(q, 0xd);
448 qc_command(q, q->top);
449 qc_command(q, 0xf);
450 qc_command(q, q->left / 2);
451
452 qc_command(q, 0x19);
453 qc_command(q, q->contrast);
454 qc_command(q, 0x1f);
455 qc_command(q, q->whitebal);
456
457 /* Clear flag that we must update the grabbing parameters on the camera
458 before we grab the next frame */
459 q->status &= (~QC_PARAM_CHANGE);
460}
461
462/* Qc_readbytes reads some bytes from the QC and puts them in
463 the supplied buffer. It returns the number of bytes read,
464 or -1 on error. */
465
Hans Verkuil483d67f2010-05-10 03:51:02 -0300466static inline int qc_readbytes(struct qcam *q, char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467{
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300468 int ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 unsigned int hi, lo;
470 unsigned int hi2, lo2;
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300471 static int state;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300473 if (buffer == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474 state = 0;
475 return 0;
476 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300477
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300478 switch (q->port_mode & QC_MODE_MASK) {
479 case QC_BIDIR: /* Bi-directional Port */
480 write_lpcontrol(q, 0x26);
481 lo = (qc_waithand2(q, 1) >> 1);
482 hi = (read_lpstatus(q) >> 3) & 0x1f;
483 write_lpcontrol(q, 0x2e);
484 lo2 = (qc_waithand2(q, 0) >> 1);
485 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
486 switch (q->bpp) {
487 case 4:
488 buffer[0] = lo & 0xf;
489 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
490 buffer[2] = (hi & 0x1e) >> 1;
491 buffer[3] = lo2 & 0xf;
492 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
493 buffer[5] = (hi2 & 0x1e) >> 1;
494 ret = 6;
495 break;
496 case 6:
497 buffer[0] = lo & 0x3f;
498 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
499 buffer[2] = lo2 & 0x3f;
500 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
501 ret = 4;
502 break;
503 }
504 break;
505
506 case QC_UNIDIR: /* Unidirectional Port */
507 write_lpcontrol(q, 6);
508 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
509 write_lpcontrol(q, 0xe);
510 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
511
512 switch (q->bpp) {
513 case 4:
514 buffer[0] = lo;
515 buffer[1] = hi;
516 ret = 2;
517 break;
518 case 6:
519 switch (state) {
520 case 0:
521 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
522 q->saved_bits = (hi & 3) << 4;
523 state = 1;
524 ret = 1;
525 break;
526 case 1:
527 buffer[0] = lo | q->saved_bits;
528 q->saved_bits = hi << 2;
529 state = 2;
530 ret = 1;
531 break;
532 case 2:
533 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
534 buffer[1] = ((lo & 3) << 4) | hi;
535 state = 0;
536 ret = 2;
537 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700538 }
539 break;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300540 }
541 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 }
543 return ret;
544}
545
546/* requests a scan from the camera. It sends the correct instructions
547 * to the camera and then reads back the correct number of bytes. In
548 * previous versions of this routine the return structure contained
549 * the raw output from the camera, and there was a 'qc_convertscan'
550 * function that converted that to a useful format. In version 0.3 I
551 * rolled qc_convertscan into qc_scan and now I only return the
552 * converted scan. The format is just an one-dimensional array of
553 * characters, one for each pixel, with 0=black up to n=white, where
554 * n=2^(bit depth)-1. Ask me for more details if you don't understand
555 * this. */
556
Hans Verkuil483d67f2010-05-10 03:51:02 -0300557static long qc_capture(struct qcam *q, char __user *buf, unsigned long len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558{
559 int i, j, k, yield;
560 int bytes;
561 int linestotrans, transperline;
562 int divisor;
563 int pixels_per_line;
564 int pixels_read = 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300565 int got = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 char buffer[6];
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300567 int shift = 8 - q->bpp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 char invert;
569
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300570 if (q->mode == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571 return -ENXIO;
572
573 qc_command(q, 0x7);
574 qc_command(q, q->mode);
575
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300576 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577 write_lpcontrol(q, 0x2e); /* turn port around */
578 write_lpcontrol(q, 0x26);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300579 qc_waithand(q, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580 write_lpcontrol(q, 0x2e);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300581 qc_waithand(q, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300583
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 /* strange -- should be 15:63 below, but 4bpp is odd */
585 invert = (q->bpp == 4) ? 16 : 63;
586
587 linestotrans = q->height / q->transfer_scale;
588 pixels_per_line = q->width / q->transfer_scale;
589 transperline = q->width * q->bpp;
590 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300591 q->transfer_scale;
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300592 transperline = DIV_ROUND_UP(transperline, divisor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300594 for (i = 0, yield = yieldlines; i < linestotrans; i++) {
595 for (pixels_read = j = 0; j < transperline; j++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596 bytes = qc_readbytes(q, buffer);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300597 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 int o;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300599 if (buffer[k] == 0 && invert == 16) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
601 must be 0-15 -- bls */
602 buffer[k] = 16;
603 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300604 o = i * pixels_per_line + pixels_read + k;
605 if (o < len) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700606 got++;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300607 put_user((invert - buffer[k]) << shift, buf + o);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 }
609 }
610 pixels_read += bytes;
611 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300612 qc_readbytes(q, NULL); /* reset state machine */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300613
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 /* Grabbing an entire frame from the quickcam is a lengthy
615 process. We don't (usually) want to busy-block the
616 processor for the entire frame. yieldlines is a module
617 parameter. If we yield every line, the minimum frame
618 time will be 240 / 200 = 1.2 seconds. The compile-time
619 default is to yield every 4 lines. */
620 if (i >= yield) {
621 msleep_interruptible(5);
622 yield = i + yieldlines;
623 }
624 }
625
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300626 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 write_lpcontrol(q, 2);
628 write_lpcontrol(q, 6);
629 udelay(3);
630 write_lpcontrol(q, 0xe);
631 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300632 if (got < len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 return got;
634 return len;
635}
636
637/*
638 * Video4linux interfacing
639 */
640
Hans Verkuil483d67f2010-05-10 03:51:02 -0300641static int qcam_querycap(struct file *file, void *priv,
642 struct v4l2_capability *vcap)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300644 struct qcam *qcam = video_drvdata(file);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300645
Hans Verkuil483d67f2010-05-10 03:51:02 -0300646 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
647 strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card));
648 strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
Hans Verkuil483d67f2010-05-10 03:51:02 -0300649 vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700650 return 0;
651}
652
Hans Verkuil483d67f2010-05-10 03:51:02 -0300653static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300655 if (vin->index > 0)
656 return -EINVAL;
657 strlcpy(vin->name, "Camera", sizeof(vin->name));
658 vin->type = V4L2_INPUT_TYPE_CAMERA;
659 vin->audioset = 0;
660 vin->tuner = 0;
661 vin->std = 0;
662 vin->status = 0;
663 return 0;
664}
665
666static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
667{
668 *inp = 0;
669 return 0;
670}
671
672static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
673{
674 return (inp > 0) ? -EINVAL : 0;
675}
676
677static int qcam_queryctrl(struct file *file, void *priv,
678 struct v4l2_queryctrl *qc)
679{
680 switch (qc->id) {
681 case V4L2_CID_BRIGHTNESS:
682 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180);
683 case V4L2_CID_CONTRAST:
684 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192);
685 case V4L2_CID_GAMMA:
686 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105);
687 }
688 return -EINVAL;
689}
690
691static int qcam_g_ctrl(struct file *file, void *priv,
692 struct v4l2_control *ctrl)
693{
694 struct qcam *qcam = video_drvdata(file);
695 int ret = 0;
696
697 switch (ctrl->id) {
698 case V4L2_CID_BRIGHTNESS:
699 ctrl->value = qcam->brightness;
700 break;
701 case V4L2_CID_CONTRAST:
702 ctrl->value = qcam->contrast;
703 break;
704 case V4L2_CID_GAMMA:
705 ctrl->value = qcam->whitebal;
706 break;
707 default:
708 ret = -EINVAL;
709 break;
710 }
711 return ret;
712}
713
714static int qcam_s_ctrl(struct file *file, void *priv,
715 struct v4l2_control *ctrl)
716{
717 struct qcam *qcam = video_drvdata(file);
718 int ret = 0;
719
720 mutex_lock(&qcam->lock);
721 switch (ctrl->id) {
722 case V4L2_CID_BRIGHTNESS:
723 qcam->brightness = ctrl->value;
724 break;
725 case V4L2_CID_CONTRAST:
726 qcam->contrast = ctrl->value;
727 break;
728 case V4L2_CID_GAMMA:
729 qcam->whitebal = ctrl->value;
730 break;
731 default:
732 ret = -EINVAL;
733 break;
734 }
735 if (ret == 0) {
736 qc_setscanmode(qcam);
737 qcam->status |= QC_PARAM_CHANGE;
738 }
739 mutex_unlock(&qcam->lock);
740 return ret;
741}
742
743static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
744{
745 struct qcam *qcam = video_drvdata(file);
746 struct v4l2_pix_format *pix = &fmt->fmt.pix;
747
748 pix->width = qcam->width / qcam->transfer_scale;
749 pix->height = qcam->height / qcam->transfer_scale;
750 pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6;
751 pix->field = V4L2_FIELD_NONE;
752 pix->bytesperline = qcam->width;
753 pix->sizeimage = qcam->width * qcam->height;
754 /* Just a guess */
755 pix->colorspace = V4L2_COLORSPACE_SRGB;
756 return 0;
757}
758
759static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
760{
761 struct v4l2_pix_format *pix = &fmt->fmt.pix;
762
763 if (pix->height <= 60 || pix->width <= 80) {
764 pix->height = 60;
765 pix->width = 80;
766 } else if (pix->height <= 120 || pix->width <= 160) {
767 pix->height = 120;
768 pix->width = 160;
769 } else {
770 pix->height = 240;
771 pix->width = 320;
772 }
773 if (pix->pixelformat != V4L2_PIX_FMT_Y4 &&
774 pix->pixelformat != V4L2_PIX_FMT_Y6)
775 pix->pixelformat = V4L2_PIX_FMT_Y4;
776 pix->field = V4L2_FIELD_NONE;
777 pix->bytesperline = pix->width;
778 pix->sizeimage = pix->width * pix->height;
779 /* Just a guess */
780 pix->colorspace = V4L2_COLORSPACE_SRGB;
781 return 0;
782}
783
784static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
785{
786 struct qcam *qcam = video_drvdata(file);
787 struct v4l2_pix_format *pix = &fmt->fmt.pix;
788 int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
789
790 if (ret)
791 return ret;
792 qcam->width = 320;
793 qcam->height = 240;
794 if (pix->height == 60)
795 qcam->transfer_scale = 4;
796 else if (pix->height == 120)
797 qcam->transfer_scale = 2;
798 else
799 qcam->transfer_scale = 1;
800 if (pix->pixelformat == V4L2_PIX_FMT_Y6)
801 qcam->bpp = 6;
802 else
803 qcam->bpp = 4;
804
805 mutex_lock(&qcam->lock);
806 qc_setscanmode(qcam);
807 /* We must update the camera before we grab. We could
808 just have changed the grab size */
809 qcam->status |= QC_PARAM_CHANGE;
810 mutex_unlock(&qcam->lock);
811 return 0;
812}
813
814static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
815{
816 static struct v4l2_fmtdesc formats[] = {
817 { 0, 0, 0,
818 "4-Bit Monochrome", V4L2_PIX_FMT_Y4,
819 { 0, 0, 0, 0 }
820 },
821 { 0, 0, 0,
822 "6-Bit Monochrome", V4L2_PIX_FMT_Y6,
823 { 0, 0, 0, 0 }
824 },
825 };
826 enum v4l2_buf_type type = fmt->type;
827
828 if (fmt->index > 1)
829 return -EINVAL;
830
831 *fmt = formats[fmt->index];
832 fmt->type = type;
833 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834}
835
836static ssize_t qcam_read(struct file *file, char __user *buf,
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300837 size_t count, loff_t *ppos)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300839 struct qcam *qcam = video_drvdata(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 int len;
841 parport_claim_or_block(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300842
Ingo Molnar3593cab2006-02-07 06:49:14 -0200843 mutex_lock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300844
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 qc_reset(qcam);
846
847 /* Update the camera parameters if we need to */
848 if (qcam->status & QC_PARAM_CHANGE)
849 qc_set(qcam);
850
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300851 len = qc_capture(qcam, buf, count);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300852
Ingo Molnar3593cab2006-02-07 06:49:14 -0200853 mutex_unlock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300854
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 parport_release(qcam->pdev);
856 return len;
857}
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300858
Hans Verkuilbec43662008-12-30 06:58:20 -0300859static const struct v4l2_file_operations qcam_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 .owner = THIS_MODULE,
Hans Verkuil61df3c92010-11-14 10:09:38 -0300861 .unlocked_ioctl = video_ioctl2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862 .read = qcam_read,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700863};
Hans Verkuil483d67f2010-05-10 03:51:02 -0300864
865static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
866 .vidioc_querycap = qcam_querycap,
867 .vidioc_g_input = qcam_g_input,
868 .vidioc_s_input = qcam_s_input,
869 .vidioc_enum_input = qcam_enum_input,
870 .vidioc_queryctrl = qcam_queryctrl,
871 .vidioc_g_ctrl = qcam_g_ctrl,
872 .vidioc_s_ctrl = qcam_s_ctrl,
873 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
874 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
875 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
876 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877};
878
Hans Verkuil483d67f2010-05-10 03:51:02 -0300879/* Initialize the QuickCam driver control structure. This is where
880 * defaults are set for people who don't have a config file.*/
881
882static struct qcam *qcam_init(struct parport *port)
883{
884 struct qcam *qcam;
885 struct v4l2_device *v4l2_dev;
886
887 qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL);
888 if (qcam == NULL)
889 return NULL;
890
891 v4l2_dev = &qcam->v4l2_dev;
892 strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name));
893
894 if (v4l2_device_register(NULL, v4l2_dev) < 0) {
895 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
Julia Lawallee893e92011-07-04 11:11:42 -0300896 kfree(qcam);
Hans Verkuil483d67f2010-05-10 03:51:02 -0300897 return NULL;
898 }
899
900 qcam->pport = port;
901 qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL,
902 NULL, 0, NULL);
903 if (qcam->pdev == NULL) {
904 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
905 kfree(qcam);
906 return NULL;
907 }
908
909 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
910 qcam->vdev.v4l2_dev = v4l2_dev;
911 qcam->vdev.fops = &qcam_fops;
912 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
913 qcam->vdev.release = video_device_release_empty;
914 video_set_drvdata(&qcam->vdev, qcam);
915
916 mutex_init(&qcam->lock);
917
918 qcam->port_mode = (QC_ANY | QC_NOTSET);
919 qcam->width = 320;
920 qcam->height = 240;
921 qcam->bpp = 4;
922 qcam->transfer_scale = 2;
923 qcam->contrast = 192;
924 qcam->brightness = 180;
925 qcam->whitebal = 105;
926 qcam->top = 1;
927 qcam->left = 14;
928 qcam->mode = -1;
929 qcam->status = QC_PARAM_CHANGE;
930 return qcam;
931}
932
933static int qc_calibrate(struct qcam *q)
934{
935 /*
936 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
937 * The white balance is an individual value for each
938 * quickcam.
939 */
940
941 int value;
942 int count = 0;
943
944 qc_command(q, 27); /* AutoAdjustOffset */
945 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
946
947 /* GetOffset (33) will read 255 until autocalibration */
948 /* is finished. After that, a value of 1-254 will be */
949 /* returned. */
950
951 do {
952 qc_command(q, 33);
953 value = qc_readparam(q);
954 mdelay(1);
955 schedule();
956 count++;
957 } while (value == 0xff && count < 2048);
958
959 q->whitebal = value;
960 return value;
961}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962
963static int init_bwqcam(struct parport *port)
964{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300965 struct qcam *qcam;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700966
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300967 if (num_cams == MAX_CAMS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
969 return -ENOSPC;
970 }
971
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300972 qcam = qcam_init(port);
973 if (qcam == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974 return -ENODEV;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300975
Linus Torvalds1da177e2005-04-16 15:20:36 -0700976 parport_claim_or_block(qcam->pdev);
977
978 qc_reset(qcam);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300979
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300980 if (qc_detect(qcam) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981 parport_release(qcam->pdev);
982 parport_unregister_device(qcam->pdev);
983 kfree(qcam);
984 return -ENODEV;
985 }
986 qc_calibrate(qcam);
987
988 parport_release(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300989
Hans Verkuil483d67f2010-05-10 03:51:02 -0300990 v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300991
Hans Verkuildc60de32008-09-03 17:11:58 -0300992 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 parport_unregister_device(qcam->pdev);
994 kfree(qcam);
995 return -ENODEV;
996 }
997
998 qcams[num_cams++] = qcam;
999
1000 return 0;
1001}
1002
Hans Verkuil483d67f2010-05-10 03:51:02 -03001003static void close_bwqcam(struct qcam *qcam)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001004{
1005 video_unregister_device(&qcam->vdev);
1006 parport_unregister_device(qcam->pdev);
1007 kfree(qcam);
1008}
1009
1010/* The parport parameter controls which parports will be scanned.
1011 * Scanning all parports causes some printers to print a garbage page.
1012 * -- March 14, 1999 Billy Donahue <billy@escape.com> */
1013#ifdef MODULE
1014static char *parport[MAX_CAMS] = { NULL, };
1015module_param_array(parport, charp, NULL, 0);
1016#endif
1017
1018static int accept_bwqcam(struct parport *port)
1019{
1020#ifdef MODULE
1021 int n;
1022
1023 if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
1024 /* user gave parport parameters */
Roel Kluinbb2b4542009-08-10 22:07:54 -03001025 for (n = 0; n < MAX_CAMS && parport[n]; n++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 char *ep;
1027 unsigned long r;
1028 r = simple_strtoul(parport[n], &ep, 0);
1029 if (ep == parport[n]) {
1030 printk(KERN_ERR
1031 "bw-qcam: bad port specifier \"%s\"\n",
1032 parport[n]);
1033 continue;
1034 }
1035 if (r == port->number)
1036 return 1;
1037 }
1038 return 0;
1039 }
1040#endif
1041 return 1;
1042}
1043
1044static void bwqcam_attach(struct parport *port)
1045{
1046 if (accept_bwqcam(port))
1047 init_bwqcam(port);
1048}
1049
1050static void bwqcam_detach(struct parport *port)
1051{
1052 int i;
1053 for (i = 0; i < num_cams; i++) {
Hans Verkuil483d67f2010-05-10 03:51:02 -03001054 struct qcam *qcam = qcams[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055 if (qcam && qcam->pdev->port == port) {
1056 qcams[i] = NULL;
1057 close_bwqcam(qcam);
1058 }
1059 }
1060}
1061
1062static struct parport_driver bwqcam_driver = {
1063 .name = "bw-qcam",
1064 .attach = bwqcam_attach,
1065 .detach = bwqcam_detach,
1066};
1067
1068static void __exit exit_bw_qcams(void)
1069{
1070 parport_unregister_driver(&bwqcam_driver);
1071}
1072
1073static int __init init_bw_qcams(void)
1074{
1075#ifdef MODULE
1076 /* Do some sanity checks on the module parameters. */
1077 if (maxpoll > 5000) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001078 printk(KERN_INFO "Connectix Quickcam max-poll was above 5000. Using 5000.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079 maxpoll = 5000;
1080 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001081
Linus Torvalds1da177e2005-04-16 15:20:36 -07001082 if (yieldlines < 1) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001083 printk(KERN_INFO "Connectix Quickcam yieldlines was less than 1. Using 1.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001084 yieldlines = 1;
1085 }
1086#endif
1087 return parport_register_driver(&bwqcam_driver);
1088}
1089
1090module_init(init_bw_qcams);
1091module_exit(exit_bw_qcams);
1092
1093MODULE_LICENSE("GPL");
Mauro Carvalho Chehab1990d502011-06-24 14:45:49 -03001094MODULE_VERSION("0.0.3");