Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
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 | ||
42 | Copyright (C) 1996 by Scott Laird | |
43 | ||
44 | Permission is hereby granted, free of charge, to any person obtaining | |
45 | a copy of this software and associated documentation files (the | |
46 | "Software"), to deal in the Software without restriction, including | |
47 | without limitation the rights to use, copy, modify, merge, publish, | |
48 | distribute, sublicense, and/or sell copies of the Software, and to | |
49 | permit persons to whom the Software is furnished to do so, subject to | |
50 | the following conditions: | |
51 | ||
52 | The above copyright notice and this permission notice shall be | |
53 | included in all copies or substantial portions of the Software. | |
54 | ||
55 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
56 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
57 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
58 | IN NO EVENT SHALL SCOTT LAIRD BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
59 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
60 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
61 | OTHER 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> | |
1da177e4 LT |
69 | #include <linux/kernel.h> |
70 | #include <linux/slab.h> | |
71 | #include <linux/mm.h> | |
72 | #include <linux/parport.h> | |
73 | #include <linux/sched.h> | |
483d67ff | 74 | #include <linux/videodev2.h> |
3593cab5 | 75 | #include <linux/mutex.h> |
1da177e4 | 76 | #include <asm/uaccess.h> |
483d67ff HV |
77 | #include <media/v4l2-common.h> |
78 | #include <media/v4l2-ioctl.h> | |
79 | #include <media/v4l2-device.h> | |
5fa1a89d HV |
80 | #include <media/v4l2-fh.h> |
81 | #include <media/v4l2-ctrls.h> | |
82 | #include <media/v4l2-event.h> | |
1888e4a9 | 83 | #include <media/videobuf2-vmalloc.h> |
483d67ff HV |
84 | |
85 | /* 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 | ||
107 | struct qcam { | |
108 | struct v4l2_device v4l2_dev; | |
109 | struct video_device vdev; | |
5fa1a89d | 110 | struct v4l2_ctrl_handler hdl; |
1888e4a9 | 111 | struct vb2_queue vb_vidq; |
483d67ff HV |
112 | struct pardevice *pdev; |
113 | struct parport *pport; | |
114 | struct mutex lock; | |
1888e4a9 | 115 | struct mutex queue_lock; |
483d67ff HV |
116 | 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 | }; | |
1da177e4 | 127 | |
1d61aac0 HV |
128 | static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */ |
129 | static unsigned int yieldlines = 4; /* Yield after this many during capture */ | |
1da177e4 | 130 | static int video_nr = -1; |
d685a483 | 131 | static unsigned int force_init; /* Whether to probe aggressively */ |
1da177e4 LT |
132 | |
133 | module_param(maxpoll, int, 0); | |
134 | module_param(yieldlines, int, 0); | |
135 | module_param(video_nr, int, 0); | |
136 | ||
d685a483 BW |
137 | /* Set force_init=1 to avoid detection by polling status register and |
138 | * immediately attempt to initialize qcam */ | |
139 | module_param(force_init, int, 0); | |
140 | ||
483d67ff HV |
141 | #define MAX_CAMS 4 |
142 | static struct qcam *qcams[MAX_CAMS]; | |
143 | static unsigned int num_cams; | |
144 | ||
145 | static inline int read_lpstatus(struct qcam *q) | |
1da177e4 LT |
146 | { |
147 | return parport_read_status(q->pport); | |
148 | } | |
149 | ||
483d67ff | 150 | static inline int read_lpdata(struct qcam *q) |
1da177e4 LT |
151 | { |
152 | return parport_read_data(q->pport); | |
153 | } | |
154 | ||
483d67ff | 155 | static inline void write_lpdata(struct qcam *q, int d) |
1da177e4 LT |
156 | { |
157 | parport_write_data(q->pport, d); | |
158 | } | |
159 | ||
483d67ff | 160 | static void write_lpcontrol(struct qcam *q, int d) |
1da177e4 | 161 | { |
7c596fa9 | 162 | if (d & 0x20) { |
9e19db5b BW |
163 | /* 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; | |
1da177e4 LT |
173 | parport_write_control(q->pport, d); |
174 | } | |
175 | ||
1da177e4 LT |
176 | |
177 | /* qc_waithand busy-waits for a handshake signal from the QuickCam. | |
178 | * Almost all communication with the camera requires handshaking. */ | |
179 | ||
483d67ff | 180 | static int qc_waithand(struct qcam *q, int val) |
1da177e4 LT |
181 | { |
182 | int status; | |
1d61aac0 | 183 | int runs = 0; |
1da177e4 | 184 | |
1d61aac0 HV |
185 | if (val) { |
186 | while (!((status = read_lpstatus(q)) & 8)) { | |
1da177e4 | 187 | /* 1000 is enough spins on the I/O for all normal |
d56410e0 | 188 | cases, at that point we start to poll slowly |
1da177e4 LT |
189 | 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. */ | |
d56410e0 | 193 | |
1d61aac0 | 194 | if (runs++ > maxpoll) |
1da177e4 | 195 | msleep_interruptible(5); |
1d61aac0 | 196 | if (runs > (maxpoll + 1000)) /* 5 seconds */ |
1da177e4 LT |
197 | return -1; |
198 | } | |
1d61aac0 HV |
199 | } else { |
200 | while (((status = read_lpstatus(q)) & 8)) { | |
1da177e4 | 201 | /* 1000 is enough spins on the I/O for all normal |
d56410e0 | 202 | cases, at that point we start to poll slowly |
1da177e4 LT |
203 | 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. */ | |
d56410e0 | 207 | |
1d61aac0 | 208 | if (runs++ > maxpoll) |
1da177e4 | 209 | msleep_interruptible(5); |
1d61aac0 | 210 | if (runs++ > (maxpoll + 1000)) /* 5 seconds */ |
1da177e4 LT |
211 | 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 | ||
483d67ff | 223 | static unsigned int qc_waithand2(struct qcam *q, int val) |
1da177e4 LT |
224 | { |
225 | unsigned int status; | |
1d61aac0 | 226 | int runs = 0; |
d56410e0 | 227 | |
1d61aac0 | 228 | do { |
1da177e4 LT |
229 | status = read_lpdata(q); |
230 | /* 1000 is enough spins on the I/O for all normal | |
d56410e0 | 231 | cases, at that point we start to poll slowly |
1da177e4 LT |
232 | 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. */ | |
d56410e0 | 236 | |
1d61aac0 | 237 | if (runs++ > maxpoll) |
1da177e4 | 238 | msleep_interruptible(5); |
1d61aac0 | 239 | if (runs++ > (maxpoll + 1000)) /* 5 seconds */ |
1da177e4 | 240 | return 0; |
1d61aac0 | 241 | } while ((status & 1) != val); |
1da177e4 LT |
242 | |
243 | return status; | |
244 | } | |
245 | ||
483d67ff HV |
246 | /* 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 | ||
251 | static 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 | ||
268 | static 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 | ||
1da177e4 LT |
283 | |
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 | ||
483d67ff | 291 | static int qc_detect(struct qcam *q) |
1da177e4 LT |
292 | { |
293 | int reg, lastreg; | |
294 | int count = 0; | |
295 | int i; | |
296 | ||
d685a483 BW |
297 | if (force_init) |
298 | return 1; | |
299 | ||
1da177e4 LT |
300 | lastreg = reg = read_lpstatus(q) & 0xf0; |
301 | ||
1d61aac0 | 302 | for (i = 0; i < 500; i++) { |
1da177e4 LT |
303 | 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 */ | |
1d61aac0 | 316 | printk(KERN_DEBUG "Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count); |
1da177e4 LT |
317 | return 1; |
318 | #endif | |
319 | ||
320 | /* Be (even more) liberal in what you accept... */ | |
321 | ||
7c596fa9 | 322 | if (count > 20 && count < 400) { |
1da177e4 | 323 | return 1; /* found */ |
9e19db5b | 324 | } else { |
7c596fa9 | 325 | printk(KERN_ERR "No Quickcam found on port %s\n", |
1d61aac0 | 326 | q->pport->name); |
d685a483 | 327 | printk(KERN_DEBUG "Quickcam detection counter: %u\n", count); |
1da177e4 | 328 | return 0; /* not found */ |
9e19db5b | 329 | } |
1da177e4 LT |
330 | } |
331 | ||
1da177e4 LT |
332 | /* 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 | ||
483d67ff | 341 | static int qc_setscanmode(struct qcam *q) |
1da177e4 LT |
342 | { |
343 | int old_mode = q->mode; | |
d56410e0 | 344 | |
1d61aac0 HV |
345 | 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; | |
1da177e4 LT |
355 | } |
356 | ||
1d61aac0 HV |
357 | switch (q->bpp) { |
358 | case 4: | |
359 | break; | |
360 | case 6: | |
361 | q->mode += 2; | |
362 | break; | |
1da177e4 LT |
363 | } |
364 | ||
1d61aac0 HV |
365 | 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; | |
1da177e4 | 372 | } |
d56410e0 | 373 | |
1da177e4 LT |
374 | if (q->mode != old_mode) |
375 | q->status |= QC_PARAM_CHANGE; | |
d56410e0 | 376 | |
1da177e4 LT |
377 | return 0; |
378 | } | |
379 | ||
380 | ||
483d67ff HV |
381 | /* 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 | ||
386 | static 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 | ||
1da177e4 LT |
416 | /* Reset the QuickCam and program for brightness, contrast, |
417 | * white-balance, and resolution. */ | |
418 | ||
483d67ff | 419 | static void qc_set(struct qcam *q) |
1da177e4 LT |
420 | { |
421 | int val; | |
422 | int val2; | |
423 | ||
1da177e4 LT |
424 | /* Set the brightness. Yes, this is repetitive, but it works. |
425 | * Shorter versions seem to fail subtly. Feel free to try :-). */ | |
426 | /* I think the problem was in qc_command, not here -- bls */ | |
d56410e0 | 427 | |
1da177e4 LT |
428 | qc_command(q, 0xb); |
429 | qc_command(q, q->brightness); | |
430 | ||
431 | val = q->height / q->transfer_scale; | |
432 | qc_command(q, 0x11); | |
433 | qc_command(q, val); | |
434 | if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) { | |
435 | /* The normal "transfers per line" calculation doesn't seem to work | |
436 | as expected here (and yet it works fine in qc_scan). No idea | |
437 | why this case is the odd man out. Fortunately, Laird's original | |
438 | working version gives me a good way to guess at working values. | |
439 | -- bls */ | |
440 | val = q->width; | |
441 | val2 = q->transfer_scale * 4; | |
442 | } else { | |
443 | val = q->width * q->bpp; | |
444 | val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * | |
1d61aac0 | 445 | q->transfer_scale; |
1da177e4 | 446 | } |
e9e24cee | 447 | val = DIV_ROUND_UP(val, val2); |
1da177e4 LT |
448 | qc_command(q, 0x13); |
449 | qc_command(q, val); | |
450 | ||
451 | /* Setting top and left -- bls */ | |
452 | qc_command(q, 0xd); | |
453 | qc_command(q, q->top); | |
454 | qc_command(q, 0xf); | |
455 | qc_command(q, q->left / 2); | |
456 | ||
457 | qc_command(q, 0x19); | |
458 | qc_command(q, q->contrast); | |
459 | qc_command(q, 0x1f); | |
460 | qc_command(q, q->whitebal); | |
461 | ||
462 | /* Clear flag that we must update the grabbing parameters on the camera | |
463 | before we grab the next frame */ | |
464 | q->status &= (~QC_PARAM_CHANGE); | |
465 | } | |
466 | ||
467 | /* Qc_readbytes reads some bytes from the QC and puts them in | |
468 | the supplied buffer. It returns the number of bytes read, | |
469 | or -1 on error. */ | |
470 | ||
483d67ff | 471 | static inline int qc_readbytes(struct qcam *q, char buffer[]) |
1da177e4 | 472 | { |
1d61aac0 | 473 | int ret = 1; |
1da177e4 LT |
474 | unsigned int hi, lo; |
475 | unsigned int hi2, lo2; | |
ff699e6b | 476 | static int state; |
1da177e4 | 477 | |
1d61aac0 | 478 | if (buffer == NULL) { |
1da177e4 LT |
479 | state = 0; |
480 | return 0; | |
481 | } | |
d56410e0 | 482 | |
1d61aac0 HV |
483 | switch (q->port_mode & QC_MODE_MASK) { |
484 | case QC_BIDIR: /* Bi-directional Port */ | |
485 | write_lpcontrol(q, 0x26); | |
486 | lo = (qc_waithand2(q, 1) >> 1); | |
487 | hi = (read_lpstatus(q) >> 3) & 0x1f; | |
488 | write_lpcontrol(q, 0x2e); | |
489 | lo2 = (qc_waithand2(q, 0) >> 1); | |
490 | hi2 = (read_lpstatus(q) >> 3) & 0x1f; | |
491 | switch (q->bpp) { | |
492 | case 4: | |
493 | buffer[0] = lo & 0xf; | |
494 | buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3); | |
495 | buffer[2] = (hi & 0x1e) >> 1; | |
496 | buffer[3] = lo2 & 0xf; | |
497 | buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3); | |
498 | buffer[5] = (hi2 & 0x1e) >> 1; | |
499 | ret = 6; | |
500 | break; | |
501 | case 6: | |
502 | buffer[0] = lo & 0x3f; | |
503 | buffer[1] = ((lo & 0x40) >> 6) | (hi << 1); | |
504 | buffer[2] = lo2 & 0x3f; | |
505 | buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1); | |
506 | ret = 4; | |
1da177e4 | 507 | break; |
1d61aac0 HV |
508 | } |
509 | break; | |
510 | ||
511 | case QC_UNIDIR: /* Unidirectional Port */ | |
512 | write_lpcontrol(q, 6); | |
513 | lo = (qc_waithand(q, 1) & 0xf0) >> 4; | |
514 | write_lpcontrol(q, 0xe); | |
515 | hi = (qc_waithand(q, 0) & 0xf0) >> 4; | |
1da177e4 | 516 | |
1d61aac0 HV |
517 | switch (q->bpp) { |
518 | case 4: | |
519 | buffer[0] = lo; | |
520 | buffer[1] = hi; | |
521 | ret = 2; | |
522 | break; | |
523 | case 6: | |
524 | switch (state) { | |
525 | case 0: | |
526 | buffer[0] = (lo << 2) | ((hi & 0xc) >> 2); | |
527 | q->saved_bits = (hi & 3) << 4; | |
528 | state = 1; | |
529 | ret = 1; | |
530 | break; | |
531 | case 1: | |
532 | buffer[0] = lo | q->saved_bits; | |
533 | q->saved_bits = hi << 2; | |
534 | state = 2; | |
535 | ret = 1; | |
536 | break; | |
537 | case 2: | |
538 | buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits; | |
539 | buffer[1] = ((lo & 3) << 4) | hi; | |
540 | state = 0; | |
541 | ret = 2; | |
542 | break; | |
1da177e4 LT |
543 | } |
544 | break; | |
1d61aac0 HV |
545 | } |
546 | break; | |
1da177e4 LT |
547 | } |
548 | return ret; | |
549 | } | |
550 | ||
551 | /* requests a scan from the camera. It sends the correct instructions | |
552 | * to the camera and then reads back the correct number of bytes. In | |
553 | * previous versions of this routine the return structure contained | |
554 | * the raw output from the camera, and there was a 'qc_convertscan' | |
555 | * function that converted that to a useful format. In version 0.3 I | |
556 | * rolled qc_convertscan into qc_scan and now I only return the | |
557 | * converted scan. The format is just an one-dimensional array of | |
558 | * characters, one for each pixel, with 0=black up to n=white, where | |
559 | * n=2^(bit depth)-1. Ask me for more details if you don't understand | |
560 | * this. */ | |
561 | ||
1888e4a9 | 562 | static long qc_capture(struct qcam *q, u8 *buf, unsigned long len) |
1da177e4 LT |
563 | { |
564 | int i, j, k, yield; | |
565 | int bytes; | |
566 | int linestotrans, transperline; | |
567 | int divisor; | |
568 | int pixels_per_line; | |
569 | int pixels_read = 0; | |
1d61aac0 | 570 | int got = 0; |
1da177e4 | 571 | char buffer[6]; |
1d61aac0 | 572 | int shift = 8 - q->bpp; |
1da177e4 LT |
573 | char invert; |
574 | ||
d56410e0 | 575 | if (q->mode == -1) |
1da177e4 LT |
576 | return -ENXIO; |
577 | ||
578 | qc_command(q, 0x7); | |
579 | qc_command(q, q->mode); | |
580 | ||
1d61aac0 | 581 | if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) { |
1da177e4 LT |
582 | write_lpcontrol(q, 0x2e); /* turn port around */ |
583 | write_lpcontrol(q, 0x26); | |
1d61aac0 | 584 | qc_waithand(q, 1); |
1da177e4 | 585 | write_lpcontrol(q, 0x2e); |
1d61aac0 | 586 | qc_waithand(q, 0); |
1da177e4 | 587 | } |
d56410e0 | 588 | |
1da177e4 LT |
589 | /* strange -- should be 15:63 below, but 4bpp is odd */ |
590 | invert = (q->bpp == 4) ? 16 : 63; | |
591 | ||
592 | linestotrans = q->height / q->transfer_scale; | |
593 | pixels_per_line = q->width / q->transfer_scale; | |
594 | transperline = q->width * q->bpp; | |
595 | divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * | |
1d61aac0 | 596 | q->transfer_scale; |
e9e24cee | 597 | transperline = DIV_ROUND_UP(transperline, divisor); |
1da177e4 | 598 | |
1d61aac0 HV |
599 | for (i = 0, yield = yieldlines; i < linestotrans; i++) { |
600 | for (pixels_read = j = 0; j < transperline; j++) { | |
1da177e4 | 601 | bytes = qc_readbytes(q, buffer); |
1d61aac0 | 602 | for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) { |
1da177e4 | 603 | int o; |
1d61aac0 | 604 | if (buffer[k] == 0 && invert == 16) { |
1da177e4 LT |
605 | /* 4bpp is odd (again) -- inverter is 16, not 15, but output |
606 | must be 0-15 -- bls */ | |
607 | buffer[k] = 16; | |
608 | } | |
1d61aac0 HV |
609 | o = i * pixels_per_line + pixels_read + k; |
610 | if (o < len) { | |
de87897a | 611 | u8 ch = invert - buffer[k]; |
1da177e4 | 612 | got++; |
1888e4a9 | 613 | buf[o] = ch << shift; |
1da177e4 LT |
614 | } |
615 | } | |
616 | pixels_read += bytes; | |
617 | } | |
1d61aac0 | 618 | qc_readbytes(q, NULL); /* reset state machine */ |
d56410e0 | 619 | |
1da177e4 LT |
620 | /* Grabbing an entire frame from the quickcam is a lengthy |
621 | process. We don't (usually) want to busy-block the | |
622 | processor for the entire frame. yieldlines is a module | |
623 | parameter. If we yield every line, the minimum frame | |
624 | time will be 240 / 200 = 1.2 seconds. The compile-time | |
625 | default is to yield every 4 lines. */ | |
626 | if (i >= yield) { | |
627 | msleep_interruptible(5); | |
628 | yield = i + yieldlines; | |
629 | } | |
630 | } | |
631 | ||
1d61aac0 | 632 | if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) { |
1da177e4 LT |
633 | write_lpcontrol(q, 2); |
634 | write_lpcontrol(q, 6); | |
635 | udelay(3); | |
636 | write_lpcontrol(q, 0xe); | |
637 | } | |
1d61aac0 | 638 | if (got < len) |
1da177e4 LT |
639 | return got; |
640 | return len; | |
641 | } | |
642 | ||
1888e4a9 HV |
643 | /* ------------------------------------------------------------------ |
644 | Videobuf operations | |
645 | ------------------------------------------------------------------*/ | |
646 | static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, | |
647 | unsigned int *nbuffers, unsigned int *nplanes, | |
648 | unsigned int sizes[], void *alloc_ctxs[]) | |
649 | { | |
650 | struct qcam *dev = vb2_get_drv_priv(vq); | |
651 | ||
652 | if (0 == *nbuffers) | |
653 | *nbuffers = 3; | |
654 | *nplanes = 1; | |
655 | mutex_lock(&dev->lock); | |
656 | if (fmt) | |
657 | sizes[0] = fmt->fmt.pix.width * fmt->fmt.pix.height; | |
658 | else | |
659 | sizes[0] = (dev->width / dev->transfer_scale) * | |
660 | (dev->height / dev->transfer_scale); | |
661 | mutex_unlock(&dev->lock); | |
662 | return 0; | |
663 | } | |
664 | ||
665 | static void buffer_queue(struct vb2_buffer *vb) | |
666 | { | |
667 | vb2_buffer_done(vb, VB2_BUF_STATE_DONE); | |
668 | } | |
669 | ||
670 | static int buffer_finish(struct vb2_buffer *vb) | |
671 | { | |
672 | struct qcam *qcam = vb2_get_drv_priv(vb->vb2_queue); | |
673 | void *vbuf = vb2_plane_vaddr(vb, 0); | |
674 | int size = vb->vb2_queue->plane_sizes[0]; | |
675 | int len; | |
676 | ||
677 | mutex_lock(&qcam->lock); | |
678 | parport_claim_or_block(qcam->pdev); | |
679 | ||
680 | qc_reset(qcam); | |
681 | ||
682 | /* Update the camera parameters if we need to */ | |
683 | if (qcam->status & QC_PARAM_CHANGE) | |
684 | qc_set(qcam); | |
685 | ||
686 | len = qc_capture(qcam, vbuf, size); | |
687 | ||
688 | parport_release(qcam->pdev); | |
689 | mutex_unlock(&qcam->lock); | |
6266a9d9 | 690 | v4l2_get_timestamp(&vb->v4l2_buf.timestamp); |
1888e4a9 HV |
691 | if (len != size) |
692 | vb->state = VB2_BUF_STATE_ERROR; | |
693 | vb2_set_plane_payload(vb, 0, len); | |
694 | return 0; | |
695 | } | |
696 | ||
697 | static struct vb2_ops qcam_video_qops = { | |
698 | .queue_setup = queue_setup, | |
699 | .buf_queue = buffer_queue, | |
700 | .buf_finish = buffer_finish, | |
701 | .wait_prepare = vb2_ops_wait_prepare, | |
702 | .wait_finish = vb2_ops_wait_finish, | |
703 | }; | |
704 | ||
1da177e4 LT |
705 | /* |
706 | * Video4linux interfacing | |
707 | */ | |
708 | ||
483d67ff HV |
709 | static int qcam_querycap(struct file *file, void *priv, |
710 | struct v4l2_capability *vcap) | |
1da177e4 | 711 | { |
483d67ff | 712 | struct qcam *qcam = video_drvdata(file); |
1da177e4 | 713 | |
483d67ff | 714 | strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); |
de87897a HV |
715 | strlcpy(vcap->card, "Connectix B&W Quickcam", sizeof(vcap->card)); |
716 | strlcpy(vcap->bus_info, qcam->pport->name, sizeof(vcap->bus_info)); | |
1888e4a9 HV |
717 | vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | |
718 | V4L2_CAP_STREAMING; | |
5fa1a89d | 719 | vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS; |
483d67ff HV |
720 | return 0; |
721 | } | |
d56410e0 | 722 | |
483d67ff HV |
723 | static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin) |
724 | { | |
725 | if (vin->index > 0) | |
726 | return -EINVAL; | |
727 | strlcpy(vin->name, "Camera", sizeof(vin->name)); | |
728 | vin->type = V4L2_INPUT_TYPE_CAMERA; | |
729 | vin->audioset = 0; | |
730 | vin->tuner = 0; | |
731 | vin->std = 0; | |
732 | vin->status = 0; | |
733 | return 0; | |
734 | } | |
d56410e0 | 735 | |
483d67ff HV |
736 | static int qcam_g_input(struct file *file, void *fh, unsigned int *inp) |
737 | { | |
738 | *inp = 0; | |
739 | return 0; | |
740 | } | |
1d61aac0 | 741 | |
483d67ff HV |
742 | static int qcam_s_input(struct file *file, void *fh, unsigned int inp) |
743 | { | |
744 | return (inp > 0) ? -EINVAL : 0; | |
745 | } | |
746 | ||
483d67ff HV |
747 | static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) |
748 | { | |
749 | struct qcam *qcam = video_drvdata(file); | |
750 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
751 | ||
752 | pix->width = qcam->width / qcam->transfer_scale; | |
753 | pix->height = qcam->height / qcam->transfer_scale; | |
754 | pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6; | |
755 | pix->field = V4L2_FIELD_NONE; | |
de87897a HV |
756 | pix->bytesperline = pix->width; |
757 | pix->sizeimage = pix->width * pix->height; | |
483d67ff HV |
758 | /* Just a guess */ |
759 | pix->colorspace = V4L2_COLORSPACE_SRGB; | |
11d37939 | 760 | pix->priv = 0; |
483d67ff HV |
761 | return 0; |
762 | } | |
763 | ||
764 | static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | |
765 | { | |
766 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
767 | ||
768 | if (pix->height <= 60 || pix->width <= 80) { | |
769 | pix->height = 60; | |
770 | pix->width = 80; | |
771 | } else if (pix->height <= 120 || pix->width <= 160) { | |
772 | pix->height = 120; | |
773 | pix->width = 160; | |
774 | } else { | |
775 | pix->height = 240; | |
776 | pix->width = 320; | |
777 | } | |
778 | if (pix->pixelformat != V4L2_PIX_FMT_Y4 && | |
779 | pix->pixelformat != V4L2_PIX_FMT_Y6) | |
780 | pix->pixelformat = V4L2_PIX_FMT_Y4; | |
781 | pix->field = V4L2_FIELD_NONE; | |
782 | pix->bytesperline = pix->width; | |
783 | pix->sizeimage = pix->width * pix->height; | |
784 | /* Just a guess */ | |
785 | pix->colorspace = V4L2_COLORSPACE_SRGB; | |
11d37939 | 786 | pix->priv = 0; |
483d67ff HV |
787 | return 0; |
788 | } | |
789 | ||
790 | static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | |
791 | { | |
792 | struct qcam *qcam = video_drvdata(file); | |
793 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | |
794 | int ret = qcam_try_fmt_vid_cap(file, fh, fmt); | |
795 | ||
796 | if (ret) | |
797 | return ret; | |
1888e4a9 HV |
798 | if (vb2_is_busy(&qcam->vb_vidq)) |
799 | return -EBUSY; | |
483d67ff HV |
800 | qcam->width = 320; |
801 | qcam->height = 240; | |
802 | if (pix->height == 60) | |
803 | qcam->transfer_scale = 4; | |
804 | else if (pix->height == 120) | |
805 | qcam->transfer_scale = 2; | |
806 | else | |
807 | qcam->transfer_scale = 1; | |
808 | if (pix->pixelformat == V4L2_PIX_FMT_Y6) | |
809 | qcam->bpp = 6; | |
810 | else | |
811 | qcam->bpp = 4; | |
812 | ||
483d67ff HV |
813 | qc_setscanmode(qcam); |
814 | /* We must update the camera before we grab. We could | |
815 | just have changed the grab size */ | |
816 | qcam->status |= QC_PARAM_CHANGE; | |
1da177e4 LT |
817 | return 0; |
818 | } | |
819 | ||
483d67ff | 820 | static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) |
1da177e4 | 821 | { |
483d67ff HV |
822 | static struct v4l2_fmtdesc formats[] = { |
823 | { 0, 0, 0, | |
824 | "4-Bit Monochrome", V4L2_PIX_FMT_Y4, | |
825 | { 0, 0, 0, 0 } | |
826 | }, | |
de87897a | 827 | { 1, 0, 0, |
483d67ff HV |
828 | "6-Bit Monochrome", V4L2_PIX_FMT_Y6, |
829 | { 0, 0, 0, 0 } | |
830 | }, | |
831 | }; | |
832 | enum v4l2_buf_type type = fmt->type; | |
833 | ||
834 | if (fmt->index > 1) | |
835 | return -EINVAL; | |
836 | ||
837 | *fmt = formats[fmt->index]; | |
838 | fmt->type = type; | |
839 | return 0; | |
1da177e4 LT |
840 | } |
841 | ||
de87897a HV |
842 | static int qcam_enum_framesizes(struct file *file, void *fh, |
843 | struct v4l2_frmsizeenum *fsize) | |
844 | { | |
845 | static const struct v4l2_frmsize_discrete sizes[] = { | |
846 | { 80, 60 }, | |
847 | { 160, 120 }, | |
848 | { 320, 240 }, | |
849 | }; | |
850 | ||
851 | if (fsize->index > 2) | |
852 | return -EINVAL; | |
853 | if (fsize->pixel_format != V4L2_PIX_FMT_Y4 && | |
854 | fsize->pixel_format != V4L2_PIX_FMT_Y6) | |
855 | return -EINVAL; | |
856 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | |
857 | fsize->discrete = sizes[fsize->index]; | |
858 | return 0; | |
859 | } | |
860 | ||
5fa1a89d HV |
861 | static int qcam_s_ctrl(struct v4l2_ctrl *ctrl) |
862 | { | |
863 | struct qcam *qcam = | |
864 | container_of(ctrl->handler, struct qcam, hdl); | |
865 | int ret = 0; | |
866 | ||
5fa1a89d HV |
867 | switch (ctrl->id) { |
868 | case V4L2_CID_BRIGHTNESS: | |
869 | qcam->brightness = ctrl->val; | |
870 | break; | |
871 | case V4L2_CID_CONTRAST: | |
872 | qcam->contrast = ctrl->val; | |
873 | break; | |
874 | case V4L2_CID_GAMMA: | |
875 | qcam->whitebal = ctrl->val; | |
876 | break; | |
877 | default: | |
878 | ret = -EINVAL; | |
879 | break; | |
880 | } | |
971dfc67 | 881 | if (ret == 0) |
5fa1a89d | 882 | qcam->status |= QC_PARAM_CHANGE; |
5fa1a89d HV |
883 | return ret; |
884 | } | |
885 | ||
483d67ff HV |
886 | static const struct v4l2_file_operations qcam_fops = { |
887 | .owner = THIS_MODULE, | |
5fa1a89d | 888 | .open = v4l2_fh_open, |
1888e4a9 HV |
889 | .release = vb2_fop_release, |
890 | .poll = vb2_fop_poll, | |
61df3c9b | 891 | .unlocked_ioctl = video_ioctl2, |
1888e4a9 HV |
892 | .read = vb2_fop_read, |
893 | .mmap = vb2_fop_mmap, | |
483d67ff HV |
894 | }; |
895 | ||
896 | static const struct v4l2_ioctl_ops qcam_ioctl_ops = { | |
897 | .vidioc_querycap = qcam_querycap, | |
898 | .vidioc_g_input = qcam_g_input, | |
899 | .vidioc_s_input = qcam_s_input, | |
900 | .vidioc_enum_input = qcam_enum_input, | |
483d67ff | 901 | .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, |
de87897a | 902 | .vidioc_enum_framesizes = qcam_enum_framesizes, |
483d67ff HV |
903 | .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, |
904 | .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, | |
905 | .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, | |
1888e4a9 HV |
906 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
907 | .vidioc_create_bufs = vb2_ioctl_create_bufs, | |
908 | .vidioc_prepare_buf = vb2_ioctl_prepare_buf, | |
909 | .vidioc_querybuf = vb2_ioctl_querybuf, | |
910 | .vidioc_qbuf = vb2_ioctl_qbuf, | |
911 | .vidioc_dqbuf = vb2_ioctl_dqbuf, | |
912 | .vidioc_streamon = vb2_ioctl_streamon, | |
913 | .vidioc_streamoff = vb2_ioctl_streamoff, | |
5fa1a89d HV |
914 | .vidioc_log_status = v4l2_ctrl_log_status, |
915 | .vidioc_subscribe_event = v4l2_ctrl_subscribe_event, | |
916 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | |
917 | }; | |
918 | ||
919 | static const struct v4l2_ctrl_ops qcam_ctrl_ops = { | |
920 | .s_ctrl = qcam_s_ctrl, | |
483d67ff HV |
921 | }; |
922 | ||
923 | /* Initialize the QuickCam driver control structure. This is where | |
924 | * defaults are set for people who don't have a config file.*/ | |
925 | ||
926 | static struct qcam *qcam_init(struct parport *port) | |
7d43cd53 | 927 | { |
483d67ff HV |
928 | struct qcam *qcam; |
929 | struct v4l2_device *v4l2_dev; | |
1888e4a9 HV |
930 | struct vb2_queue *q; |
931 | int err; | |
483d67ff HV |
932 | |
933 | qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL); | |
934 | if (qcam == NULL) | |
935 | return NULL; | |
936 | ||
937 | v4l2_dev = &qcam->v4l2_dev; | |
de87897a | 938 | snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "bw-qcam%d", num_cams); |
7d43cd53 | 939 | |
de87897a | 940 | if (v4l2_device_register(port->dev, v4l2_dev) < 0) { |
483d67ff | 941 | v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); |
ee893e9a | 942 | kfree(qcam); |
483d67ff HV |
943 | return NULL; |
944 | } | |
945 | ||
5fa1a89d HV |
946 | v4l2_ctrl_handler_init(&qcam->hdl, 3); |
947 | v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops, | |
948 | V4L2_CID_BRIGHTNESS, 0, 255, 1, 180); | |
949 | v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops, | |
950 | V4L2_CID_CONTRAST, 0, 255, 1, 192); | |
951 | v4l2_ctrl_new_std(&qcam->hdl, &qcam_ctrl_ops, | |
952 | V4L2_CID_GAMMA, 0, 255, 1, 105); | |
953 | if (qcam->hdl.error) { | |
954 | v4l2_err(v4l2_dev, "couldn't register controls\n"); | |
1888e4a9 HV |
955 | goto exit; |
956 | } | |
957 | ||
958 | mutex_init(&qcam->lock); | |
959 | mutex_init(&qcam->queue_lock); | |
960 | ||
961 | /* initialize queue */ | |
962 | q = &qcam->vb_vidq; | |
963 | q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | |
964 | q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; | |
965 | q->drv_priv = qcam; | |
966 | q->ops = &qcam_video_qops; | |
967 | q->mem_ops = &vb2_vmalloc_memops; | |
ade48681 | 968 | q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
1888e4a9 HV |
969 | err = vb2_queue_init(q); |
970 | if (err < 0) { | |
971 | v4l2_err(v4l2_dev, "couldn't init vb2_queue for %s.\n", port->name); | |
972 | goto exit; | |
5fa1a89d | 973 | } |
1888e4a9 HV |
974 | qcam->vdev.queue = q; |
975 | qcam->vdev.queue->lock = &qcam->queue_lock; | |
976 | ||
483d67ff | 977 | qcam->pport = port; |
de87897a | 978 | qcam->pdev = parport_register_device(port, v4l2_dev->name, NULL, NULL, |
483d67ff HV |
979 | NULL, 0, NULL); |
980 | if (qcam->pdev == NULL) { | |
981 | v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); | |
1888e4a9 | 982 | goto exit; |
483d67ff HV |
983 | } |
984 | ||
985 | strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name)); | |
986 | qcam->vdev.v4l2_dev = v4l2_dev; | |
5fa1a89d | 987 | qcam->vdev.ctrl_handler = &qcam->hdl; |
483d67ff | 988 | qcam->vdev.fops = &qcam_fops; |
1888e4a9 | 989 | qcam->vdev.lock = &qcam->lock; |
483d67ff | 990 | qcam->vdev.ioctl_ops = &qcam_ioctl_ops; |
5fa1a89d | 991 | set_bit(V4L2_FL_USE_FH_PRIO, &qcam->vdev.flags); |
483d67ff HV |
992 | qcam->vdev.release = video_device_release_empty; |
993 | video_set_drvdata(&qcam->vdev, qcam); | |
994 | ||
483d67ff HV |
995 | qcam->port_mode = (QC_ANY | QC_NOTSET); |
996 | qcam->width = 320; | |
997 | qcam->height = 240; | |
998 | qcam->bpp = 4; | |
999 | qcam->transfer_scale = 2; | |
1000 | qcam->contrast = 192; | |
1001 | qcam->brightness = 180; | |
1002 | qcam->whitebal = 105; | |
1003 | qcam->top = 1; | |
1004 | qcam->left = 14; | |
1005 | qcam->mode = -1; | |
1006 | qcam->status = QC_PARAM_CHANGE; | |
1007 | return qcam; | |
1888e4a9 HV |
1008 | |
1009 | exit: | |
1010 | v4l2_ctrl_handler_free(&qcam->hdl); | |
1011 | kfree(qcam); | |
1012 | return NULL; | |
7d43cd53 HV |
1013 | } |
1014 | ||
483d67ff | 1015 | static int qc_calibrate(struct qcam *q) |
7d43cd53 | 1016 | { |
483d67ff HV |
1017 | /* |
1018 | * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96 | |
1019 | * The white balance is an individual value for each | |
1020 | * quickcam. | |
1021 | */ | |
7d43cd53 | 1022 | |
483d67ff HV |
1023 | int value; |
1024 | int count = 0; | |
7d43cd53 | 1025 | |
483d67ff HV |
1026 | qc_command(q, 27); /* AutoAdjustOffset */ |
1027 | qc_command(q, 0); /* Dummy Parameter, ignored by the camera */ | |
1da177e4 | 1028 | |
483d67ff HV |
1029 | /* GetOffset (33) will read 255 until autocalibration */ |
1030 | /* is finished. After that, a value of 1-254 will be */ | |
1031 | /* returned. */ | |
1032 | ||
1033 | do { | |
1034 | qc_command(q, 33); | |
1035 | value = qc_readparam(q); | |
1036 | mdelay(1); | |
1037 | schedule(); | |
1038 | count++; | |
1039 | } while (value == 0xff && count < 2048); | |
1040 | ||
1041 | q->whitebal = value; | |
1042 | return value; | |
1043 | } | |
1da177e4 LT |
1044 | |
1045 | static int init_bwqcam(struct parport *port) | |
1046 | { | |
483d67ff | 1047 | struct qcam *qcam; |
1da177e4 | 1048 | |
1d61aac0 | 1049 | if (num_cams == MAX_CAMS) { |
1da177e4 LT |
1050 | printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS); |
1051 | return -ENOSPC; | |
1052 | } | |
1053 | ||
1d61aac0 HV |
1054 | qcam = qcam_init(port); |
1055 | if (qcam == NULL) | |
1da177e4 | 1056 | return -ENODEV; |
d56410e0 | 1057 | |
1da177e4 LT |
1058 | parport_claim_or_block(qcam->pdev); |
1059 | ||
1060 | qc_reset(qcam); | |
d56410e0 | 1061 | |
1d61aac0 | 1062 | if (qc_detect(qcam) == 0) { |
1da177e4 LT |
1063 | parport_release(qcam->pdev); |
1064 | parport_unregister_device(qcam->pdev); | |
1065 | kfree(qcam); | |
1066 | return -ENODEV; | |
1067 | } | |
1068 | qc_calibrate(qcam); | |
de87897a | 1069 | v4l2_ctrl_handler_setup(&qcam->hdl); |
1da177e4 LT |
1070 | |
1071 | parport_release(qcam->pdev); | |
d56410e0 | 1072 | |
483d67ff | 1073 | v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name); |
d56410e0 | 1074 | |
dc60de33 | 1075 | if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { |
1da177e4 LT |
1076 | parport_unregister_device(qcam->pdev); |
1077 | kfree(qcam); | |
1078 | return -ENODEV; | |
1079 | } | |
1080 | ||
1081 | qcams[num_cams++] = qcam; | |
1082 | ||
1083 | return 0; | |
1084 | } | |
1085 | ||
483d67ff | 1086 | static void close_bwqcam(struct qcam *qcam) |
1da177e4 LT |
1087 | { |
1088 | video_unregister_device(&qcam->vdev); | |
5fa1a89d | 1089 | v4l2_ctrl_handler_free(&qcam->hdl); |
1da177e4 LT |
1090 | parport_unregister_device(qcam->pdev); |
1091 | kfree(qcam); | |
1092 | } | |
1093 | ||
1094 | /* The parport parameter controls which parports will be scanned. | |
1095 | * Scanning all parports causes some printers to print a garbage page. | |
1096 | * -- March 14, 1999 Billy Donahue <billy@escape.com> */ | |
1097 | #ifdef MODULE | |
1098 | static char *parport[MAX_CAMS] = { NULL, }; | |
1099 | module_param_array(parport, charp, NULL, 0); | |
1100 | #endif | |
1101 | ||
1102 | static int accept_bwqcam(struct parport *port) | |
1103 | { | |
1104 | #ifdef MODULE | |
1105 | int n; | |
1106 | ||
1107 | if (parport[0] && strncmp(parport[0], "auto", 4) != 0) { | |
1108 | /* user gave parport parameters */ | |
bb2b4542 | 1109 | for (n = 0; n < MAX_CAMS && parport[n]; n++) { |
1da177e4 LT |
1110 | char *ep; |
1111 | unsigned long r; | |
1112 | r = simple_strtoul(parport[n], &ep, 0); | |
1113 | if (ep == parport[n]) { | |
1114 | printk(KERN_ERR | |
1115 | "bw-qcam: bad port specifier \"%s\"\n", | |
1116 | parport[n]); | |
1117 | continue; | |
1118 | } | |
1119 | if (r == port->number) | |
1120 | return 1; | |
1121 | } | |
1122 | return 0; | |
1123 | } | |
1124 | #endif | |
1125 | return 1; | |
1126 | } | |
1127 | ||
1128 | static void bwqcam_attach(struct parport *port) | |
1129 | { | |
1130 | if (accept_bwqcam(port)) | |
1131 | init_bwqcam(port); | |
1132 | } | |
1133 | ||
1134 | static void bwqcam_detach(struct parport *port) | |
1135 | { | |
1136 | int i; | |
1137 | for (i = 0; i < num_cams; i++) { | |
483d67ff | 1138 | struct qcam *qcam = qcams[i]; |
1da177e4 LT |
1139 | if (qcam && qcam->pdev->port == port) { |
1140 | qcams[i] = NULL; | |
1141 | close_bwqcam(qcam); | |
1142 | } | |
1143 | } | |
1144 | } | |
1145 | ||
1146 | static struct parport_driver bwqcam_driver = { | |
1147 | .name = "bw-qcam", | |
1148 | .attach = bwqcam_attach, | |
1149 | .detach = bwqcam_detach, | |
1150 | }; | |
1151 | ||
1152 | static void __exit exit_bw_qcams(void) | |
1153 | { | |
1154 | parport_unregister_driver(&bwqcam_driver); | |
1155 | } | |
1156 | ||
1157 | static int __init init_bw_qcams(void) | |
1158 | { | |
1159 | #ifdef MODULE | |
1160 | /* Do some sanity checks on the module parameters. */ | |
1161 | if (maxpoll > 5000) { | |
1d61aac0 | 1162 | printk(KERN_INFO "Connectix Quickcam max-poll was above 5000. Using 5000.\n"); |
1da177e4 LT |
1163 | maxpoll = 5000; |
1164 | } | |
d56410e0 | 1165 | |
1da177e4 | 1166 | if (yieldlines < 1) { |
1d61aac0 | 1167 | printk(KERN_INFO "Connectix Quickcam yieldlines was less than 1. Using 1.\n"); |
1da177e4 LT |
1168 | yieldlines = 1; |
1169 | } | |
1170 | #endif | |
1171 | return parport_register_driver(&bwqcam_driver); | |
1172 | } | |
1173 | ||
1174 | module_init(init_bw_qcams); | |
1175 | module_exit(exit_bw_qcams); | |
1176 | ||
1177 | MODULE_LICENSE("GPL"); | |
1990d50b | 1178 | MODULE_VERSION("0.0.3"); |