diff options
author | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
---|---|---|
committer | Jonathan Herman <hermanjl@cs.unc.edu> | 2013-01-22 10:38:37 -0500 |
commit | fcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch) | |
tree | a57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/media/video/bw-qcam.c | |
parent | 8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff) |
Diffstat (limited to 'drivers/media/video/bw-qcam.c')
-rw-r--r-- | drivers/media/video/bw-qcam.c | 1094 |
1 files changed, 1094 insertions, 0 deletions
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c new file mode 100644 index 00000000000..f09df9dffaa --- /dev/null +++ b/drivers/media/video/bw-qcam.c | |||
@@ -0,0 +1,1094 @@ | |||
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> | ||
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> | ||
74 | #include <linux/videodev2.h> | ||
75 | #include <linux/mutex.h> | ||
76 | #include <asm/uaccess.h> | ||
77 | #include <media/v4l2-common.h> | ||
78 | #include <media/v4l2-ioctl.h> | ||
79 | #include <media/v4l2-device.h> | ||
80 | |||
81 | /* One from column A... */ | ||
82 | #define QC_NOTSET 0 | ||
83 | #define QC_UNIDIR 1 | ||
84 | #define QC_BIDIR 2 | ||
85 | #define QC_SERIAL 3 | ||
86 | |||
87 | /* ... and one from column B */ | ||
88 | #define QC_ANY 0x00 | ||
89 | #define QC_FORCE_UNIDIR 0x10 | ||
90 | #define QC_FORCE_BIDIR 0x20 | ||
91 | #define QC_FORCE_SERIAL 0x30 | ||
92 | /* in the port_mode member */ | ||
93 | |||
94 | #define QC_MODE_MASK 0x07 | ||
95 | #define QC_FORCE_MASK 0x70 | ||
96 | |||
97 | #define MAX_HEIGHT 243 | ||
98 | #define MAX_WIDTH 336 | ||
99 | |||
100 | /* Bit fields for status flags */ | ||
101 | #define QC_PARAM_CHANGE 0x01 /* Camera status change has occurred */ | ||
102 | |||
103 | struct qcam { | ||
104 | struct v4l2_device v4l2_dev; | ||
105 | struct video_device vdev; | ||
106 | struct pardevice *pdev; | ||
107 | struct parport *pport; | ||
108 | struct mutex lock; | ||
109 | int width, height; | ||
110 | int bpp; | ||
111 | int mode; | ||
112 | int contrast, brightness, whitebal; | ||
113 | int port_mode; | ||
114 | int transfer_scale; | ||
115 | int top, left; | ||
116 | int status; | ||
117 | unsigned int saved_bits; | ||
118 | unsigned long in_use; | ||
119 | }; | ||
120 | |||
121 | static unsigned int maxpoll = 250; /* Maximum busy-loop count for qcam I/O */ | ||
122 | static unsigned int yieldlines = 4; /* Yield after this many during capture */ | ||
123 | static int video_nr = -1; | ||
124 | static unsigned int force_init; /* Whether to probe aggressively */ | ||
125 | |||
126 | module_param(maxpoll, int, 0); | ||
127 | module_param(yieldlines, int, 0); | ||
128 | module_param(video_nr, int, 0); | ||
129 | |||
130 | /* Set force_init=1 to avoid detection by polling status register and | ||
131 | * immediately attempt to initialize qcam */ | ||
132 | module_param(force_init, int, 0); | ||
133 | |||
134 | #define MAX_CAMS 4 | ||
135 | static struct qcam *qcams[MAX_CAMS]; | ||
136 | static unsigned int num_cams; | ||
137 | |||
138 | static inline int read_lpstatus(struct qcam *q) | ||
139 | { | ||
140 | return parport_read_status(q->pport); | ||
141 | } | ||
142 | |||
143 | static inline int read_lpdata(struct qcam *q) | ||
144 | { | ||
145 | return parport_read_data(q->pport); | ||
146 | } | ||
147 | |||
148 | static inline void write_lpdata(struct qcam *q, int d) | ||
149 | { | ||
150 | parport_write_data(q->pport, d); | ||
151 | } | ||
152 | |||
153 | static void write_lpcontrol(struct qcam *q, int d) | ||
154 | { | ||
155 | if (d & 0x20) { | ||
156 | /* Set bidirectional mode to reverse (data in) */ | ||
157 | parport_data_reverse(q->pport); | ||
158 | } else { | ||
159 | /* Set bidirectional mode to forward (data out) */ | ||
160 | parport_data_forward(q->pport); | ||
161 | } | ||
162 | |||
163 | /* Now issue the regular port command, but strip out the | ||
164 | * direction flag */ | ||
165 | d &= ~0x20; | ||
166 | parport_write_control(q->pport, d); | ||
167 | } | ||
168 | |||
169 | |||
170 | /* qc_waithand busy-waits for a handshake signal from the QuickCam. | ||
171 | * Almost all communication with the camera requires handshaking. */ | ||
172 | |||
173 | static int qc_waithand(struct qcam *q, int val) | ||
174 | { | ||
175 | int status; | ||
176 | int runs = 0; | ||
177 | |||
178 | if (val) { | ||
179 | while (!((status = read_lpstatus(q)) & 8)) { | ||
180 | /* 1000 is enough spins on the I/O for all normal | ||
181 | cases, at that point we start to poll slowly | ||
182 | until the camera wakes up. However, we are | ||
183 | busy blocked until the camera responds, so | ||
184 | setting it lower is much better for interactive | ||
185 | response. */ | ||
186 | |||
187 | if (runs++ > maxpoll) | ||
188 | msleep_interruptible(5); | ||
189 | if (runs > (maxpoll + 1000)) /* 5 seconds */ | ||
190 | return -1; | ||
191 | } | ||
192 | } else { | ||
193 | while (((status = read_lpstatus(q)) & 8)) { | ||
194 | /* 1000 is enough spins on the I/O for all normal | ||
195 | cases, at that point we start to poll slowly | ||
196 | until the camera wakes up. However, we are | ||
197 | busy blocked until the camera responds, so | ||
198 | setting it lower is much better for interactive | ||
199 | response. */ | ||
200 | |||
201 | if (runs++ > maxpoll) | ||
202 | msleep_interruptible(5); | ||
203 | if (runs++ > (maxpoll + 1000)) /* 5 seconds */ | ||
204 | return -1; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | return status; | ||
209 | } | ||
210 | |||
211 | /* Waithand2 is used when the qcam is in bidirectional mode, and the | ||
212 | * handshaking signal is CamRdy2 (bit 0 of data reg) instead of CamRdy1 | ||
213 | * (bit 3 of status register). It also returns the last value read, | ||
214 | * since this data is useful. */ | ||
215 | |||
216 | static unsigned int qc_waithand2(struct qcam *q, int val) | ||
217 | { | ||
218 | unsigned int status; | ||
219 | int runs = 0; | ||
220 | |||
221 | do { | ||
222 | status = read_lpdata(q); | ||
223 | /* 1000 is enough spins on the I/O for all normal | ||
224 | cases, at that point we start to poll slowly | ||
225 | until the camera wakes up. However, we are | ||
226 | busy blocked until the camera responds, so | ||
227 | setting it lower is much better for interactive | ||
228 | response. */ | ||
229 | |||
230 | if (runs++ > maxpoll) | ||
231 | msleep_interruptible(5); | ||
232 | if (runs++ > (maxpoll + 1000)) /* 5 seconds */ | ||
233 | return 0; | ||
234 | } while ((status & 1) != val); | ||
235 | |||
236 | return status; | ||
237 | } | ||
238 | |||
239 | /* qc_command is probably a bit of a misnomer -- it's used to send | ||
240 | * bytes *to* the camera. Generally, these bytes are either commands | ||
241 | * or arguments to commands, so the name fits, but it still bugs me a | ||
242 | * bit. See the documentation for a list of commands. */ | ||
243 | |||
244 | static int qc_command(struct qcam *q, int command) | ||
245 | { | ||
246 | int n1, n2; | ||
247 | int cmd; | ||
248 | |||
249 | write_lpdata(q, command); | ||
250 | write_lpcontrol(q, 6); | ||
251 | |||
252 | n1 = qc_waithand(q, 1); | ||
253 | |||
254 | write_lpcontrol(q, 0xe); | ||
255 | n2 = qc_waithand(q, 0); | ||
256 | |||
257 | cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); | ||
258 | return cmd; | ||
259 | } | ||
260 | |||
261 | static int qc_readparam(struct qcam *q) | ||
262 | { | ||
263 | int n1, n2; | ||
264 | int cmd; | ||
265 | |||
266 | write_lpcontrol(q, 6); | ||
267 | n1 = qc_waithand(q, 1); | ||
268 | |||
269 | write_lpcontrol(q, 0xe); | ||
270 | n2 = qc_waithand(q, 0); | ||
271 | |||
272 | cmd = (n1 & 0xf0) | ((n2 & 0xf0) >> 4); | ||
273 | return cmd; | ||
274 | } | ||
275 | |||
276 | |||
277 | /* Try to detect a QuickCam. It appears to flash the upper 4 bits of | ||
278 | the status register at 5-10 Hz. This is only used in the autoprobe | ||
279 | code. Be aware that this isn't the way Connectix detects the | ||
280 | camera (they send a reset and try to handshake), but this should be | ||
281 | almost completely safe, while their method screws up my printer if | ||
282 | I plug it in before the camera. */ | ||
283 | |||
284 | static int qc_detect(struct qcam *q) | ||
285 | { | ||
286 | int reg, lastreg; | ||
287 | int count = 0; | ||
288 | int i; | ||
289 | |||
290 | if (force_init) | ||
291 | return 1; | ||
292 | |||
293 | lastreg = reg = read_lpstatus(q) & 0xf0; | ||
294 | |||
295 | for (i = 0; i < 500; i++) { | ||
296 | reg = read_lpstatus(q) & 0xf0; | ||
297 | if (reg != lastreg) | ||
298 | count++; | ||
299 | lastreg = reg; | ||
300 | mdelay(2); | ||
301 | } | ||
302 | |||
303 | |||
304 | #if 0 | ||
305 | /* Force camera detection during testing. Sometimes the camera | ||
306 | won't be flashing these bits. Possibly unloading the module | ||
307 | in the middle of a grab? Or some timeout condition? | ||
308 | I've seen this parameter as low as 19 on my 450Mhz box - mpc */ | ||
309 | printk(KERN_DEBUG "Debugging: QCam detection counter <30-200 counts as detected>: %d\n", count); | ||
310 | return 1; | ||
311 | #endif | ||
312 | |||
313 | /* Be (even more) liberal in what you accept... */ | ||
314 | |||
315 | if (count > 20 && count < 400) { | ||
316 | return 1; /* found */ | ||
317 | } else { | ||
318 | printk(KERN_ERR "No Quickcam found on port %s\n", | ||
319 | q->pport->name); | ||
320 | printk(KERN_DEBUG "Quickcam detection counter: %u\n", count); | ||
321 | return 0; /* not found */ | ||
322 | } | ||
323 | } | ||
324 | |||
325 | /* Decide which scan mode to use. There's no real requirement that | ||
326 | * the scanmode match the resolution in q->height and q-> width -- the | ||
327 | * camera takes the picture at the resolution specified in the | ||
328 | * "scanmode" and then returns the image at the resolution specified | ||
329 | * with the resolution commands. If the scan is bigger than the | ||
330 | * requested resolution, the upper-left hand corner of the scan is | ||
331 | * returned. If the scan is smaller, then the rest of the image | ||
332 | * returned contains garbage. */ | ||
333 | |||
334 | static int qc_setscanmode(struct qcam *q) | ||
335 | { | ||
336 | int old_mode = q->mode; | ||
337 | |||
338 | switch (q->transfer_scale) { | ||
339 | case 1: | ||
340 | q->mode = 0; | ||
341 | break; | ||
342 | case 2: | ||
343 | q->mode = 4; | ||
344 | break; | ||
345 | case 4: | ||
346 | q->mode = 8; | ||
347 | break; | ||
348 | } | ||
349 | |||
350 | switch (q->bpp) { | ||
351 | case 4: | ||
352 | break; | ||
353 | case 6: | ||
354 | q->mode += 2; | ||
355 | break; | ||
356 | } | ||
357 | |||
358 | switch (q->port_mode & QC_MODE_MASK) { | ||
359 | case QC_BIDIR: | ||
360 | q->mode += 1; | ||
361 | break; | ||
362 | case QC_NOTSET: | ||
363 | case QC_UNIDIR: | ||
364 | break; | ||
365 | } | ||
366 | |||
367 | if (q->mode != old_mode) | ||
368 | q->status |= QC_PARAM_CHANGE; | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | |||
374 | /* Reset the QuickCam. This uses the same sequence the Windows | ||
375 | * QuickPic program uses. Someone with a bi-directional port should | ||
376 | * check that bi-directional mode is detected right, and then | ||
377 | * implement bi-directional mode in qc_readbyte(). */ | ||
378 | |||
379 | static void qc_reset(struct qcam *q) | ||
380 | { | ||
381 | switch (q->port_mode & QC_FORCE_MASK) { | ||
382 | case QC_FORCE_UNIDIR: | ||
383 | q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; | ||
384 | break; | ||
385 | |||
386 | case QC_FORCE_BIDIR: | ||
387 | q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; | ||
388 | break; | ||
389 | |||
390 | case QC_ANY: | ||
391 | write_lpcontrol(q, 0x20); | ||
392 | write_lpdata(q, 0x75); | ||
393 | |||
394 | if (read_lpdata(q) != 0x75) | ||
395 | q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_BIDIR; | ||
396 | else | ||
397 | q->port_mode = (q->port_mode & ~QC_MODE_MASK) | QC_UNIDIR; | ||
398 | break; | ||
399 | } | ||
400 | |||
401 | write_lpcontrol(q, 0xb); | ||
402 | udelay(250); | ||
403 | write_lpcontrol(q, 0xe); | ||
404 | qc_setscanmode(q); /* in case port_mode changed */ | ||
405 | } | ||
406 | |||
407 | |||
408 | |||
409 | /* Reset the QuickCam and program for brightness, contrast, | ||
410 | * white-balance, and resolution. */ | ||
411 | |||
412 | static void qc_set(struct qcam *q) | ||
413 | { | ||
414 | int val; | ||
415 | int val2; | ||
416 | |||
417 | qc_reset(q); | ||
418 | |||
419 | /* Set the brightness. Yes, this is repetitive, but it works. | ||
420 | * Shorter versions seem to fail subtly. Feel free to try :-). */ | ||
421 | /* I think the problem was in qc_command, not here -- bls */ | ||
422 | |||
423 | qc_command(q, 0xb); | ||
424 | qc_command(q, q->brightness); | ||
425 | |||
426 | val = q->height / q->transfer_scale; | ||
427 | qc_command(q, 0x11); | ||
428 | qc_command(q, val); | ||
429 | if ((q->port_mode & QC_MODE_MASK) == QC_UNIDIR && q->bpp == 6) { | ||
430 | /* The normal "transfers per line" calculation doesn't seem to work | ||
431 | as expected here (and yet it works fine in qc_scan). No idea | ||
432 | why this case is the odd man out. Fortunately, Laird's original | ||
433 | working version gives me a good way to guess at working values. | ||
434 | -- bls */ | ||
435 | val = q->width; | ||
436 | val2 = q->transfer_scale * 4; | ||
437 | } else { | ||
438 | val = q->width * q->bpp; | ||
439 | val2 = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * | ||
440 | q->transfer_scale; | ||
441 | } | ||
442 | val = DIV_ROUND_UP(val, val2); | ||
443 | qc_command(q, 0x13); | ||
444 | qc_command(q, val); | ||
445 | |||
446 | /* Setting top and left -- bls */ | ||
447 | qc_command(q, 0xd); | ||
448 | qc_command(q, q->top); | ||
449 | qc_command(q, 0xf); | ||
450 | qc_command(q, q->left / 2); | ||
451 | |||
452 | qc_command(q, 0x19); | ||
453 | qc_command(q, q->contrast); | ||
454 | qc_command(q, 0x1f); | ||
455 | qc_command(q, q->whitebal); | ||
456 | |||
457 | /* Clear flag that we must update the grabbing parameters on the camera | ||
458 | before we grab the next frame */ | ||
459 | q->status &= (~QC_PARAM_CHANGE); | ||
460 | } | ||
461 | |||
462 | /* Qc_readbytes reads some bytes from the QC and puts them in | ||
463 | the supplied buffer. It returns the number of bytes read, | ||
464 | or -1 on error. */ | ||
465 | |||
466 | static inline int qc_readbytes(struct qcam *q, char buffer[]) | ||
467 | { | ||
468 | int ret = 1; | ||
469 | unsigned int hi, lo; | ||
470 | unsigned int hi2, lo2; | ||
471 | static int state; | ||
472 | |||
473 | if (buffer == NULL) { | ||
474 | state = 0; | ||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | switch (q->port_mode & QC_MODE_MASK) { | ||
479 | case QC_BIDIR: /* Bi-directional Port */ | ||
480 | write_lpcontrol(q, 0x26); | ||
481 | lo = (qc_waithand2(q, 1) >> 1); | ||
482 | hi = (read_lpstatus(q) >> 3) & 0x1f; | ||
483 | write_lpcontrol(q, 0x2e); | ||
484 | lo2 = (qc_waithand2(q, 0) >> 1); | ||
485 | hi2 = (read_lpstatus(q) >> 3) & 0x1f; | ||
486 | switch (q->bpp) { | ||
487 | case 4: | ||
488 | buffer[0] = lo & 0xf; | ||
489 | buffer[1] = ((lo & 0x70) >> 4) | ((hi & 1) << 3); | ||
490 | buffer[2] = (hi & 0x1e) >> 1; | ||
491 | buffer[3] = lo2 & 0xf; | ||
492 | buffer[4] = ((lo2 & 0x70) >> 4) | ((hi2 & 1) << 3); | ||
493 | buffer[5] = (hi2 & 0x1e) >> 1; | ||
494 | ret = 6; | ||
495 | break; | ||
496 | case 6: | ||
497 | buffer[0] = lo & 0x3f; | ||
498 | buffer[1] = ((lo & 0x40) >> 6) | (hi << 1); | ||
499 | buffer[2] = lo2 & 0x3f; | ||
500 | buffer[3] = ((lo2 & 0x40) >> 6) | (hi2 << 1); | ||
501 | ret = 4; | ||
502 | break; | ||
503 | } | ||
504 | break; | ||
505 | |||
506 | case QC_UNIDIR: /* Unidirectional Port */ | ||
507 | write_lpcontrol(q, 6); | ||
508 | lo = (qc_waithand(q, 1) & 0xf0) >> 4; | ||
509 | write_lpcontrol(q, 0xe); | ||
510 | hi = (qc_waithand(q, 0) & 0xf0) >> 4; | ||
511 | |||
512 | switch (q->bpp) { | ||
513 | case 4: | ||
514 | buffer[0] = lo; | ||
515 | buffer[1] = hi; | ||
516 | ret = 2; | ||
517 | break; | ||
518 | case 6: | ||
519 | switch (state) { | ||
520 | case 0: | ||
521 | buffer[0] = (lo << 2) | ((hi & 0xc) >> 2); | ||
522 | q->saved_bits = (hi & 3) << 4; | ||
523 | state = 1; | ||
524 | ret = 1; | ||
525 | break; | ||
526 | case 1: | ||
527 | buffer[0] = lo | q->saved_bits; | ||
528 | q->saved_bits = hi << 2; | ||
529 | state = 2; | ||
530 | ret = 1; | ||
531 | break; | ||
532 | case 2: | ||
533 | buffer[0] = ((lo & 0xc) >> 2) | q->saved_bits; | ||
534 | buffer[1] = ((lo & 3) << 4) | hi; | ||
535 | state = 0; | ||
536 | ret = 2; | ||
537 | break; | ||
538 | } | ||
539 | break; | ||
540 | } | ||
541 | break; | ||
542 | } | ||
543 | return ret; | ||
544 | } | ||
545 | |||
546 | /* requests a scan from the camera. It sends the correct instructions | ||
547 | * to the camera and then reads back the correct number of bytes. In | ||
548 | * previous versions of this routine the return structure contained | ||
549 | * the raw output from the camera, and there was a 'qc_convertscan' | ||
550 | * function that converted that to a useful format. In version 0.3 I | ||
551 | * rolled qc_convertscan into qc_scan and now I only return the | ||
552 | * converted scan. The format is just an one-dimensional array of | ||
553 | * characters, one for each pixel, with 0=black up to n=white, where | ||
554 | * n=2^(bit depth)-1. Ask me for more details if you don't understand | ||
555 | * this. */ | ||
556 | |||
557 | static long qc_capture(struct qcam *q, char __user *buf, unsigned long len) | ||
558 | { | ||
559 | int i, j, k, yield; | ||
560 | int bytes; | ||
561 | int linestotrans, transperline; | ||
562 | int divisor; | ||
563 | int pixels_per_line; | ||
564 | int pixels_read = 0; | ||
565 | int got = 0; | ||
566 | char buffer[6]; | ||
567 | int shift = 8 - q->bpp; | ||
568 | char invert; | ||
569 | |||
570 | if (q->mode == -1) | ||
571 | return -ENXIO; | ||
572 | |||
573 | qc_command(q, 0x7); | ||
574 | qc_command(q, q->mode); | ||
575 | |||
576 | if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) { | ||
577 | write_lpcontrol(q, 0x2e); /* turn port around */ | ||
578 | write_lpcontrol(q, 0x26); | ||
579 | qc_waithand(q, 1); | ||
580 | write_lpcontrol(q, 0x2e); | ||
581 | qc_waithand(q, 0); | ||
582 | } | ||
583 | |||
584 | /* strange -- should be 15:63 below, but 4bpp is odd */ | ||
585 | invert = (q->bpp == 4) ? 16 : 63; | ||
586 | |||
587 | linestotrans = q->height / q->transfer_scale; | ||
588 | pixels_per_line = q->width / q->transfer_scale; | ||
589 | transperline = q->width * q->bpp; | ||
590 | divisor = (((q->port_mode & QC_MODE_MASK) == QC_BIDIR) ? 24 : 8) * | ||
591 | q->transfer_scale; | ||
592 | transperline = DIV_ROUND_UP(transperline, divisor); | ||
593 | |||
594 | for (i = 0, yield = yieldlines; i < linestotrans; i++) { | ||
595 | for (pixels_read = j = 0; j < transperline; j++) { | ||
596 | bytes = qc_readbytes(q, buffer); | ||
597 | for (k = 0; k < bytes && (pixels_read + k) < pixels_per_line; k++) { | ||
598 | int o; | ||
599 | if (buffer[k] == 0 && invert == 16) { | ||
600 | /* 4bpp is odd (again) -- inverter is 16, not 15, but output | ||
601 | must be 0-15 -- bls */ | ||
602 | buffer[k] = 16; | ||
603 | } | ||
604 | o = i * pixels_per_line + pixels_read + k; | ||
605 | if (o < len) { | ||
606 | got++; | ||
607 | put_user((invert - buffer[k]) << shift, buf + o); | ||
608 | } | ||
609 | } | ||
610 | pixels_read += bytes; | ||
611 | } | ||
612 | qc_readbytes(q, NULL); /* reset state machine */ | ||
613 | |||
614 | /* Grabbing an entire frame from the quickcam is a lengthy | ||
615 | process. We don't (usually) want to busy-block the | ||
616 | processor for the entire frame. yieldlines is a module | ||
617 | parameter. If we yield every line, the minimum frame | ||
618 | time will be 240 / 200 = 1.2 seconds. The compile-time | ||
619 | default is to yield every 4 lines. */ | ||
620 | if (i >= yield) { | ||
621 | msleep_interruptible(5); | ||
622 | yield = i + yieldlines; | ||
623 | } | ||
624 | } | ||
625 | |||
626 | if ((q->port_mode & QC_MODE_MASK) == QC_BIDIR) { | ||
627 | write_lpcontrol(q, 2); | ||
628 | write_lpcontrol(q, 6); | ||
629 | udelay(3); | ||
630 | write_lpcontrol(q, 0xe); | ||
631 | } | ||
632 | if (got < len) | ||
633 | return got; | ||
634 | return len; | ||
635 | } | ||
636 | |||
637 | /* | ||
638 | * Video4linux interfacing | ||
639 | */ | ||
640 | |||
641 | static int qcam_querycap(struct file *file, void *priv, | ||
642 | struct v4l2_capability *vcap) | ||
643 | { | ||
644 | struct qcam *qcam = video_drvdata(file); | ||
645 | |||
646 | strlcpy(vcap->driver, qcam->v4l2_dev.name, sizeof(vcap->driver)); | ||
647 | strlcpy(vcap->card, "B&W Quickcam", sizeof(vcap->card)); | ||
648 | strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info)); | ||
649 | vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE; | ||
650 | return 0; | ||
651 | } | ||
652 | |||
653 | static int qcam_enum_input(struct file *file, void *fh, struct v4l2_input *vin) | ||
654 | { | ||
655 | if (vin->index > 0) | ||
656 | return -EINVAL; | ||
657 | strlcpy(vin->name, "Camera", sizeof(vin->name)); | ||
658 | vin->type = V4L2_INPUT_TYPE_CAMERA; | ||
659 | vin->audioset = 0; | ||
660 | vin->tuner = 0; | ||
661 | vin->std = 0; | ||
662 | vin->status = 0; | ||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static int qcam_g_input(struct file *file, void *fh, unsigned int *inp) | ||
667 | { | ||
668 | *inp = 0; | ||
669 | return 0; | ||
670 | } | ||
671 | |||
672 | static int qcam_s_input(struct file *file, void *fh, unsigned int inp) | ||
673 | { | ||
674 | return (inp > 0) ? -EINVAL : 0; | ||
675 | } | ||
676 | |||
677 | static int qcam_queryctrl(struct file *file, void *priv, | ||
678 | struct v4l2_queryctrl *qc) | ||
679 | { | ||
680 | switch (qc->id) { | ||
681 | case V4L2_CID_BRIGHTNESS: | ||
682 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 180); | ||
683 | case V4L2_CID_CONTRAST: | ||
684 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 192); | ||
685 | case V4L2_CID_GAMMA: | ||
686 | return v4l2_ctrl_query_fill(qc, 0, 255, 1, 105); | ||
687 | } | ||
688 | return -EINVAL; | ||
689 | } | ||
690 | |||
691 | static int qcam_g_ctrl(struct file *file, void *priv, | ||
692 | struct v4l2_control *ctrl) | ||
693 | { | ||
694 | struct qcam *qcam = video_drvdata(file); | ||
695 | int ret = 0; | ||
696 | |||
697 | switch (ctrl->id) { | ||
698 | case V4L2_CID_BRIGHTNESS: | ||
699 | ctrl->value = qcam->brightness; | ||
700 | break; | ||
701 | case V4L2_CID_CONTRAST: | ||
702 | ctrl->value = qcam->contrast; | ||
703 | break; | ||
704 | case V4L2_CID_GAMMA: | ||
705 | ctrl->value = qcam->whitebal; | ||
706 | break; | ||
707 | default: | ||
708 | ret = -EINVAL; | ||
709 | break; | ||
710 | } | ||
711 | return ret; | ||
712 | } | ||
713 | |||
714 | static int qcam_s_ctrl(struct file *file, void *priv, | ||
715 | struct v4l2_control *ctrl) | ||
716 | { | ||
717 | struct qcam *qcam = video_drvdata(file); | ||
718 | int ret = 0; | ||
719 | |||
720 | mutex_lock(&qcam->lock); | ||
721 | switch (ctrl->id) { | ||
722 | case V4L2_CID_BRIGHTNESS: | ||
723 | qcam->brightness = ctrl->value; | ||
724 | break; | ||
725 | case V4L2_CID_CONTRAST: | ||
726 | qcam->contrast = ctrl->value; | ||
727 | break; | ||
728 | case V4L2_CID_GAMMA: | ||
729 | qcam->whitebal = ctrl->value; | ||
730 | break; | ||
731 | default: | ||
732 | ret = -EINVAL; | ||
733 | break; | ||
734 | } | ||
735 | if (ret == 0) { | ||
736 | qc_setscanmode(qcam); | ||
737 | qcam->status |= QC_PARAM_CHANGE; | ||
738 | } | ||
739 | mutex_unlock(&qcam->lock); | ||
740 | return ret; | ||
741 | } | ||
742 | |||
743 | static int qcam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
744 | { | ||
745 | struct qcam *qcam = video_drvdata(file); | ||
746 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
747 | |||
748 | pix->width = qcam->width / qcam->transfer_scale; | ||
749 | pix->height = qcam->height / qcam->transfer_scale; | ||
750 | pix->pixelformat = (qcam->bpp == 4) ? V4L2_PIX_FMT_Y4 : V4L2_PIX_FMT_Y6; | ||
751 | pix->field = V4L2_FIELD_NONE; | ||
752 | pix->bytesperline = qcam->width; | ||
753 | pix->sizeimage = qcam->width * qcam->height; | ||
754 | /* Just a guess */ | ||
755 | pix->colorspace = V4L2_COLORSPACE_SRGB; | ||
756 | return 0; | ||
757 | } | ||
758 | |||
759 | static int qcam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
760 | { | ||
761 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
762 | |||
763 | if (pix->height <= 60 || pix->width <= 80) { | ||
764 | pix->height = 60; | ||
765 | pix->width = 80; | ||
766 | } else if (pix->height <= 120 || pix->width <= 160) { | ||
767 | pix->height = 120; | ||
768 | pix->width = 160; | ||
769 | } else { | ||
770 | pix->height = 240; | ||
771 | pix->width = 320; | ||
772 | } | ||
773 | if (pix->pixelformat != V4L2_PIX_FMT_Y4 && | ||
774 | pix->pixelformat != V4L2_PIX_FMT_Y6) | ||
775 | pix->pixelformat = V4L2_PIX_FMT_Y4; | ||
776 | pix->field = V4L2_FIELD_NONE; | ||
777 | pix->bytesperline = pix->width; | ||
778 | pix->sizeimage = pix->width * pix->height; | ||
779 | /* Just a guess */ | ||
780 | pix->colorspace = V4L2_COLORSPACE_SRGB; | ||
781 | return 0; | ||
782 | } | ||
783 | |||
784 | static int qcam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) | ||
785 | { | ||
786 | struct qcam *qcam = video_drvdata(file); | ||
787 | struct v4l2_pix_format *pix = &fmt->fmt.pix; | ||
788 | int ret = qcam_try_fmt_vid_cap(file, fh, fmt); | ||
789 | |||
790 | if (ret) | ||
791 | return ret; | ||
792 | qcam->width = 320; | ||
793 | qcam->height = 240; | ||
794 | if (pix->height == 60) | ||
795 | qcam->transfer_scale = 4; | ||
796 | else if (pix->height == 120) | ||
797 | qcam->transfer_scale = 2; | ||
798 | else | ||
799 | qcam->transfer_scale = 1; | ||
800 | if (pix->pixelformat == V4L2_PIX_FMT_Y6) | ||
801 | qcam->bpp = 6; | ||
802 | else | ||
803 | qcam->bpp = 4; | ||
804 | |||
805 | mutex_lock(&qcam->lock); | ||
806 | qc_setscanmode(qcam); | ||
807 | /* We must update the camera before we grab. We could | ||
808 | just have changed the grab size */ | ||
809 | qcam->status |= QC_PARAM_CHANGE; | ||
810 | mutex_unlock(&qcam->lock); | ||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | static int qcam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) | ||
815 | { | ||
816 | static struct v4l2_fmtdesc formats[] = { | ||
817 | { 0, 0, 0, | ||
818 | "4-Bit Monochrome", V4L2_PIX_FMT_Y4, | ||
819 | { 0, 0, 0, 0 } | ||
820 | }, | ||
821 | { 0, 0, 0, | ||
822 | "6-Bit Monochrome", V4L2_PIX_FMT_Y6, | ||
823 | { 0, 0, 0, 0 } | ||
824 | }, | ||
825 | }; | ||
826 | enum v4l2_buf_type type = fmt->type; | ||
827 | |||
828 | if (fmt->index > 1) | ||
829 | return -EINVAL; | ||
830 | |||
831 | *fmt = formats[fmt->index]; | ||
832 | fmt->type = type; | ||
833 | return 0; | ||
834 | } | ||
835 | |||
836 | static ssize_t qcam_read(struct file *file, char __user *buf, | ||
837 | size_t count, loff_t *ppos) | ||
838 | { | ||
839 | struct qcam *qcam = video_drvdata(file); | ||
840 | int len; | ||
841 | parport_claim_or_block(qcam->pdev); | ||
842 | |||
843 | mutex_lock(&qcam->lock); | ||
844 | |||
845 | qc_reset(qcam); | ||
846 | |||
847 | /* Update the camera parameters if we need to */ | ||
848 | if (qcam->status & QC_PARAM_CHANGE) | ||
849 | qc_set(qcam); | ||
850 | |||
851 | len = qc_capture(qcam, buf, count); | ||
852 | |||
853 | mutex_unlock(&qcam->lock); | ||
854 | |||
855 | parport_release(qcam->pdev); | ||
856 | return len; | ||
857 | } | ||
858 | |||
859 | static const struct v4l2_file_operations qcam_fops = { | ||
860 | .owner = THIS_MODULE, | ||
861 | .unlocked_ioctl = video_ioctl2, | ||
862 | .read = qcam_read, | ||
863 | }; | ||
864 | |||
865 | static const struct v4l2_ioctl_ops qcam_ioctl_ops = { | ||
866 | .vidioc_querycap = qcam_querycap, | ||
867 | .vidioc_g_input = qcam_g_input, | ||
868 | .vidioc_s_input = qcam_s_input, | ||
869 | .vidioc_enum_input = qcam_enum_input, | ||
870 | .vidioc_queryctrl = qcam_queryctrl, | ||
871 | .vidioc_g_ctrl = qcam_g_ctrl, | ||
872 | .vidioc_s_ctrl = qcam_s_ctrl, | ||
873 | .vidioc_enum_fmt_vid_cap = qcam_enum_fmt_vid_cap, | ||
874 | .vidioc_g_fmt_vid_cap = qcam_g_fmt_vid_cap, | ||
875 | .vidioc_s_fmt_vid_cap = qcam_s_fmt_vid_cap, | ||
876 | .vidioc_try_fmt_vid_cap = qcam_try_fmt_vid_cap, | ||
877 | }; | ||
878 | |||
879 | /* Initialize the QuickCam driver control structure. This is where | ||
880 | * defaults are set for people who don't have a config file.*/ | ||
881 | |||
882 | static struct qcam *qcam_init(struct parport *port) | ||
883 | { | ||
884 | struct qcam *qcam; | ||
885 | struct v4l2_device *v4l2_dev; | ||
886 | |||
887 | qcam = kzalloc(sizeof(struct qcam), GFP_KERNEL); | ||
888 | if (qcam == NULL) | ||
889 | return NULL; | ||
890 | |||
891 | v4l2_dev = &qcam->v4l2_dev; | ||
892 | strlcpy(v4l2_dev->name, "bw-qcam", sizeof(v4l2_dev->name)); | ||
893 | |||
894 | if (v4l2_device_register(NULL, v4l2_dev) < 0) { | ||
895 | v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); | ||
896 | kfree(qcam); | ||
897 | return NULL; | ||
898 | } | ||
899 | |||
900 | qcam->pport = port; | ||
901 | qcam->pdev = parport_register_device(port, "bw-qcam", NULL, NULL, | ||
902 | NULL, 0, NULL); | ||
903 | if (qcam->pdev == NULL) { | ||
904 | v4l2_err(v4l2_dev, "couldn't register for %s.\n", port->name); | ||
905 | kfree(qcam); | ||
906 | return NULL; | ||
907 | } | ||
908 | |||
909 | strlcpy(qcam->vdev.name, "Connectix QuickCam", sizeof(qcam->vdev.name)); | ||
910 | qcam->vdev.v4l2_dev = v4l2_dev; | ||
911 | qcam->vdev.fops = &qcam_fops; | ||
912 | qcam->vdev.ioctl_ops = &qcam_ioctl_ops; | ||
913 | qcam->vdev.release = video_device_release_empty; | ||
914 | video_set_drvdata(&qcam->vdev, qcam); | ||
915 | |||
916 | mutex_init(&qcam->lock); | ||
917 | |||
918 | qcam->port_mode = (QC_ANY | QC_NOTSET); | ||
919 | qcam->width = 320; | ||
920 | qcam->height = 240; | ||
921 | qcam->bpp = 4; | ||
922 | qcam->transfer_scale = 2; | ||
923 | qcam->contrast = 192; | ||
924 | qcam->brightness = 180; | ||
925 | qcam->whitebal = 105; | ||
926 | qcam->top = 1; | ||
927 | qcam->left = 14; | ||
928 | qcam->mode = -1; | ||
929 | qcam->status = QC_PARAM_CHANGE; | ||
930 | return qcam; | ||
931 | } | ||
932 | |||
933 | static int qc_calibrate(struct qcam *q) | ||
934 | { | ||
935 | /* | ||
936 | * Bugfix by Hanno Mueller hmueller@kabel.de, Mai 21 96 | ||
937 | * The white balance is an individual value for each | ||
938 | * quickcam. | ||
939 | */ | ||
940 | |||
941 | int value; | ||
942 | int count = 0; | ||
943 | |||
944 | qc_command(q, 27); /* AutoAdjustOffset */ | ||
945 | qc_command(q, 0); /* Dummy Parameter, ignored by the camera */ | ||
946 | |||
947 | /* GetOffset (33) will read 255 until autocalibration */ | ||
948 | /* is finished. After that, a value of 1-254 will be */ | ||
949 | /* returned. */ | ||
950 | |||
951 | do { | ||
952 | qc_command(q, 33); | ||
953 | value = qc_readparam(q); | ||
954 | mdelay(1); | ||
955 | schedule(); | ||
956 | count++; | ||
957 | } while (value == 0xff && count < 2048); | ||
958 | |||
959 | q->whitebal = value; | ||
960 | return value; | ||
961 | } | ||
962 | |||
963 | static int init_bwqcam(struct parport *port) | ||
964 | { | ||
965 | struct qcam *qcam; | ||
966 | |||
967 | if (num_cams == MAX_CAMS) { | ||
968 | printk(KERN_ERR "Too many Quickcams (max %d)\n", MAX_CAMS); | ||
969 | return -ENOSPC; | ||
970 | } | ||
971 | |||
972 | qcam = qcam_init(port); | ||
973 | if (qcam == NULL) | ||
974 | return -ENODEV; | ||
975 | |||
976 | parport_claim_or_block(qcam->pdev); | ||
977 | |||
978 | qc_reset(qcam); | ||
979 | |||
980 | if (qc_detect(qcam) == 0) { | ||
981 | parport_release(qcam->pdev); | ||
982 | parport_unregister_device(qcam->pdev); | ||
983 | kfree(qcam); | ||
984 | return -ENODEV; | ||
985 | } | ||
986 | qc_calibrate(qcam); | ||
987 | |||
988 | parport_release(qcam->pdev); | ||
989 | |||
990 | v4l2_info(&qcam->v4l2_dev, "Connectix Quickcam on %s\n", qcam->pport->name); | ||
991 | |||
992 | if (video_register_device(&qcam->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { | ||
993 | parport_unregister_device(qcam->pdev); | ||
994 | kfree(qcam); | ||
995 | return -ENODEV; | ||
996 | } | ||
997 | |||
998 | qcams[num_cams++] = qcam; | ||
999 | |||
1000 | return 0; | ||
1001 | } | ||
1002 | |||
1003 | static void close_bwqcam(struct qcam *qcam) | ||
1004 | { | ||
1005 | video_unregister_device(&qcam->vdev); | ||
1006 | parport_unregister_device(qcam->pdev); | ||
1007 | kfree(qcam); | ||
1008 | } | ||
1009 | |||
1010 | /* The parport parameter controls which parports will be scanned. | ||
1011 | * Scanning all parports causes some printers to print a garbage page. | ||
1012 | * -- March 14, 1999 Billy Donahue <billy@escape.com> */ | ||
1013 | #ifdef MODULE | ||
1014 | static char *parport[MAX_CAMS] = { NULL, }; | ||
1015 | module_param_array(parport, charp, NULL, 0); | ||
1016 | #endif | ||
1017 | |||
1018 | static int accept_bwqcam(struct parport *port) | ||
1019 | { | ||
1020 | #ifdef MODULE | ||
1021 | int n; | ||
1022 | |||
1023 | if (parport[0] && strncmp(parport[0], "auto", 4) != 0) { | ||
1024 | /* user gave parport parameters */ | ||
1025 | for (n = 0; n < MAX_CAMS && parport[n]; n++) { | ||
1026 | char *ep; | ||
1027 | unsigned long r; | ||
1028 | r = simple_strtoul(parport[n], &ep, 0); | ||
1029 | if (ep == parport[n]) { | ||
1030 | printk(KERN_ERR | ||
1031 | "bw-qcam: bad port specifier \"%s\"\n", | ||
1032 | parport[n]); | ||
1033 | continue; | ||
1034 | } | ||
1035 | if (r == port->number) | ||
1036 | return 1; | ||
1037 | } | ||
1038 | return 0; | ||
1039 | } | ||
1040 | #endif | ||
1041 | return 1; | ||
1042 | } | ||
1043 | |||
1044 | static void bwqcam_attach(struct parport *port) | ||
1045 | { | ||
1046 | if (accept_bwqcam(port)) | ||
1047 | init_bwqcam(port); | ||
1048 | } | ||
1049 | |||
1050 | static void bwqcam_detach(struct parport *port) | ||
1051 | { | ||
1052 | int i; | ||
1053 | for (i = 0; i < num_cams; i++) { | ||
1054 | struct qcam *qcam = qcams[i]; | ||
1055 | if (qcam && qcam->pdev->port == port) { | ||
1056 | qcams[i] = NULL; | ||
1057 | close_bwqcam(qcam); | ||
1058 | } | ||
1059 | } | ||
1060 | } | ||
1061 | |||
1062 | static struct parport_driver bwqcam_driver = { | ||
1063 | .name = "bw-qcam", | ||
1064 | .attach = bwqcam_attach, | ||
1065 | .detach = bwqcam_detach, | ||
1066 | }; | ||
1067 | |||
1068 | static void __exit exit_bw_qcams(void) | ||
1069 | { | ||
1070 | parport_unregister_driver(&bwqcam_driver); | ||
1071 | } | ||
1072 | |||
1073 | static int __init init_bw_qcams(void) | ||
1074 | { | ||
1075 | #ifdef MODULE | ||
1076 | /* Do some sanity checks on the module parameters. */ | ||
1077 | if (maxpoll > 5000) { | ||
1078 | printk(KERN_INFO "Connectix Quickcam max-poll was above 5000. Using 5000.\n"); | ||
1079 | maxpoll = 5000; | ||
1080 | } | ||
1081 | |||
1082 | if (yieldlines < 1) { | ||
1083 | printk(KERN_INFO "Connectix Quickcam yieldlines was less than 1. Using 1.\n"); | ||
1084 | yieldlines = 1; | ||
1085 | } | ||
1086 | #endif | ||
1087 | return parport_register_driver(&bwqcam_driver); | ||
1088 | } | ||
1089 | |||
1090 | module_init(init_bw_qcams); | ||
1091 | module_exit(exit_bw_qcams); | ||
1092 | |||
1093 | MODULE_LICENSE("GPL"); | ||
1094 | MODULE_VERSION("0.0.3"); | ||