blob: d3fe34f14c0dfcbe41c2755daa6437813d446ad7 [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>
Hans Verkuil1888e4a2013-01-30 14:10:14 -030083#include <media/videobuf2-vmalloc.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070084
Hans Verkuil483d67f2010-05-10 03:51:02 -030085/* One from column A... */
86#define QC_NOTSET 0
87#define QC_UNIDIR 1
88#define QC_BIDIR 2
89#define QC_SERIAL 3
90
91/* ... and one from column B */
92#define QC_ANY 0x00
93#define QC_FORCE_UNIDIR 0x10
94#define QC_FORCE_BIDIR 0x20
95#define QC_FORCE_SERIAL 0x30
96/* in the port_mode member */
97
98#define QC_MODE_MASK 0x07
99#define QC_FORCE_MASK 0x70
100
101#define MAX_HEIGHT 243
102#define MAX_WIDTH 336
103
104/* Bit fields for status flags */
105#define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */
106
107struct qcam {
108 struct v4l2_device v4l2_dev;
109 struct video_device vdev;
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300110 struct v4l2_ctrl_handler hdl;
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300111 struct vb2_queue vb_vidq;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300112 struct pardevice *pdev;
113 struct parport *pport;
114 struct mutex lock;
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300115 struct mutex queue_lock;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300116 int width, height;
117 int bpp;
118 int mode;
119 int contrast, brightness, whitebal;
120 int port_mode;
121 int transfer_scale;
122 int top, left;
123 int status;
124 unsigned int saved_bits;
125 unsigned long in_use;
126};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300128static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */
129static unsigned int yieldlines = 4; /* Yield after this many during capture */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700130static int video_nr = -1;
Brett T. Wardend685a482008-01-10 04:33:31 -0300131static unsigned int force_init; /* Whether to probe aggressively */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
133module_param(maxpoll, int, 0);
134module_param(yieldlines, int, 0);
135module_param(video_nr, int, 0);
136
Brett T. Wardend685a482008-01-10 04:33:31 -0300137/* Set force_init=1 to avoid detection by polling status register and
138 * immediately attempt to initialize qcam */
139module_param(force_init, int, 0);
140
Hans Verkuil483d67f2010-05-10 03:51:02 -0300141#define MAX_CAMS 4
142static struct qcam *qcams[MAX_CAMS];
143static unsigned int num_cams;
144
145static inline int read_lpstatus(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146{
147 return parport_read_status(q->pport);
148}
149
Hans Verkuil483d67f2010-05-10 03:51:02 -0300150static inline int read_lpdata(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151{
152 return parport_read_data(q->pport);
153}
154
Hans Verkuil483d67f2010-05-10 03:51:02 -0300155static inline void write_lpdata(struct qcam *q, int d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156{
157 parport_write_data(q->pport, d);
158}
159
Hans Verkuil483d67f2010-05-10 03:51:02 -0300160static void write_lpcontrol(struct qcam *q, int d)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700161{
Brett Warden7c596fa2007-10-02 17:37:21 -0300162 if (d & 0x20) {
Brett Warden9e19db52007-09-28 03:19:04 -0300163 /* Set bidirectional mode to reverse (data in) */
164 parport_data_reverse(q->pport);
165 } else {
166 /* Set bidirectional mode to forward (data out) */
167 parport_data_forward(q->pport);
168 }
169
170 /* Now issue the regular port command, but strip out the
171 * direction flag */
172 d &= ~0x20;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700173 parport_write_control(q->pport, d);
174}
175
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176
177/* qc_waithand busy-waits for a handshake signal from the QuickCam.
178 * Almost all communication with the camera requires handshaking. */
179
Hans Verkuil483d67f2010-05-10 03:51:02 -0300180static int qc_waithand(struct qcam *q, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181{
182 int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300183 int runs = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300185 if (val) {
186 while (!((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300188 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700189 until the camera wakes up. However, we are
190 busy blocked until the camera responds, so
191 setting it lower is much better for interactive
192 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300193
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300194 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300196 if (runs > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197 return -1;
198 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300199 } else {
200 while (((status = read_lpstatus(q)) & 8)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300202 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 until the camera wakes up. However, we are
204 busy blocked until the camera responds, so
205 setting it lower is much better for interactive
206 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300207
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300208 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300210 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 return -1;
212 }
213 }
214
215 return status;
216}
217
218/* Waithand2 is used when the qcam is in bidirectional mode, and the
219 * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1
220 * (bit 3 of status register). It also returns the last value read,
221 * since this data is useful. */
222
Hans Verkuil483d67f2010-05-10 03:51:02 -0300223static unsigned int qc_waithand2(struct qcam *q, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224{
225 unsigned int status;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300226 int runs = 0;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300227
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300228 do {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 status = read_lpdata(q);
230 /* 1000 is enough spins on the I/O for all normal
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300231 cases, at that point we start to poll slowly
Linus Torvalds1da177e2005-04-16 15:20:36 -0700232 until the camera wakes up. However, we are
233 busy blocked until the camera responds, so
234 setting it lower is much better for interactive
235 response. */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300236
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300237 if (runs++ > maxpoll)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700238 msleep_interruptible(5);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300239 if (runs++ > (maxpoll + 1000)) /* 5 seconds */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 return 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300241 } while ((status & 1) != val);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
243 return status;
244}
245
Hans Verkuil483d67f2010-05-10 03:51:02 -0300246/* qc_command is probably a bit of a misnomer -- it's used to send
247 * bytes *to* the camera. Generally, these bytes are either commands
248 * or arguments to commands, so the name fits, but it still bugs me a
249 * bit. See the documentation for a list of commands. */
250
251static int qc_command(struct qcam *q, int command)
252{
253 int n1, n2;
254 int cmd;
255
256 write_lpdata(q, command);
257 write_lpcontrol(q, 6);
258
259 n1 = qc_waithand(q, 1);
260
261 write_lpcontrol(q, 0xe);
262 n2 = qc_waithand(q, 0);
263
264 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
265 return cmd;
266}
267
268static int qc_readparam(struct qcam *q)
269{
270 int n1, n2;
271 int cmd;
272
273 write_lpcontrol(q, 6);
274 n1 = qc_waithand(q, 1);
275
276 write_lpcontrol(q, 0xe);
277 n2 = qc_waithand(q, 0);
278
279 cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4);
280 return cmd;
281}
282
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283
284/* Try to detect a QuickCam. It appears to flash the upper 4 bits of
285 the status register at 5-10 Hz. This is only used in the autoprobe
286 code. Be aware that this isn't the way Connectix detects the
287 camera (they send a reset and try to handshake), but this should be
288 almost completely safe, while their method screws up my printer if
289 I plug it in before the camera. */
290
Hans Verkuil483d67f2010-05-10 03:51:02 -0300291static int qc_detect(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292{
293 int reg, lastreg;
294 int count = 0;
295 int i;
296
Brett T. Wardend685a482008-01-10 04:33:31 -0300297 if (force_init)
298 return 1;
299
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 lastreg = reg = read_lpstatus(q) & 0xf0;
301
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300302 for (i = 0; i < 500; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700303 reg = read_lpstatus(q) & 0xf0;
304 if (reg != lastreg)
305 count++;
306 lastreg = reg;
307 mdelay(2);
308 }
309
310
311#if 0
312 /* Force camera detection during testing. Sometimes the camera
313 won't be flashing these bits. Possibly unloading the module
314 in the middle of a grab? Or some timeout condition?
315 I've seen this parameter as low as 19 on my 450Mhz box - mpc */
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300316 printk(KERN_DEBUG "Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317 return 1;
318#endif
319
320 /* Be (even more) liberal in what you accept... */
321
Brett Warden7c596fa2007-10-02 17:37:21 -0300322 if (count > 20 && count < 400) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 return 1; /* found */
Brett Warden9e19db52007-09-28 03:19:04 -0300324 } else {
Brett Warden7c596fa2007-10-02 17:37:21 -0300325 printk(KERN_ERR "No Quickcam found on port %s\n",
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300326 q->pport->name);
Brett T. Wardend685a482008-01-10 04:33:31 -0300327 printk(KERN_DEBUG "Quickcam detection counter: %u\n", count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700328 return 0; /* not found */
Brett Warden9e19db52007-09-28 03:19:04 -0300329 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330}
331
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332/* Decide which scan mode to use. There's no real requirement that
333 * the scanmode match the resolution in q->height and q-> width -- the
334 * camera takes the picture at the resolution specified in the
335 * "scanmode" and then returns the image at the resolution specified
336 * with the resolution commands. If the scan is bigger than the
337 * requested resolution, the upper-left hand corner of the scan is
338 * returned. If the scan is smaller, then the rest of the image
339 * returned contains garbage. */
340
Hans Verkuil483d67f2010-05-10 03:51:02 -0300341static int qc_setscanmode(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342{
343 int old_mode = q->mode;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300344
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300345 switch (q->transfer_scale) {
346 case 1:
347 q->mode = 0;
348 break;
349 case 2:
350 q->mode = 4;
351 break;
352 case 4:
353 q->mode = 8;
354 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 }
356
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300357 switch (q->bpp) {
358 case 4:
359 break;
360 case 6:
361 q->mode += 2;
362 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 }
364
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300365 switch (q->port_mode & QC_MODE_MASK) {
366 case QC_BIDIR:
367 q->mode += 1;
368 break;
369 case QC_NOTSET:
370 case QC_UNIDIR:
371 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300373
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374 if (q->mode != old_mode)
375 q->status |= QC_PARAM_CHANGE;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300376
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 return 0;
378}
379
380
Hans Verkuil483d67f2010-05-10 03:51:02 -0300381/* Reset the QuickCam. This uses the same sequence the Windows
382 * QuickPic program uses. Someone with a bi-directional port should
383 * check that bi-directional mode is detected right, and then
384 * implement bi-directional mode in qc_readbyte(). */
385
386static void qc_reset(struct qcam *q)
387{
388 switch (q->port_mode & QC_FORCE_MASK) {
389 case QC_FORCE_UNIDIR:
390 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
391 break;
392
393 case QC_FORCE_BIDIR:
394 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
395 break;
396
397 case QC_ANY:
398 write_lpcontrol(q, 0x20);
399 write_lpdata(q, 0x75);
400
401 if (read_lpdata(q) != 0x75)
402 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR;
403 else
404 q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR;
405 break;
406 }
407
408 write_lpcontrol(q, 0xb);
409 udelay(250);
410 write_lpcontrol(q, 0xe);
411 qc_setscanmode(q); /* in case port_mode changed */
412}
413
414
415
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416/* Reset the QuickCam and program for brightness, contrast,
417 * white-balance, and resolution. */
418
Hans Verkuil483d67f2010-05-10 03:51:02 -0300419static void qc_set(struct qcam *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420{
421 int val;
422 int val2;
423
424 qc_reset(q);
425
426 /* Set the brightness. Yes, this is repetitive, but it works.
427 * Shorter versions seem to fail subtly. Feel free to try :-). */
428 /* I think the problem was in qc_command, not here -- bls */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300429
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430 qc_command(q, 0xb);
431 qc_command(q, q->brightness);
432
433 val = q->height / q->transfer_scale;
434 qc_command(q, 0x11);
435 qc_command(q, val);
436 if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) {
437 /* The normal "transfers per line" calculation doesn't seem to work
438 as expected here (and yet it works fine in qc_scan). No idea
439 why this case is the odd man out. Fortunately, Laird's original
440 working version gives me a good way to guess at working values.
441 -- bls */
442 val = q->width;
443 val2 = q->transfer_scale * 4;
444 } else {
445 val = q->width * q->bpp;
446 val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300447 q->transfer_scale;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 }
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300449 val = DIV_ROUND_UP(val, val2);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 qc_command(q, 0x13);
451 qc_command(q, val);
452
453 /* Setting top and left -- bls */
454 qc_command(q, 0xd);
455 qc_command(q, q->top);
456 qc_command(q, 0xf);
457 qc_command(q, q->left / 2);
458
459 qc_command(q, 0x19);
460 qc_command(q, q->contrast);
461 qc_command(q, 0x1f);
462 qc_command(q, q->whitebal);
463
464 /* Clear flag that we must update the grabbing parameters on the camera
465 before we grab the next frame */
466 q->status &= (~QC_PARAM_CHANGE);
467}
468
469/* Qc_readbytes reads some bytes from the QC and puts them in
470 the supplied buffer. It returns the number of bytes read,
471 or -1 on error. */
472
Hans Verkuil483d67f2010-05-10 03:51:02 -0300473static inline int qc_readbytes(struct qcam *q, char buffer[])
Linus Torvalds1da177e2005-04-16 15:20:36 -0700474{
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300475 int ret = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700476 unsigned int hi, lo;
477 unsigned int hi2, lo2;
Douglas Schilling Landgrafff699e62008-04-22 14:41:48 -0300478 static int state;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300480 if (buffer == NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 state = 0;
482 return 0;
483 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300484
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300485 switch (q->port_mode & QC_MODE_MASK) {
486 case QC_BIDIR: /* Bi-directional Port */
487 write_lpcontrol(q, 0x26);
488 lo = (qc_waithand2(q, 1) >> 1);
489 hi = (read_lpstatus(q) >> 3) & 0x1f;
490 write_lpcontrol(q, 0x2e);
491 lo2 = (qc_waithand2(q, 0) >> 1);
492 hi2 = (read_lpstatus(q) >> 3) & 0x1f;
493 switch (q->bpp) {
494 case 4:
495 buffer[0] = lo & 0xf;
496 buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3);
497 buffer[2] = (hi & 0x1e) >> 1;
498 buffer[3] = lo2 & 0xf;
499 buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3);
500 buffer[5] = (hi2 & 0x1e) >> 1;
501 ret = 6;
502 break;
503 case 6:
504 buffer[0] = lo & 0x3f;
505 buffer[1] = ((lo & 0x40) >> 6) | (hi << 1);
506 buffer[2] = lo2 & 0x3f;
507 buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1);
508 ret = 4;
509 break;
510 }
511 break;
512
513 case QC_UNIDIR: /* Unidirectional Port */
514 write_lpcontrol(q, 6);
515 lo = (qc_waithand(q, 1) & 0xf0) >> 4;
516 write_lpcontrol(q, 0xe);
517 hi = (qc_waithand(q, 0) & 0xf0) >> 4;
518
519 switch (q->bpp) {
520 case 4:
521 buffer[0] = lo;
522 buffer[1] = hi;
523 ret = 2;
524 break;
525 case 6:
526 switch (state) {
527 case 0:
528 buffer[0] = (lo << 2) | ((hi & 0xc) >> 2);
529 q->saved_bits = (hi & 3) << 4;
530 state = 1;
531 ret = 1;
532 break;
533 case 1:
534 buffer[0] = lo | q->saved_bits;
535 q->saved_bits = hi << 2;
536 state = 2;
537 ret = 1;
538 break;
539 case 2:
540 buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits;
541 buffer[1] = ((lo & 3) << 4) | hi;
542 state = 0;
543 ret = 2;
544 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 }
546 break;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300547 }
548 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549 }
550 return ret;
551}
552
553/* requests a scan from the camera. It sends the correct instructions
554 * to the camera and then reads back the correct number of bytes. In
555 * previous versions of this routine the return structure contained
556 * the raw output from the camera, and there was a 'qc_convertscan'
557 * function that converted that to a useful format. In version 0.3 I
558 * rolled qc_convertscan into qc_scan and now I only return the
559 * converted scan. The format is just an one-dimensional array of
560 * characters, one for each pixel, with 0=black up to n=white, where
561 * n=2^(bit depth)-1. Ask me for more details if you don't understand
562 * this. */
563
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300564static long qc_capture(struct qcam *q, u8 *buf, unsigned long len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565{
566 int i, j, k, yield;
567 int bytes;
568 int linestotrans, transperline;
569 int divisor;
570 int pixels_per_line;
571 int pixels_read = 0;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300572 int got = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573 char buffer[6];
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300574 int shift = 8 - q->bpp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575 char invert;
576
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300577 if (q->mode == -1)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578 return -ENXIO;
579
580 qc_command(q, 0x7);
581 qc_command(q, q->mode);
582
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300583 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 write_lpcontrol(q, 0x2e); /* turn port around */
585 write_lpcontrol(q, 0x26);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300586 qc_waithand(q, 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 write_lpcontrol(q, 0x2e);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300588 qc_waithand(q, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300590
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591 /* strange -- should be 15:63 below, but 4bpp is odd */
592 invert = (q->bpp == 4) ? 16 : 63;
593
594 linestotrans = q->height / q->transfer_scale;
595 pixels_per_line = q->width / q->transfer_scale;
596 transperline = q->width * q->bpp;
597 divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) *
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300598 q->transfer_scale;
Julia Lawalle9e24ce2008-08-20 20:44:53 -0300599 transperline = DIV_ROUND_UP(transperline, divisor);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300601 for (i = 0, yield = yieldlines; i < linestotrans; i++) {
602 for (pixels_read = j = 0; j < transperline; j++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 bytes = qc_readbytes(q, buffer);
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300604 for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 int o;
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300606 if (buffer[k] == 0 && invert == 16) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 /* 4bpp is odd (again) -- inverter is 16, not 15, but output
608 must be 0-15 -- bls */
609 buffer[k] = 16;
610 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300611 o = i * pixels_per_line + pixels_read + k;
612 if (o < len) {
Hans Verkuilde878972012-06-06 01:46:50 -0300613 u8 ch = invert - buffer[k];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700614 got++;
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300615 buf[o] = ch << shift;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700616 }
617 }
618 pixels_read += bytes;
619 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300620 qc_readbytes(q, NULL); /* reset state machine */
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300621
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 /* Grabbing an entire frame from the quickcam is a lengthy
623 process. We don't (usually) want to busy-block the
624 processor for the entire frame. yieldlines is a module
625 parameter. If we yield every line, the minimum frame
626 time will be 240 / 200 = 1.2 seconds. The compile-time
627 default is to yield every 4 lines. */
628 if (i >= yield) {
629 msleep_interruptible(5);
630 yield = i + yieldlines;
631 }
632 }
633
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300634 if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635 write_lpcontrol(q, 2);
636 write_lpcontrol(q, 6);
637 udelay(3);
638 write_lpcontrol(q, 0xe);
639 }
Hans Verkuil1d61aac2010-03-22 04:36:04 -0300640 if (got < len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 return got;
642 return len;
643}
644
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300645/* ------------------------------------------------------------------
646 Videobuf operations
647 ------------------------------------------------------------------*/
648static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
649 unsigned int *nbuffers, unsigned int *nplanes,
650 unsigned int sizes[], void *alloc_ctxs[])
651{
652 struct qcam *dev = vb2_get_drv_priv(vq);
653
654 if (0 == *nbuffers)
655 *nbuffers = 3;
656 *nplanes = 1;
657 mutex_lock(&dev->lock);
658 if (fmt)
659 sizes[0] = fmt->fmt.pix.width * fmt->fmt.pix.height;
660 else
661 sizes[0] = (dev->width / dev->transfer_scale) *
662 (dev->height / dev->transfer_scale);
663 mutex_unlock(&dev->lock);
664 return 0;
665}
666
667static void buffer_queue(struct vb2_buffer *vb)
668{
669 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
670}
671
672static int buffer_finish(struct vb2_buffer *vb)
673{
674 struct qcam *qcam = vb2_get_drv_priv(vb->vb2_queue);
675 void *vbuf = vb2_plane_vaddr(vb, 0);
676 int size = vb->vb2_queue->plane_sizes[0];
677 int len;
678
679 mutex_lock(&qcam->lock);
680 parport_claim_or_block(qcam->pdev);
681
682 qc_reset(qcam);
683
684 /* Update the camera parameters if we need to */
685 if (qcam->status & QC_PARAM_CHANGE)
686 qc_set(qcam);
687
688 len = qc_capture(qcam, vbuf, size);
689
690 parport_release(qcam->pdev);
691 mutex_unlock(&qcam->lock);
692 if (len != size)
693 vb->state = VB2_BUF_STATE_ERROR;
694 vb2_set_plane_payload(vb, 0, len);
695 return 0;
696}
697
698static struct vb2_ops qcam_video_qops = {
699 .queue_setup = queue_setup,
700 .buf_queue = buffer_queue,
701 .buf_finish = buffer_finish,
702 .wait_prepare = vb2_ops_wait_prepare,
703 .wait_finish = vb2_ops_wait_finish,
704};
705
Linus Torvalds1da177e2005-04-16 15:20:36 -0700706/*
707 * Video4linux interfacing
708 */
709
Hans Verkuil483d67f2010-05-10 03:51:02 -0300710static int qcam_querycap(struct file *file, void *priv,
711 struct v4l2_capability *vcap)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300713 struct qcam *qcam = video_drvdata(file);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -0300714
Hans Verkuil483d67f2010-05-10 03:51:02 -0300715 strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver));
Hans Verkuilde878972012-06-06 01:46:50 -0300716 strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card));
717 strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info));
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300718 vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE |
719 V4L2_CAP_STREAMING;
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300720 vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721 return 0;
722}
723
Hans Verkuil483d67f2010-05-10 03:51:02 -0300724static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700725{
Hans Verkuil483d67f2010-05-10 03:51:02 -0300726 if (vin->index > 0)
727 return -EINVAL;
728 strlcpy(vin->name, "Camera", sizeof(vin->name));
729 vin->type = V4L2_INPUT_TYPE_CAMERA;
730 vin->audioset = 0;
731 vin->tuner = 0;
732 vin->std = 0;
733 vin->status = 0;
734 return 0;
735}
736
737static int qcam_g_input(struct file *file, void *fh, unsigned int *inp)
738{
739 *inp = 0;
740 return 0;
741}
742
743static int qcam_s_input(struct file *file, void *fh, unsigned int inp)
744{
745 return (inp > 0) ? -EINVAL : 0;
746}
747
Hans Verkuil483d67f2010-05-10 03:51:02 -0300748static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
749{
750 struct qcam *qcam = video_drvdata(file);
751 struct v4l2_pix_format *pix = &fmt->fmt.pix;
752
753 pix->width = qcam->width / qcam->transfer_scale;
754 pix->height = qcam->height / qcam->transfer_scale;
755 pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6;
756 pix->field = V4L2_FIELD_NONE;
Hans Verkuilde878972012-06-06 01:46:50 -0300757 pix->bytesperline = pix->width;
758 pix->sizeimage = pix->width * pix->height;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300759 /* Just a guess */
760 pix->colorspace = V4L2_COLORSPACE_SRGB;
Hans Verkuil11d37932013-01-30 11:59:48 -0300761 pix->priv = 0;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300762 return 0;
763}
764
765static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
766{
767 struct v4l2_pix_format *pix = &fmt->fmt.pix;
768
769 if (pix->height <= 60 || pix->width <= 80) {
770 pix->height = 60;
771 pix->width = 80;
772 } else if (pix->height <= 120 || pix->width <= 160) {
773 pix->height = 120;
774 pix->width = 160;
775 } else {
776 pix->height = 240;
777 pix->width = 320;
778 }
779 if (pix->pixelformat != V4L2_PIX_FMT_Y4 &&
780 pix->pixelformat != V4L2_PIX_FMT_Y6)
781 pix->pixelformat = V4L2_PIX_FMT_Y4;
782 pix->field = V4L2_FIELD_NONE;
783 pix->bytesperline = pix->width;
784 pix->sizeimage = pix->width * pix->height;
785 /* Just a guess */
786 pix->colorspace = V4L2_COLORSPACE_SRGB;
Hans Verkuil11d37932013-01-30 11:59:48 -0300787 pix->priv = 0;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300788 return 0;
789}
790
791static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
792{
793 struct qcam *qcam = video_drvdata(file);
794 struct v4l2_pix_format *pix = &fmt->fmt.pix;
795 int ret = qcam_try_fmt_vid_cap(file, fh, fmt);
796
797 if (ret)
798 return ret;
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300799 if (vb2_is_busy(&qcam->vb_vidq))
800 return -EBUSY;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300801 qcam->width = 320;
802 qcam->height = 240;
803 if (pix->height == 60)
804 qcam->transfer_scale = 4;
805 else if (pix->height == 120)
806 qcam->transfer_scale = 2;
807 else
808 qcam->transfer_scale = 1;
809 if (pix->pixelformat == V4L2_PIX_FMT_Y6)
810 qcam->bpp = 6;
811 else
812 qcam->bpp = 4;
813
Hans Verkuil483d67f2010-05-10 03:51:02 -0300814 qc_setscanmode(qcam);
815 /* We must update the camera before we grab. We could
816 just have changed the grab size */
817 qcam->status |= QC_PARAM_CHANGE;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300818 return 0;
819}
820
821static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
822{
823 static struct v4l2_fmtdesc formats[] = {
824 { 0, 0, 0,
825 "4-Bit Monochrome", V4L2_PIX_FMT_Y4,
826 { 0, 0, 0, 0 }
827 },
Hans Verkuilde878972012-06-06 01:46:50 -0300828 { 1, 0, 0,
Hans Verkuil483d67f2010-05-10 03:51:02 -0300829 "6-Bit Monochrome", V4L2_PIX_FMT_Y6,
830 { 0, 0, 0, 0 }
831 },
832 };
833 enum v4l2_buf_type type = fmt->type;
834
835 if (fmt->index > 1)
836 return -EINVAL;
837
838 *fmt = formats[fmt->index];
839 fmt->type = type;
840 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841}
842
Hans Verkuilde878972012-06-06 01:46:50 -0300843static int qcam_enum_framesizes(struct file *file, void *fh,
844 struct v4l2_frmsizeenum *fsize)
845{
846 static const struct v4l2_frmsize_discrete sizes[] = {
847 { 80, 60 },
848 { 160, 120 },
849 { 320, 240 },
850 };
851
852 if (fsize->index > 2)
853 return -EINVAL;
854 if (fsize->pixel_format != V4L2_PIX_FMT_Y4 &&
855 fsize->pixel_format != V4L2_PIX_FMT_Y6)
856 return -EINVAL;
857 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
858 fsize->discrete = sizes[fsize->index];
859 return 0;
860}
861
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300862static int qcam_s_ctrl(struct v4l2_ctrl *ctrl)
863{
864 struct qcam *qcam =
865 container_of(ctrl->handler, struct qcam, hdl);
866 int ret = 0;
867
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300868 switch (ctrl->id) {
869 case V4L2_CID_BRIGHTNESS:
870 qcam->brightness = ctrl->val;
871 break;
872 case V4L2_CID_CONTRAST:
873 qcam->contrast = ctrl->val;
874 break;
875 case V4L2_CID_GAMMA:
876 qcam->whitebal = ctrl->val;
877 break;
878 default:
879 ret = -EINVAL;
880 break;
881 }
882 if (ret == 0) {
883 qc_setscanmode(qcam);
884 qcam->status |= QC_PARAM_CHANGE;
885 }
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300886 return ret;
887}
888
Hans Verkuilbec43662008-12-30 06:58:20 -0300889static const struct v4l2_file_operations qcam_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 .owner = THIS_MODULE,
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300891 .open = v4l2_fh_open,
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300892 .release = vb2_fop_release,
893 .poll = vb2_fop_poll,
Hans Verkuil61df3c92010-11-14 10:09:38 -0300894 .unlocked_ioctl = video_ioctl2,
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300895 .read = vb2_fop_read,
896 .mmap = vb2_fop_mmap,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897};
Hans Verkuil483d67f2010-05-10 03:51:02 -0300898
899static const struct v4l2_ioctl_ops qcam_ioctl_ops = {
900 .vidioc_querycap = qcam_querycap,
901 .vidioc_g_input = qcam_g_input,
902 .vidioc_s_input = qcam_s_input,
903 .vidioc_enum_input = qcam_enum_input,
Hans Verkuil483d67f2010-05-10 03:51:02 -0300904 .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap,
Hans Verkuilde878972012-06-06 01:46:50 -0300905 .vidioc_enum_framesizes = qcam_enum_framesizes,
Hans Verkuil483d67f2010-05-10 03:51:02 -0300906 .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap,
907 .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap,
908 .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap,
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300909 .vidioc_reqbufs = vb2_ioctl_reqbufs,
910 .vidioc_create_bufs = vb2_ioctl_create_bufs,
911 .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
912 .vidioc_querybuf = vb2_ioctl_querybuf,
913 .vidioc_qbuf = vb2_ioctl_qbuf,
914 .vidioc_dqbuf = vb2_ioctl_dqbuf,
915 .vidioc_streamon = vb2_ioctl_streamon,
916 .vidioc_streamoff = vb2_ioctl_streamoff,
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300917 .vidioc_log_status = v4l2_ctrl_log_status,
918 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
919 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
920};
921
922static const struct v4l2_ctrl_ops qcam_ctrl_ops = {
923 .s_ctrl = qcam_s_ctrl,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700924};
925
Hans Verkuil483d67f2010-05-10 03:51:02 -0300926/* Initialize the QuickCam driver control structure. This is where
927 * defaults are set for people who don't have a config file.*/
928
929static struct qcam *qcam_init(struct parport *port)
930{
931 struct qcam *qcam;
932 struct v4l2_device *v4l2_dev;
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300933 struct vb2_queue *q;
934 int err;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300935
936 qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL);
937 if (qcam == NULL)
938 return NULL;
939
940 v4l2_dev = &qcam->v4l2_dev;
Hans Verkuilde878972012-06-06 01:46:50 -0300941 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams);
Hans Verkuil483d67f2010-05-10 03:51:02 -0300942
Hans Verkuilde878972012-06-06 01:46:50 -0300943 if (v4l2_device_register(port->dev, v4l2_dev) < 0) {
Hans Verkuil483d67f2010-05-10 03:51:02 -0300944 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
Julia Lawallee893e92011-07-04 11:11:42 -0300945 kfree(qcam);
Hans Verkuil483d67f2010-05-10 03:51:02 -0300946 return NULL;
947 }
948
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300949 v4l2_ctrl_handler_init(&qcam->hdl, 3);
950 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
951 V4L2_CID_BRIGHTNESS, 0, 255, 1, 180);
952 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
953 V4L2_CID_CONTRAST, 0, 255, 1, 192);
954 v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops,
955 V4L2_CID_GAMMA, 0, 255, 1, 105);
956 if (qcam->hdl.error) {
957 v4l2_err(v4l2_dev, "couldn't register controls\n");
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300958 goto exit;
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300959 }
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300960
961 mutex_init(&qcam->lock);
962 mutex_init(&qcam->queue_lock);
963
964 /* initialize queue */
965 q = &qcam->vb_vidq;
966 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
967 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
968 q->drv_priv = qcam;
969 q->ops = &qcam_video_qops;
970 q->mem_ops = &vb2_vmalloc_memops;
971 err = vb2_queue_init(q);
972 if (err < 0) {
973 v4l2_err(v4l2_dev, "couldn't init vb2_queue for %s.\n", port->name);
974 goto exit;
975 }
976 qcam->vdev.queue = q;
977 qcam->vdev.queue->lock = &qcam->queue_lock;
978
Hans Verkuil483d67f2010-05-10 03:51:02 -0300979 qcam->pport = port;
Hans Verkuilde878972012-06-06 01:46:50 -0300980 qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL,
Hans Verkuil483d67f2010-05-10 03:51:02 -0300981 NULL, 0, NULL);
982 if (qcam->pdev == NULL) {
983 v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name);
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300984 goto exit;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300985 }
986
987 strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name));
988 qcam->vdev.v4l2_dev = v4l2_dev;
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300989 qcam->vdev.ctrl_handler = &qcam->hdl;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300990 qcam->vdev.fops = &qcam_fops;
Hans Verkuil1888e4a2013-01-30 14:10:14 -0300991 qcam->vdev.lock = &qcam->lock;
Hans Verkuil483d67f2010-05-10 03:51:02 -0300992 qcam->vdev.ioctl_ops = &qcam_ioctl_ops;
Hans Verkuil5fa1a892012-05-08 15:12:41 -0300993 set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags);
Hans Verkuil483d67f2010-05-10 03:51:02 -0300994 qcam->vdev.release = video_device_release_empty;
995 video_set_drvdata(&qcam->vdev, qcam);
996
Hans Verkuil483d67f2010-05-10 03:51:02 -0300997 qcam->port_mode = (QC_ANY | QC_NOTSET);
998 qcam->width = 320;
999 qcam->height = 240;
1000 qcam->bpp = 4;
1001 qcam->transfer_scale = 2;
1002 qcam->contrast = 192;
1003 qcam->brightness = 180;
1004 qcam->whitebal = 105;
1005 qcam->top = 1;
1006 qcam->left = 14;
1007 qcam->mode = -1;
1008 qcam->status = QC_PARAM_CHANGE;
1009 return qcam;
Hans Verkuil1888e4a2013-01-30 14:10:14 -03001010
1011exit:
1012 v4l2_ctrl_handler_free(&qcam->hdl);
1013 kfree(qcam);
1014 return NULL;
Hans Verkuil483d67f2010-05-10 03:51:02 -03001015}
1016
1017static int qc_calibrate(struct qcam *q)
1018{
1019 /*
1020 * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96
1021 * The white balance is an individual value for each
1022 * quickcam.
1023 */
1024
1025 int value;
1026 int count = 0;
1027
1028 qc_command(q, 27); /* AutoAdjustOffset */
1029 qc_command(q, 0); /* Dummy Parameter, ignored by the camera */
1030
1031 /* GetOffset (33) will read 255 until autocalibration */
1032 /* is finished. After that, a value of 1-254 will be */
1033 /* returned. */
1034
1035 do {
1036 qc_command(q, 33);
1037 value = qc_readparam(q);
1038 mdelay(1);
1039 schedule();
1040 count++;
1041 } while (value == 0xff && count < 2048);
1042
1043 q->whitebal = value;
1044 return value;
1045}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001046
1047static int init_bwqcam(struct parport *port)
1048{
Hans Verkuil483d67f2010-05-10 03:51:02 -03001049 struct qcam *qcam;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001051 if (num_cams == MAX_CAMS) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS);
1053 return -ENOSPC;
1054 }
1055
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001056 qcam = qcam_init(port);
1057 if (qcam == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 return -ENODEV;
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001059
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060 parport_claim_or_block(qcam->pdev);
1061
1062 qc_reset(qcam);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001063
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001064 if (qc_detect(qcam) == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001065 parport_release(qcam->pdev);
1066 parport_unregister_device(qcam->pdev);
1067 kfree(qcam);
1068 return -ENODEV;
1069 }
1070 qc_calibrate(qcam);
Hans Verkuilde878972012-06-06 01:46:50 -03001071 v4l2_ctrl_handler_setup(&qcam->hdl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072
1073 parport_release(qcam->pdev);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001074
Hans Verkuil483d67f2010-05-10 03:51:02 -03001075 v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name);
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001076
Hans Verkuildc60de32008-09-03 17:11:58 -03001077 if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 parport_unregister_device(qcam->pdev);
1079 kfree(qcam);
1080 return -ENODEV;
1081 }
1082
1083 qcams[num_cams++] = qcam;
1084
1085 return 0;
1086}
1087
Hans Verkuil483d67f2010-05-10 03:51:02 -03001088static void close_bwqcam(struct qcam *qcam)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089{
1090 video_unregister_device(&qcam->vdev);
Hans Verkuil5fa1a892012-05-08 15:12:41 -03001091 v4l2_ctrl_handler_free(&qcam->hdl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092 parport_unregister_device(qcam->pdev);
1093 kfree(qcam);
1094}
1095
1096/* The parport parameter controls which parports will be scanned.
1097 * Scanning all parports causes some printers to print a garbage page.
1098 * -- March 14, 1999 Billy Donahue <billy@escape.com> */
1099#ifdef MODULE
1100static char *parport[MAX_CAMS] = { NULL, };
1101module_param_array(parport, charp, NULL, 0);
1102#endif
1103
1104static int accept_bwqcam(struct parport *port)
1105{
1106#ifdef MODULE
1107 int n;
1108
1109 if (parport[0] && strncmp(parport[0], "auto", 4) != 0) {
1110 /* user gave parport parameters */
Roel Kluinbb2b4542009-08-10 22:07:54 -03001111 for (n = 0; n < MAX_CAMS && parport[n]; n++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 char *ep;
1113 unsigned long r;
1114 r = simple_strtoul(parport[n], &ep, 0);
1115 if (ep == parport[n]) {
1116 printk(KERN_ERR
1117 "bw-qcam: bad port specifier \"%s\"\n",
1118 parport[n]);
1119 continue;
1120 }
1121 if (r == port->number)
1122 return 1;
1123 }
1124 return 0;
1125 }
1126#endif
1127 return 1;
1128}
1129
1130static void bwqcam_attach(struct parport *port)
1131{
1132 if (accept_bwqcam(port))
1133 init_bwqcam(port);
1134}
1135
1136static void bwqcam_detach(struct parport *port)
1137{
1138 int i;
1139 for (i = 0; i < num_cams; i++) {
Hans Verkuil483d67f2010-05-10 03:51:02 -03001140 struct qcam *qcam = qcams[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 if (qcam && qcam->pdev->port == port) {
1142 qcams[i] = NULL;
1143 close_bwqcam(qcam);
1144 }
1145 }
1146}
1147
1148static struct parport_driver bwqcam_driver = {
1149 .name = "bw-qcam",
1150 .attach = bwqcam_attach,
1151 .detach = bwqcam_detach,
1152};
1153
1154static void __exit exit_bw_qcams(void)
1155{
1156 parport_unregister_driver(&bwqcam_driver);
1157}
1158
1159static int __init init_bw_qcams(void)
1160{
1161#ifdef MODULE
1162 /* Do some sanity checks on the module parameters. */
1163 if (maxpoll > 5000) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001164 printk(KERN_INFO "Connectix Quickcam max-poll was above 5000. Using 5000.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001165 maxpoll = 5000;
1166 }
Mauro Carvalho Chehabd56410e2006-03-25 09:19:53 -03001167
Linus Torvalds1da177e2005-04-16 15:20:36 -07001168 if (yieldlines < 1) {
Hans Verkuil1d61aac2010-03-22 04:36:04 -03001169 printk(KERN_INFO "Connectix Quickcam yieldlines was less than 1. Using 1.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001170 yieldlines = 1;
1171 }
1172#endif
1173 return parport_register_driver(&bwqcam_driver);
1174}
1175
1176module_init(init_bw_qcams);
1177module_exit(exit_bw_qcams);
1178
1179MODULE_LICENSE("GPL");
Mauro Carvalho Chehab1990d502011-06-24 14:45:49 -03001180MODULE_VERSION("0.0.3");