blob: 497b342b0f72d6d5332180e54f371f74185d5d24 [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>
Hans Verkuil5fa1a892012-05-08 15:12:41 -030080#include <media/v4l2-fh.h>
81#include <media/v4l2-ctrls.h>
82#include <media/v4l2-event.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070083
Hans Verkuil483d67f2010-05-10 03:51:02 -030084/* One from column A... */
85#define QC_NOTSET 0
86#define QC_UNIDIR 1
87#define QC_BIDIR 2
88#define QC_SERIAL 3
89
90/* ... and one from column B */
91#define QC_ANY 0x00
92#define QC_FORCE_UNIDIR 0x10
93#define QC_FORCE_BIDIR 0x20
94#define QC_FORCE_SERIAL 0x30
95/* in the port_mode member */
96
97#define QC_MODE_MASK 0x07
98#define QC_FORCE_MASK 0x70
99
100#define MAX_HEIGHT 243
101#define MAX_WIDTH 336
102
103/* Bit fields for status flags */
104#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
105
106struct qcam {
107 struct v4l2_device v4l2_dev;
108 struct video_device vdev;
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300109 struct v4l2_ctrl_handler hdl;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300110 struct pardevice *pdev;
111 struct parport *pport;
112 struct mutex lock;
113 int width, height;
114 int bpp;
115 int mode;
116 int contrast, brightness, whitebal;
117 int port_mode;
118 int transfer_scale;
119 int top, left;
120 int status;
121 unsigned int saved_bits;
122 unsigned long in_use;
123};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300125static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
126static unsigned int yieldlines = 4; /* Yield after this many during capture */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127static int video_nr = -1;
Brett T. Wardend685a482008-01-10 04:33:31 -0300128static unsigned int force_init; /* Whether to probe aggressively */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129
130module_param(maxpoll, int, 0);
131module_param(yieldlines, int, 0);
132module_param(video_nr, int, 0);
133
Brett T. Wardend685a482008-01-10 04:33:31 -0300134/* Set force_init=1 to avoid detection by polling status register and
135 * immediately attempt to initialize qcam */
136module_param(force_init, int, 0);
137
Hans Verkuil483d67f2010-05-10 03:51:02 -0300138#define MAX_CAMS 4
139static struct qcam *qcams[MAX_CAMS];
140static unsigned int num_cams;
141
142static inline int read_lpstatus(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700143{
144 return parport_read_status(q->pport);
145}
146
Hans Verkuil483d67f2010-05-10 03:51:02 -0300147static inline int read_lpdata(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148{
149 return parport_read_data(q->pport);
150}
151
Hans Verkuil483d67f2010-05-10 03:51:02 -0300152static inline void write_lpdata(struct qcam *q, int d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153{
154 parport_write_data(q->pport, d);
155}
156
Hans Verkuil483d67f2010-05-10 03:51:02 -0300157static void write_lpcontrol(struct qcam *q, int d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158{
Brett Warden7c596fa2007-10-02 17:37:21 -0300159 if (d & 0x20) {
Brett Warden9e19db52007-09-28 03:19:04 -0300160 /* Set bidirectional mode to reverse (data in) */
161 parport_data_reverse(q->pport);
162 } else {
163 /* Set bidirectional mode to forward (data out) */
164 parport_data_forward(q->pport);
165 }
166
167 /* Now issue the regular port command, but strip out the
168 * direction flag */
169 d &= ~0x20;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 parport_write_control(q->pport, d);
171}
172
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173
174/* qc_waithand busy-waits for a handshake signal from the QuickCam.
175 * Almost all communication with the camera requires handshaking. */
176
Hans Verkuil483d67f2010-05-10 03:51:02 -0300177static int qc_waithand(struct qcam *q, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700178{
179 int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300180 int runs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300182 if (val) {
183 while (!((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300185 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700186 until the camera wakes up. However, we are
187 busy blocked until the camera responds, so
188 setting it lower is much better for interactive
189 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300190
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300191 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300193 if (runs > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700194 return -1;
195 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300196 } else {
197 while (((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300199 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700200 until the camera wakes up. However, we are
201 busy blocked until the camera responds, so
202 setting it lower is much better for interactive
203 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300204
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300205 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300207 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 return -1;
209 }
210 }
211
212 return status;
213}
214
215/* Waithand2 is used when the qcam is in bidirectional mode, and the
216 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
217 * (bit 3 of status register). It also returns the last value read,
218 * since this data is useful. */
219
Hans Verkuil483d67f2010-05-10 03:51:02 -0300220static unsigned int qc_waithand2(struct qcam *q, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221{
222 unsigned int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300223 int runs = 0;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300224
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300225 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700226 status = read_lpdata(q);
227 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300228 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 until the camera wakes up. However, we are
230 busy blocked until the camera responds, so
231 setting it lower is much better for interactive
232 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300233
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300234 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300236 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700237 return 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300238 } while ((status & 1) != val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239
240 return status;
241}
242
Hans Verkuil483d67f2010-05-10 03:51:02 -0300243/* qc_command is probably a bit of a misnomer -- it's used to send
244 * bytes *to* the camera. Generally, these bytes are either commands
245 * or arguments to commands, so the name fits, but it still bugs me a
246 * bit. See the documentation for a list of commands. */
247
248static int qc_command(struct qcam *q, int command)
249{
250 int n1, n2;
251 int cmd;
252
253 write_lpdata(q, command);
254 write_lpcontrol(q, 6);
255
256 n1 = qc_waithand(q, 1);
257
258 write_lpcontrol(q, 0xe);
259 n2 = qc_waithand(q, 0);
260
261 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
262 return cmd;
263}
264
265static int qc_readparam(struct qcam *q)
266{
267 int n1, n2;
268 int cmd;
269
270 write_lpcontrol(q, 6);
271 n1 = qc_waithand(q, 1);
272
273 write_lpcontrol(q, 0xe);
274 n2 = qc_waithand(q, 0);
275
276 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
277 return cmd;
278}
279
Linus Torvalds1da177e2005-04-16 15:20:36 -0700280
281/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
282 the status register at 5-10 Hz. This is only used in the autoprobe
283 code. Be aware that this isn't the way Connectix detects the
284 camera (they send a reset and try to handshake), but this should be
285 almost completely safe, while their method screws up my printer if
286 I plug it in before the camera. */
287
Hans Verkuil483d67f2010-05-10 03:51:02 -0300288static int qc_detect(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700289{
290 int reg, lastreg;
291 int count = 0;
292 int i;
293
Brett T. Wardend685a482008-01-10 04:33:31 -0300294 if (force_init)
295 return 1;
296
Linus Torvalds1da177e2005-04-16 15:20:36 -0700297 lastreg = reg = read_lpstatus(q) & 0xf0;
298
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300299 for (i = 0; i < 500; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 reg = read_lpstatus(q) & 0xf0;
301 if (reg != lastreg)
302 count++;
303 lastreg = reg;
304 mdelay(2);
305 }
306
307
308#if 0
309 /* Force camera detection during testing. Sometimes the camera
310 won't be flashing these bits. Possibly unloading the module
311 in the middle of a grab? Or some timeout condition?
312 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300313 printk(KERN_DEBUG "Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700314 return 1;
315#endif
316
317 /* Be (even more) liberal in what you accept... */
318
Brett Warden7c596fa2007-10-02 17:37:21 -0300319 if (count > 20 && count < 400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700320 return 1; /* found */
Brett Warden9e19db52007-09-28 03:19:04 -0300321 } else {
Brett Warden7c596fa2007-10-02 17:37:21 -0300322 printk(KERN_ERR "No Quickcam found on port %s\n",
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300323 q->pport->name);
Brett T. Wardend685a482008-01-10 04:33:31 -0300324 printk(KERN_DEBUG "Quickcam detection counter: %u\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700325 return 0; /* not found */
Brett Warden9e19db52007-09-28 03:19:04 -0300326 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327}
328
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329/* Decide which scan mode to use. There's no real requirement that
330 * the scanmode match the resolution in q->height and q-> width -- the
331 * camera takes the picture at the resolution specified in the
332 * "scanmode" and then returns the image at the resolution specified
333 * with the resolution commands. If the scan is bigger than the
334 * requested resolution, the upper-left hand corner of the scan is
335 * returned. If the scan is smaller, then the rest of the image
336 * returned contains garbage. */
337
Hans Verkuil483d67f2010-05-10 03:51:02 -0300338static int qc_setscanmode(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339{
340 int old_mode = q->mode;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300341
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300342 switch (q->transfer_scale) {
343 case 1:
344 q->mode = 0;
345 break;
346 case 2:
347 q->mode = 4;
348 break;
349 case 4:
350 q->mode = 8;
351 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 }
353
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300354 switch (q->bpp) {
355 case 4:
356 break;
357 case 6:
358 q->mode += 2;
359 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360 }
361
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300362 switch (q->port_mode & QC_MODE_MASK) {
363 case QC_BIDIR:
364 q->mode += 1;
365 break;
366 case QC_NOTSET:
367 case QC_UNIDIR:
368 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300370
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 if (q->mode != old_mode)
372 q->status |= QC_PARAM_CHANGE;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300373
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 return 0;
375}
376
377
Hans Verkuil483d67f2010-05-10 03:51:02 -0300378/* Reset the QuickCam. This uses the same sequence the Windows
379 * QuickPic program uses. Someone with a bi-directional port should
380 * check that bi-directional mode is detected right, and then
381 * implement bi-directional mode in qc_readbyte(). */
382
383static void qc_reset(struct qcam *q)
384{
385 switch (q->port_mode & QC_FORCE_MASK) {
386 case QC_FORCE_UNIDIR:
387 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
388 break;
389
390 case QC_FORCE_BIDIR:
391 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
392 break;
393
394 case QC_ANY:
395 write_lpcontrol(q, 0x20);
396 write_lpdata(q, 0x75);
397
398 if (read_lpdata(q) != 0x75)
399 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
400 else
401 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
402 break;
403 }
404
405 write_lpcontrol(q, 0xb);
406 udelay(250);
407 write_lpcontrol(q, 0xe);
408 qc_setscanmode(q); /* in case port_mode changed */
409}
410
411
412
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413/* Reset the QuickCam and program for brightness, contrast,
414 * white-balance, and resolution. */
415
Hans Verkuil483d67f2010-05-10 03:51:02 -0300416static void qc_set(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417{
418 int val;
419 int val2;
420
421 qc_reset(q);
422
423 /* Set the brightness. Yes, this is repetitive, but it works.
424 * Shorter versions seem to fail subtly. Feel free to try :-). */
425 /* I think the problem was in qc_command, not here -- bls */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300426
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 qc_command(q, 0xb);
428 qc_command(q, q->brightness);
429
430 val = q->height / q->transfer_scale;
431 qc_command(q, 0x11);
432 qc_command(q, val);
433 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
434 /* The normal "transfers per line" calculation doesn't seem to work
435 as expected here (and yet it works fine in qc_scan). No idea
436 why this case is the odd man out. Fortunately, Laird's original
437 working version gives me a good way to guess at working values.
438 -- bls */
439 val = q->width;
440 val2 = q->transfer_scale * 4;
441 } else {
442 val = q->width * q->bpp;
443 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300444 q->transfer_scale;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 }
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300446 val = DIV_ROUND_UP(val, val2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700447 qc_command(q, 0x13);
448 qc_command(q, val);
449
450 /* Setting top and left -- bls */
451 qc_command(q, 0xd);
452 qc_command(q, q->top);
453 qc_command(q, 0xf);
454 qc_command(q, q->left / 2);
455
456 qc_command(q, 0x19);
457 qc_command(q, q->contrast);
458 qc_command(q, 0x1f);
459 qc_command(q, q->whitebal);
460
461 /* Clear flag that we must update the grabbing parameters on the camera
462 before we grab the next frame */
463 q->status &= (~QC_PARAM_CHANGE);
464}
465
466/* Qc_readbytes reads some bytes from the QC and puts them in
467 the supplied buffer. It returns the number of bytes read,
468 or -1 on error. */
469
Hans Verkuil483d67f2010-05-10 03:51:02 -0300470static inline int qc_readbytes(struct qcam *q, char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471{
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300472 int ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700473 unsigned int hi, lo;
474 unsigned int hi2, lo2;
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300475 static int state;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300477 if (buffer == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700478 state = 0;
479 return 0;
480 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300481
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300482 switch (q->port_mode & QC_MODE_MASK) {
483 case QC_BIDIR: /* Bi-directional Port */
484 write_lpcontrol(q, 0x26);
485 lo = (qc_waithand2(q, 1) >> 1);
486 hi = (read_lpstatus(q) >> 3) & 0x1f;
487 write_lpcontrol(q, 0x2e);
488 lo2 = (qc_waithand2(q, 0) >> 1);
489 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
490 switch (q->bpp) {
491 case 4:
492 buffer[0] = lo & 0xf;
493 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
494 buffer[2] = (hi & 0x1e) >> 1;
495 buffer[3] = lo2 & 0xf;
496 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
497 buffer[5] = (hi2 & 0x1e) >> 1;
498 ret = 6;
499 break;
500 case 6:
501 buffer[0] = lo & 0x3f;
502 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
503 buffer[2] = lo2 & 0x3f;
504 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
505 ret = 4;
506 break;
507 }
508 break;
509
510 case QC_UNIDIR: /* Unidirectional Port */
511 write_lpcontrol(q, 6);
512 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
513 write_lpcontrol(q, 0xe);
514 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
515
516 switch (q->bpp) {
517 case 4:
518 buffer[0] = lo;
519 buffer[1] = hi;
520 ret = 2;
521 break;
522 case 6:
523 switch (state) {
524 case 0:
525 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
526 q->saved_bits = (hi & 3) << 4;
527 state = 1;
528 ret = 1;
529 break;
530 case 1:
531 buffer[0] = lo | q->saved_bits;
532 q->saved_bits = hi << 2;
533 state = 2;
534 ret = 1;
535 break;
536 case 2:
537 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
538 buffer[1] = ((lo & 3) << 4) | hi;
539 state = 0;
540 ret = 2;
541 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 }
543 break;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300544 }
545 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 }
547 return ret;
548}
549
550/* requests a scan from the camera. It sends the correct instructions
551 * to the camera and then reads back the correct number of bytes. In
552 * previous versions of this routine the return structure contained
553 * the raw output from the camera, and there was a 'qc_convertscan'
554 * function that converted that to a useful format. In version 0.3 I
555 * rolled qc_convertscan into qc_scan and now I only return the
556 * converted scan. The format is just an one-dimensional array of
557 * characters, one for each pixel, with 0=black up to n=white, where
558 * n=2^(bit depth)-1. Ask me for more details if you don't understand
559 * this. */
560
Hans Verkuil483d67f2010-05-10 03:51:02 -0300561static long qc_capture(struct qcam *q, char __user *buf, unsigned long len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562{
563 int i, j, k, yield;
564 int bytes;
565 int linestotrans, transperline;
566 int divisor;
567 int pixels_per_line;
568 int pixels_read = 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300569 int got = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570 char buffer[6];
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300571 int shift = 8 - q->bpp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700572 char invert;
573
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300574 if (q->mode == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 return -ENXIO;
576
577 qc_command(q, 0x7);
578 qc_command(q, q->mode);
579
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300580 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700581 write_lpcontrol(q, 0x2e); /* turn port around */
582 write_lpcontrol(q, 0x26);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300583 qc_waithand(q, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 write_lpcontrol(q, 0x2e);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300585 qc_waithand(q, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300587
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 /* strange -- should be 15:63 below, but 4bpp is odd */
589 invert = (q->bpp == 4) ? 16 : 63;
590
591 linestotrans = q->height / q->transfer_scale;
592 pixels_per_line = q->width / q->transfer_scale;
593 transperline = q->width * q->bpp;
594 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300595 q->transfer_scale;
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300596 transperline = DIV_ROUND_UP(transperline, divisor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300598 for (i = 0, yield = yieldlines; i < linestotrans; i++) {
599 for (pixels_read = j = 0; j < transperline; j++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 bytes = qc_readbytes(q, buffer);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300601 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700602 int o;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300603 if (buffer[k] == 0 && invert == 16) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
605 must be 0-15 -- bls */
606 buffer[k] = 16;
607 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300608 o = i * pixels_per_line + pixels_read + k;
609 if (o < len) {
Hans Verkuilde878972012-06-06 01:46:50 -0300610 u8 ch = invert - buffer[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611 got++;
Hans Verkuilde878972012-06-06 01:46:50 -0300612 put_user(ch << shift, buf + o);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700613 }
614 }
615 pixels_read += bytes;
616 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300617 qc_readbytes(q, NULL); /* reset state machine */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300618
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 /* Grabbing an entire frame from the quickcam is a lengthy
620 process. We don't (usually) want to busy-block the
621 processor for the entire frame. yieldlines is a module
622 parameter. If we yield every line, the minimum frame
623 time will be 240 / 200 = 1.2 seconds. The compile-time
624 default is to yield every 4 lines. */
625 if (i >= yield) {
626 msleep_interruptible(5);
627 yield = i + yieldlines;
628 }
629 }
630
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300631 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 write_lpcontrol(q, 2);
633 write_lpcontrol(q, 6);
634 udelay(3);
635 write_lpcontrol(q, 0xe);
636 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300637 if (got < len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 return got;
639 return len;
640}
641
642/*
643 * Video4linux interfacing
644 */
645
Hans Verkuil483d67f2010-05-10 03:51:02 -0300646static int qcam_querycap(struct file *file, void *priv,
647 struct v4l2_capability *vcap)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300649 struct qcam *qcam = video_drvdata(file);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300650
Hans Verkuil483d67f2010-05-10 03:51:02 -0300651 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
Hans Verkuilde878972012-06-06 01:46:50 -0300652 strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card));
653 strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info));
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300654 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
655 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 return 0;
657}
658
Hans Verkuil483d67f2010-05-10 03:51:02 -0300659static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300661 if (vin->index > 0)
662 return -EINVAL;
663 strlcpy(vin->name, "Camera", sizeof(vin->name));
664 vin->type = V4L2_INPUT_TYPE_CAMERA;
665 vin->audioset = 0;
666 vin->tuner = 0;
667 vin->std = 0;
668 vin->status = 0;
669 return 0;
670}
671
672static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
673{
674 *inp = 0;
675 return 0;
676}
677
678static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
679{
680 return (inp > 0) ? -EINVAL : 0;
681}
682
Hans Verkuil483d67f2010-05-10 03:51:02 -0300683static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
684{
685 struct qcam *qcam = video_drvdata(file);
686 struct v4l2_pix_format *pix = &fmt->fmt.pix;
687
688 pix->width = qcam->width / qcam->transfer_scale;
689 pix->height = qcam->height / qcam->transfer_scale;
690 pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6;
691 pix->field = V4L2_FIELD_NONE;
Hans Verkuilde878972012-06-06 01:46:50 -0300692 pix->bytesperline = pix->width;
693 pix->sizeimage = pix->width * pix->height;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300694 /* Just a guess */
695 pix->colorspace = V4L2_COLORSPACE_SRGB;
Hans Verkuil11d37932013-01-30 11:59:48 -0300696 pix->priv = 0;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300697 return 0;
698}
699
700static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
701{
702 struct v4l2_pix_format *pix = &fmt->fmt.pix;
703
704 if (pix->height <= 60 || pix->width <= 80) {
705 pix->height = 60;
706 pix->width = 80;
707 } else if (pix->height <= 120 || pix->width <= 160) {
708 pix->height = 120;
709 pix->width = 160;
710 } else {
711 pix->height = 240;
712 pix->width = 320;
713 }
714 if (pix->pixelformat != V4L2_PIX_FMT_Y4 &&
715 pix->pixelformat != V4L2_PIX_FMT_Y6)
716 pix->pixelformat = V4L2_PIX_FMT_Y4;
717 pix->field = V4L2_FIELD_NONE;
718 pix->bytesperline = pix->width;
719 pix->sizeimage = pix->width * pix->height;
720 /* Just a guess */
721 pix->colorspace = V4L2_COLORSPACE_SRGB;
Hans Verkuil11d37932013-01-30 11:59:48 -0300722 pix->priv = 0;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300723 return 0;
724}
725
726static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
727{
728 struct qcam *qcam = video_drvdata(file);
729 struct v4l2_pix_format *pix = &fmt->fmt.pix;
730 int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
731
732 if (ret)
733 return ret;
734 qcam->width = 320;
735 qcam->height = 240;
736 if (pix->height == 60)
737 qcam->transfer_scale = 4;
738 else if (pix->height == 120)
739 qcam->transfer_scale = 2;
740 else
741 qcam->transfer_scale = 1;
742 if (pix->pixelformat == V4L2_PIX_FMT_Y6)
743 qcam->bpp = 6;
744 else
745 qcam->bpp = 4;
746
747 mutex_lock(&qcam->lock);
748 qc_setscanmode(qcam);
749 /* We must update the camera before we grab. We could
750 just have changed the grab size */
751 qcam->status |= QC_PARAM_CHANGE;
752 mutex_unlock(&qcam->lock);
753 return 0;
754}
755
756static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
757{
758 static struct v4l2_fmtdesc formats[] = {
759 { 0, 0, 0,
760 "4-Bit Monochrome", V4L2_PIX_FMT_Y4,
761 { 0, 0, 0, 0 }
762 },
Hans Verkuilde878972012-06-06 01:46:50 -0300763 { 1, 0, 0,
Hans Verkuil483d67f2010-05-10 03:51:02 -0300764 "6-Bit Monochrome", V4L2_PIX_FMT_Y6,
765 { 0, 0, 0, 0 }
766 },
767 };
768 enum v4l2_buf_type type = fmt->type;
769
770 if (fmt->index > 1)
771 return -EINVAL;
772
773 *fmt = formats[fmt->index];
774 fmt->type = type;
775 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700776}
777
Hans Verkuilde878972012-06-06 01:46:50 -0300778static int qcam_enum_framesizes(struct file *file, void *fh,
779 struct v4l2_frmsizeenum *fsize)
780{
781 static const struct v4l2_frmsize_discrete sizes[] = {
782 { 80, 60 },
783 { 160, 120 },
784 { 320, 240 },
785 };
786
787 if (fsize->index > 2)
788 return -EINVAL;
789 if (fsize->pixel_format != V4L2_PIX_FMT_Y4 &&
790 fsize->pixel_format != V4L2_PIX_FMT_Y6)
791 return -EINVAL;
792 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
793 fsize->discrete = sizes[fsize->index];
794 return 0;
795}
796
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797static ssize_t qcam_read(struct file *file, char __user *buf,
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300798 size_t count, loff_t *ppos)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300800 struct qcam *qcam = video_drvdata(file);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 int len;
802 parport_claim_or_block(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300803
Ingo Molnar3593cab2006-02-07 06:49:14 -0200804 mutex_lock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300805
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 qc_reset(qcam);
807
808 /* Update the camera parameters if we need to */
809 if (qcam->status & QC_PARAM_CHANGE)
810 qc_set(qcam);
811
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300812 len = qc_capture(qcam, buf, count);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300813
Ingo Molnar3593cab2006-02-07 06:49:14 -0200814 mutex_unlock(&qcam->lock);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300815
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 parport_release(qcam->pdev);
817 return len;
818}
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300819
Hans Verkuilde878972012-06-06 01:46:50 -0300820static unsigned int qcam_poll(struct file *filp, poll_table *wait)
821{
822 return v4l2_ctrl_poll(filp, wait) | POLLIN | POLLRDNORM;
823}
824
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300825static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
826{
827 struct qcam *qcam =
828 container_of(ctrl->handler, struct qcam, hdl);
829 int ret = 0;
830
831 mutex_lock(&qcam->lock);
832 switch (ctrl->id) {
833 case V4L2_CID_BRIGHTNESS:
834 qcam->brightness = ctrl->val;
835 break;
836 case V4L2_CID_CONTRAST:
837 qcam->contrast = ctrl->val;
838 break;
839 case V4L2_CID_GAMMA:
840 qcam->whitebal = ctrl->val;
841 break;
842 default:
843 ret = -EINVAL;
844 break;
845 }
846 if (ret == 0) {
847 qc_setscanmode(qcam);
848 qcam->status |= QC_PARAM_CHANGE;
849 }
850 mutex_unlock(&qcam->lock);
851 return ret;
852}
853
Hans Verkuilbec43662008-12-30 06:58:20 -0300854static const struct v4l2_file_operations qcam_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 .owner = THIS_MODULE,
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300856 .open = v4l2_fh_open,
857 .release = v4l2_fh_release,
Hans Verkuilde878972012-06-06 01:46:50 -0300858 .poll = qcam_poll,
Hans Verkuil61df3c92010-11-14 10:09:38 -0300859 .unlocked_ioctl = video_ioctl2,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 .read = qcam_read,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861};
Hans Verkuil483d67f2010-05-10 03:51:02 -0300862
863static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
864 .vidioc_querycap = qcam_querycap,
865 .vidioc_g_input = qcam_g_input,
866 .vidioc_s_input = qcam_s_input,
867 .vidioc_enum_input = qcam_enum_input,
Hans Verkuil483d67f2010-05-10 03:51:02 -0300868 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
Hans Verkuilde878972012-06-06 01:46:50 -0300869 .vidioc_enum_framesizes = qcam_enum_framesizes,
Hans Verkuil483d67f2010-05-10 03:51:02 -0300870 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
871 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
872 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300873 .vidioc_log_status = v4l2_ctrl_log_status,
874 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
875 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
876};
877
878static const struct v4l2_ctrl_ops qcam_ctrl_ops = {
879 .s_ctrl = qcam_s_ctrl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880};
881
Hans Verkuil483d67f2010-05-10 03:51:02 -0300882/* Initialize the QuickCam driver control structure. This is where
883 * defaults are set for people who don't have a config file.*/
884
885static struct qcam *qcam_init(struct parport *port)
886{
887 struct qcam *qcam;
888 struct v4l2_device *v4l2_dev;
889
890 qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL);
891 if (qcam == NULL)
892 return NULL;
893
894 v4l2_dev = &qcam->v4l2_dev;
Hans Verkuilde878972012-06-06 01:46:50 -0300895 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams);
Hans Verkuil483d67f2010-05-10 03:51:02 -0300896
Hans Verkuilde878972012-06-06 01:46:50 -0300897 if (v4l2_device_register(port->dev, v4l2_dev) < 0) {
Hans Verkuil483d67f2010-05-10 03:51:02 -0300898 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
Julia Lawallee893e92011-07-04 11:11:42 -0300899 kfree(qcam);
Hans Verkuil483d67f2010-05-10 03:51:02 -0300900 return NULL;
901 }
902
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300903 v4l2_ctrl_handler_init(&qcam->hdl, 3);
904 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
905 V4L2_CID_BRIGHTNESS, 0, 255, 1, 180);
906 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
907 V4L2_CID_CONTRAST, 0, 255, 1, 192);
908 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
909 V4L2_CID_GAMMA, 0, 255, 1, 105);
910 if (qcam->hdl.error) {
911 v4l2_err(v4l2_dev, "couldn't register controls\n");
912 v4l2_ctrl_handler_free(&qcam->hdl);
913 kfree(qcam);
914 return NULL;
915 }
Hans Verkuil483d67f2010-05-10 03:51:02 -0300916 qcam->pport = port;
Hans Verkuilde878972012-06-06 01:46:50 -0300917 qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL,
Hans Verkuil483d67f2010-05-10 03:51:02 -0300918 NULL, 0, NULL);
919 if (qcam->pdev == NULL) {
920 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300921 v4l2_ctrl_handler_free(&qcam->hdl);
Hans Verkuil483d67f2010-05-10 03:51:02 -0300922 kfree(qcam);
923 return NULL;
924 }
925
926 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
927 qcam->vdev.v4l2_dev = v4l2_dev;
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300928 qcam->vdev.ctrl_handler = &qcam->hdl;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300929 qcam->vdev.fops = &qcam_fops;
930 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300931 set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
Hans Verkuil483d67f2010-05-10 03:51:02 -0300932 qcam->vdev.release = video_device_release_empty;
933 video_set_drvdata(&qcam->vdev, qcam);
934
935 mutex_init(&qcam->lock);
936
937 qcam->port_mode = (QC_ANY | QC_NOTSET);
938 qcam->width = 320;
939 qcam->height = 240;
940 qcam->bpp = 4;
941 qcam->transfer_scale = 2;
942 qcam->contrast = 192;
943 qcam->brightness = 180;
944 qcam->whitebal = 105;
945 qcam->top = 1;
946 qcam->left = 14;
947 qcam->mode = -1;
948 qcam->status = QC_PARAM_CHANGE;
949 return qcam;
950}
951
952static int qc_calibrate(struct qcam *q)
953{
954 /*
955 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
956 * The white balance is an individual value for each
957 * quickcam.
958 */
959
960 int value;
961 int count = 0;
962
963 qc_command(q, 27); /* AutoAdjustOffset */
964 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
965
966 /* GetOffset (33) will read 255 until autocalibration */
967 /* is finished. After that, a value of 1-254 will be */
968 /* returned. */
969
970 do {
971 qc_command(q, 33);
972 value = qc_readparam(q);
973 mdelay(1);
974 schedule();
975 count++;
976 } while (value == 0xff && count < 2048);
977
978 q->whitebal = value;
979 return value;
980}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700981
982static int init_bwqcam(struct parport *port)
983{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300984 struct qcam *qcam;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300986 if (num_cams == MAX_CAMS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
988 return -ENOSPC;
989 }
990
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300991 qcam = qcam_init(port);
992 if (qcam == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 return -ENODEV;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300994
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 parport_claim_or_block(qcam->pdev);
996
997 qc_reset(qcam);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300998
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300999 if (qc_detect(qcam) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001000 parport_release(qcam->pdev);
1001 parport_unregister_device(qcam->pdev);
1002 kfree(qcam);
1003 return -ENODEV;
1004 }
1005 qc_calibrate(qcam);
Hans Verkuilde878972012-06-06 01:46:50 -03001006 v4l2_ctrl_handler_setup(&qcam->hdl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001007
1008 parport_release(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001009
Hans Verkuil483d67f2010-05-10 03:51:02 -03001010 v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001011
Hans Verkuildc60de32008-09-03 17:11:58 -03001012 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 parport_unregister_device(qcam->pdev);
1014 kfree(qcam);
1015 return -ENODEV;
1016 }
1017
1018 qcams[num_cams++] = qcam;
1019
1020 return 0;
1021}
1022
Hans Verkuil483d67f2010-05-10 03:51:02 -03001023static void close_bwqcam(struct qcam *qcam)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001024{
1025 video_unregister_device(&qcam->vdev);
Hans Verkuil5fa1a892012-05-08 15:12:41 -03001026 v4l2_ctrl_handler_free(&qcam->hdl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027 parport_unregister_device(qcam->pdev);
1028 kfree(qcam);
1029}
1030
1031/* The parport parameter controls which parports will be scanned.
1032 * Scanning all parports causes some printers to print a garbage page.
1033 * -- March 14, 1999 Billy Donahue <billy@escape.com> */
1034#ifdef MODULE
1035static char *parport[MAX_CAMS] = { NULL, };
1036module_param_array(parport, charp, NULL, 0);
1037#endif
1038
1039static int accept_bwqcam(struct parport *port)
1040{
1041#ifdef MODULE
1042 int n;
1043
1044 if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
1045 /* user gave parport parameters */
Roel Kluinbb2b4542009-08-10 22:07:54 -03001046 for (n = 0; n < MAX_CAMS && parport[n]; n++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 char *ep;
1048 unsigned long r;
1049 r = simple_strtoul(parport[n], &ep, 0);
1050 if (ep == parport[n]) {
1051 printk(KERN_ERR
1052 "bw-qcam: bad port specifier \"%s\"\n",
1053 parport[n]);
1054 continue;
1055 }
1056 if (r == port->number)
1057 return 1;
1058 }
1059 return 0;
1060 }
1061#endif
1062 return 1;
1063}
1064
1065static void bwqcam_attach(struct parport *port)
1066{
1067 if (accept_bwqcam(port))
1068 init_bwqcam(port);
1069}
1070
1071static void bwqcam_detach(struct parport *port)
1072{
1073 int i;
1074 for (i = 0; i < num_cams; i++) {
Hans Verkuil483d67f2010-05-10 03:51:02 -03001075 struct qcam *qcam = qcams[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 if (qcam && qcam->pdev->port == port) {
1077 qcams[i] = NULL;
1078 close_bwqcam(qcam);
1079 }
1080 }
1081}
1082
1083static struct parport_driver bwqcam_driver = {
1084 .name = "bw-qcam",
1085 .attach = bwqcam_attach,
1086 .detach = bwqcam_detach,
1087};
1088
1089static void __exit exit_bw_qcams(void)
1090{
1091 parport_unregister_driver(&bwqcam_driver);
1092}
1093
1094static int __init init_bw_qcams(void)
1095{
1096#ifdef MODULE
1097 /* Do some sanity checks on the module parameters. */
1098 if (maxpoll > 5000) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001099 printk(KERN_INFO "Connectix Quickcam max-poll was above 5000. Using 5000.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 maxpoll = 5000;
1101 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001102
Linus Torvalds1da177e2005-04-16 15:20:36 -07001103 if (yieldlines < 1) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001104 printk(KERN_INFO "Connectix Quickcam yieldlines was less than 1. Using 1.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001105 yieldlines = 1;
1106 }
1107#endif
1108 return parport_register_driver(&bwqcam_driver);
1109}
1110
1111module_init(init_bw_qcams);
1112module_exit(exit_bw_qcams);
1113
1114MODULE_LICENSE("GPL");
Mauro Carvalho Chehab1990d502011-06-24 14:45:49 -03001115MODULE_VERSION("0.0.3");