1 /*
2 Winbond w9966cf Webcam parport driver.
3
4 Copyright (C) 2001 Jakob Kemi <jakob.kemi@telia.com>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 /*
21 Supported devices:
22 * Lifeview Flycam Supra (Philips saa7111a chip)
23
24 * Mikrotek Eyestar2 (Sanyo lc99053 chip)
25 Very rudimentary support, total lack of ccd-control chip settings.
26 Only green video data and no image properties (brightness, etc..)
27 If anyone can parse the Japanese data-sheet for the Sanyo lc99053
28 chip, feel free to help.
29 <http://service.semic.sanyo.co.jp/semi/ds_pdf_j/LC99053.pdf>
30 Thanks to Steven Griffiths <steve@sgriff.com> and
31 James Murray <jsm@jsm-net.demon.co.uk> for testing.
32
33 Todo:
34 * Add a working EPP mode (Is this a parport or a w9966 issue?)
35 * Add proper probing. IEEE1284 probing of w9966 chips haven't
36 worked since parport drivers changed in 2.4.x.
37 * Probe for onboard SRAM, port directions etc. (possible?)
38
39 Changes:
40
41 Alan Cox: Removed RGB mode for kernel merge, added THIS_MODULE
42 and owner support for newer module locks
43 */
44
45 #include <linux/module.h>
46 #include <linux/init.h>
47 #include <linux/delay.h>
48 #include <linux/videodev.h>
49 #include <linux/parport.h>
50 #include <linux/types.h>
51 #include <linux/slab.h>
52
53 //#define DEBUG // Define for debug output.
54
55 #ifdef DEBUG
56 # define DPRINTF(f, a...) \
57 do { \
58 printk ("%s%s, %d (DEBUG) %s(): ", \
59 KERN_DEBUG, __FILE__, __LINE__, __func__); \
60 printk (f, ##a); \
61 } while (0)
62 # define DASSERT(x) \
63 do { \
64 if (!x) \
65 DPRINTF("Assertion failed at line %d.\n", __LINE__); \
66 } while (0)
67 #else
68 # define DPRINTF(f, a...) do {} while(0)
69 # define DASSERT(f, a...) do {} while(0)
70 #endif
71
72 /*
73 * Defines, simple typedefs etc.
74 */
75
76 #define W9966_DRIVERNAME "w9966cf"
77 #define W9966_MAXCAMS 4 // Maximum number of cameras
78 #define W9966_RBUFFER 8096 // Read buffer (must be an even number)
79
80 #define W9966_WND_MIN_W 2
81 #define W9966_WND_MIN_H 1
82
83 // Keep track of our current state
84 #define W9966_STATE_PDEV 0x01 // pdev registered
85 #define W9966_STATE_CLAIMED 0x02 // pdev claimed
86 #define W9966_STATE_VDEV 0x04 // vdev registered
87 #define W9966_STATE_BUFFER 0x08 // buffer allocated
88 #define W9966_STATE_DETECTED 0x10 // model identified
89
90 #define W9966_SAA7111_ID 0x24 // I2C device id
91
92 #define W9966_I2C_UDELAY 5
93 #define W9966_I2C_TIMEOUT 100
94 #define W9966_I2C_R_DATA 0x08
95 #define W9966_I2C_R_CLOCK 0x04
96 #define W9966_I2C_W_DATA 0x02
97 #define W9966_I2C_W_CLOCK 0x01
98
99 #define MAX(a, b) ((a > b) ? a : b)
100 #define MIN(a, b) ((a > b) ? b : a)
101
102 struct w9966_dev {
103 struct video_device vdev;
104 struct parport* pport;
105 struct pardevice* pdev;
106 int ppmode;
107
108 u8* buffer;
109 u8 dev_state;
110 u8 i2c_state;
111 u16 width;
112 u16 height;
113
114 // Image properties
115 u8 brightness;
116 s8 contrast;
117 s8 color;
118 s8 hue;
119
120 // Model specific:
121 const char* name;
122 u32 sramsize;
123 u8 sramid; // reg 0x0c, bank layout
124 u8 cmask; // reg 0x01, for polarity
125 u16 min_x, max_x; // Capture window limits
126 u16 min_y, max_y;
127 int (*image)(struct w9966_dev* cam);
128 };
129
130 /*
131 * Module properties
132 */
133
134 MODULE_AUTHOR("Jakob Kemi <jakob.kemi@telia.com>");
135 MODULE_DESCRIPTION("Winbond w9966cf webcam driver (Flycam Supra and others)");
136 MODULE_LICENSE("GPL");
137
138
139 static const char* pardev[] = {[0 ... W9966_MAXCAMS-1] = "auto"};
140 MODULE_PARM(pardev, "0-" __MODULE_STRING(W9966_MAXCAMS) "s");
141 MODULE_PARM_DESC(pardev,"\n\
142 <auto|name|none[,...]> Where to find cameras.\n\
143 auto = probe all parports for camera (default)\n\
144 name = name of parport (eg parport0)\n\
145 none = don't use this camera\n\
146 You can specify all cameras this way, for example:\n\
147 pardev=parport2,auto,none,parport0 would search for cam1 on parport2, search\n\
148 for cam2 on all parports, skip cam3 and search for cam4 on parport0");
149
150 static int parmode = 1;
151 MODULE_PARM(parmode, "i");
152 MODULE_PARM_DESC(parmode, "\n<0|1|2|3> transfer mode (0=auto, 1=ecp(default), 2=epp, 3=forced hw-ecp)");
153
154 static int video_nr[] = {[0 ... W9966_MAXCAMS-1] = -1};
155 MODULE_PARM(video_nr, "0-" __MODULE_STRING(W9966_MAXCAMS) "i");
156 MODULE_PARM_DESC(video_nr,"\n\
157 <-1|n[,...]> Specify V4L minor mode number.\n\
158 -1 = use next available (default)\n\
159 n = use minor number n (integer >= 0)\n\
160 You can specify all cameras this way, for example:\n\
161 video_nr=-1,2,-1 would assign minor number 2 for cam2 and use auto for cam1,\n\
162 cam3 and cam4");
163
164 /*
165 * Private data
166 */
167
168 static struct w9966_dev* w9966_cams;
169
170 /*
171 * Private function declarations
172 */
173
w9966_flag_set(struct w9966_dev * cam,int flag)174 static inline void w9966_flag_set(struct w9966_dev* cam, int flag) {
175 cam->dev_state |= flag;}
176
w9966_flag_clear(struct w9966_dev * cam,int flag)177 static inline void w9966_flag_clear(struct w9966_dev* cam, int flag) {
178 cam->dev_state &= ~flag;}
179
w9966_flag_test(struct w9966_dev * cam,int flag)180 static inline int w9966_flag_test(struct w9966_dev* cam, int flag) {
181 return (cam->dev_state & flag);}
182
183 static inline int w9966_pdev_claim(struct w9966_dev *vdev);
184 static inline void w9966_pdev_release(struct w9966_dev *vdev);
185
186 static int w9966_rreg(struct w9966_dev* cam, int reg);
187 static int w9966_wreg(struct w9966_dev* cam, int reg, int data);
188
189 static int w9966_init(struct w9966_dev* cam, struct parport* port, int vidnr);
190 static void w9966_term(struct w9966_dev* cam);
191 static int w9966_setup(struct w9966_dev* cam);
192 static int w9966_findlen(int near, int size, int maxlen);
193 static int w9966_calcscale(int size, int min, int max,
194 int* beg, int* end, u8* factor);
195 static int w9966_window(struct w9966_dev* cam, int x1, int y1,
196 int x2, int y2, int w, int h);
197
198 static int w9966_saa7111_init(struct w9966_dev* cam);
199 static int w9966_saa7111_image(struct w9966_dev* cam);
200 static int w9966_lc99053_init(struct w9966_dev* cam);
201 static int w9966_lc99053_image(struct w9966_dev* cam);
202
203 static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state);
204 static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state);
205 static inline int w9966_i2c_getsda(struct w9966_dev* cam);
206 static inline int w9966_i2c_getscl(struct w9966_dev* cam);
207 static int w9966_i2c_wbyte(struct w9966_dev* cam, int data);
208 static int w9966_i2c_rbyte(struct w9966_dev* cam);
209 static int w9966_i2c_rreg(struct w9966_dev* cam, int device, int reg);
210 static int w9966_i2c_wreg(struct w9966_dev* cam, int device, int reg, int data);
211
212 static int w9966_v4l_open(struct video_device *vdev, int mode);
213 static void w9966_v4l_close(struct video_device *vdev);
214 static int w9966_v4l_ioctl(struct video_device *vdev,
215 unsigned int cmd, void *arg);
216 static long w9966_v4l_read(struct video_device *vdev,
217 char *buf, unsigned long count, int noblock);
218
219 /*
220 * Private function definitions
221 */
222
223 // Claim parport for ourself
224 // 1 on success, else 0
w9966_pdev_claim(struct w9966_dev * cam)225 static inline int w9966_pdev_claim(struct w9966_dev* cam)
226 {
227 if (w9966_flag_test(cam, W9966_STATE_CLAIMED))
228 return 1;
229 if (parport_claim_or_block(cam->pdev) < 0)
230 return 0;
231 w9966_flag_set(cam, W9966_STATE_CLAIMED);
232 return 1;
233 }
234
235 // Release parport for others to use
w9966_pdev_release(struct w9966_dev * cam)236 static inline void w9966_pdev_release(struct w9966_dev* cam)
237 {
238 if (!w9966_flag_test(cam, W9966_STATE_CLAIMED))
239 return;
240 parport_release(cam->pdev);
241 w9966_flag_clear(cam, W9966_STATE_CLAIMED);
242 }
243
244 // Read register from w9966 interface-chip
245 // Expects a claimed pdev
246 // -1 on error, else register data (byte)
w9966_rreg(struct w9966_dev * cam,int reg)247 static int w9966_rreg(struct w9966_dev* cam, int reg)
248 {
249 // ECP, read, regtransfer, REG, REG, REG, REG, REG
250 const u8 addr = 0x80 | (reg & 0x1f);
251 u8 val;
252
253 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0 ||
254 parport_write(cam->pport, &addr, 1) != 1 ||
255 parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0 ||
256 parport_read(cam->pport, &val, 1) != 1)
257 return -1;
258
259 return val;
260 }
261
262 // Write register to w9966 interface-chip
263 // Expects a claimed pdev
264 // 1 on success, else 0
w9966_wreg(struct w9966_dev * cam,int reg,int data)265 static int w9966_wreg(struct w9966_dev* cam, int reg, int data)
266 {
267 // ECP, write, regtransfer, REG, REG, REG, REG, REG
268 const u8 addr = 0xc0 | (reg & 0x1f);
269 const u8 val = data;
270
271 if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0 ||
272 parport_write(cam->pport, &addr, 1) != 1 ||
273 parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0 ||
274 parport_write(cam->pport, &val, 1) != 1)
275 return 0;
276
277 return 1;
278 }
279
280 // Initialize camera device. Setup all internal flags, set a
281 // default video mode, setup ccd-chip, register v4l device etc..
282 // Also used for 'probing' of hardware.
283 // 1 on success, else 0
w9966_init(struct w9966_dev * cam,struct parport * port,int vidnr)284 static int w9966_init(struct w9966_dev* cam, struct parport* port, int vidnr)
285 {
286 if (cam->dev_state != 0)
287 return 0;
288
289 cam->pport = port;
290 cam->brightness = 128;
291 cam->contrast = 64;
292 cam->color = 64;
293 cam->hue = 0;
294
295 // Select requested transfer mode
296 switch(parmode)
297 {
298 default: // Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
299 case 0:
300 if (port->modes & PARPORT_MODE_ECP)
301 cam->ppmode = IEEE1284_MODE_ECP;
302 else if (port->modes & PARPORT_MODE_EPP)
303 cam->ppmode = IEEE1284_MODE_EPP;
304 else
305 cam->ppmode = IEEE1284_MODE_ECPSWE;
306 break;
307 case 1: // hw- or sw-ecp
308 if (port->modes & PARPORT_MODE_ECP)
309 cam->ppmode = IEEE1284_MODE_ECP;
310 else
311 cam->ppmode = IEEE1284_MODE_ECPSWE;
312 break;
313 case 2: // hw- or sw-epp
314 if (port->modes & PARPORT_MODE_EPP)
315 cam->ppmode = IEEE1284_MODE_EPP;
316 else
317 cam->ppmode = IEEE1284_MODE_EPPSWE;
318 break;
319 case 3: // hw-ecp
320 cam->ppmode = IEEE1284_MODE_ECP;
321 break;
322 }
323
324 // Tell the parport driver that we exists
325 cam->pdev = parport_register_device(
326 port, W9966_DRIVERNAME, NULL, NULL, NULL, 0, NULL);
327
328 if (cam->pdev == NULL) {
329 DPRINTF("parport_register_device() failed.\n");
330 return 0;
331 }
332 w9966_flag_set(cam, W9966_STATE_PDEV);
333
334 // Claim parport
335 if (!w9966_pdev_claim(cam)) {
336 DPRINTF("w9966_pdev_claim() failed.\n");
337 return 0;
338 }
339
340 // Perform initial w9966 setup
341 if (!w9966_setup(cam)) {
342 DPRINTF("w9966_setup() failed.\n");
343 return 0;
344 }
345
346 // Detect model
347 if (!w9966_saa7111_init(cam)) {
348 DPRINTF("w9966_saa7111_init() failed.\n");
349 return 0;
350 }
351 if (!w9966_lc99053_init(cam)) {
352 DPRINTF("w9966_lc99053_init() failed.\n");
353 return 0;
354 }
355 if (!w9966_flag_test(cam, W9966_STATE_DETECTED)) {
356 DPRINTF("Camera model not identified.\n");
357 return 0;
358 }
359
360 // Setup w9966 with a default capture mode (QCIF res.)
361 if (!w9966_window(cam, 0, 0, 1023, 1023, 176, 144)) {
362 DPRINTF("w9966_window() failed.\n");
363 return 0;
364 }
365 w9966_pdev_release(cam);
366
367 // Fill in the video_device struct and register us to v4l
368 memset(&cam->vdev, 0, sizeof(struct video_device));
369 strcpy(cam->vdev.name, W9966_DRIVERNAME);
370 cam->vdev.type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
371 cam->vdev.hardware = VID_HARDWARE_W9966;
372 cam->vdev.open = &w9966_v4l_open;
373 cam->vdev.close = &w9966_v4l_close;
374 cam->vdev.read = &w9966_v4l_read;
375 cam->vdev.ioctl = &w9966_v4l_ioctl;
376 cam->vdev.priv = (void*)cam;
377 cam->vdev.owner = THIS_MODULE;
378
379 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, vidnr) == -1) {
380 DPRINTF("video_register_device() failed (minor: %d).\n", vidnr);
381 return 0;
382 }
383 w9966_flag_set(cam, W9966_STATE_VDEV);
384
385 // All ok
386 printk("w9966: Found and initialized %s on %s.\n",
387 cam->name, cam->pport->name);
388 return 1;
389 }
390
391 // Terminate everything gracefully
w9966_term(struct w9966_dev * cam)392 static void w9966_term(struct w9966_dev* cam)
393 {
394 // Delete allocated buffer
395 if (w9966_flag_test(cam, W9966_STATE_BUFFER))
396 kfree(cam->buffer);
397
398 // Unregister from v4l
399 if (w9966_flag_test(cam, W9966_STATE_VDEV))
400 video_unregister_device(&cam->vdev);
401
402 // Terminate from IEEE1284 mode and unregister from parport
403 if (w9966_flag_test(cam, W9966_STATE_PDEV)) {
404 if (w9966_pdev_claim(cam))
405 parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
406
407 w9966_pdev_release(cam);
408 parport_unregister_device(cam->pdev);
409 }
410
411 cam->dev_state = 0x00;
412 }
413
414 // Do initial setup for the w9966 chip, init i2c bus, etc.
415 // this is generic for all models
416 // expects a claimed pdev
417 // 1 on success, else 0
w9966_setup(struct w9966_dev * cam)418 static int w9966_setup(struct w9966_dev* cam)
419 {
420 const u8 i2c = cam->i2c_state = W9966_I2C_W_DATA | W9966_I2C_W_CLOCK;
421 const u8 regs[] = {
422 0x40, // 0x13 - VEE control (raw 4:2:2)
423 0x00, 0x00, 0x00, // 0x14 - 0x16
424 0x00, // 0x17 - ???
425 i2c, // 0x18 - Serial bus
426 0xff, // 0x19 - I/O port direction control
427 0xff, // 0x1a - I/O port data register
428 0x10 // 0x1b - ???
429 };
430 int i;
431
432 DASSERT(w9966_flag_test(cam, W9966_STATE_CLAIMED));
433
434 // Reset (ECP-fifo & serial-bus)
435 if (!w9966_wreg(cam, 0x00, 0x03) ||
436 !w9966_wreg(cam, 0x00, 0x00))
437 return 0;
438
439 // Write regs to w9966cf chip
440 for (i = 0x13; i < 0x1c; i++)
441 if (!w9966_wreg(cam, i, regs[i-0x13]))
442 return 0;
443
444 return 1;
445 }
446
447 // Find a good length for capture window (used both for W and H)
448 // A bit ugly but pretty functional. The capture length
449 // have to match the downscale
w9966_findlen(int near,int size,int maxlen)450 static int w9966_findlen(int near, int size, int maxlen)
451 {
452 int bestlen = size;
453 int besterr = abs(near - bestlen);
454 int len;
455
456 for(len = size+1; len < maxlen; len++)
457 {
458 int err;
459 if ( ((64*size) %len) != 0)
460 continue;
461
462 err = abs(near - len);
463
464 // Only continue as long as we keep getting better values
465 if (err > besterr)
466 break;
467
468 besterr = err;
469 bestlen = len;
470 }
471
472 return bestlen;
473 }
474
475 // Modify capture window (if necessary)
476 // and calculate downscaling
477 // 1 on success, else 0
w9966_calcscale(int size,int min,int max,int * beg,int * end,u8 * factor)478 static int w9966_calcscale(int size, int min, int max, int* beg, int* end, u8* factor)
479 {
480 const int maxlen = max - min;
481 const int len = *end - *beg + 1;
482 const int newlen = w9966_findlen(len, size, maxlen);
483 const int err = newlen - len;
484
485 // Check for bad format
486 if (newlen > maxlen || newlen < size)
487 return 0;
488
489 // Set factor (6 bit fixed)
490 *factor = (64*size) / newlen;
491 if (*factor == 64)
492 *factor = 0x00; // downscale is disabled
493 else
494 *factor |= 0x80; // set downscale-enable bit
495
496 // Modify old beginning and end
497 *beg -= err / 2;
498 *end += err - (err / 2);
499
500 // Move window if outside borders
501 if (*beg < min) {
502 *end += min - *beg;
503 *beg += min - *beg;
504 }
505 if (*end > max) {
506 *beg -= *end - max;
507 *end -= *end - max;
508 }
509
510 return 1;
511 }
512
513 // Setup the w9966 capture window and also set SRAM settings
514 // expects a claimed pdev and detected camera model
515 // 1 on success, else 0
w9966_window(struct w9966_dev * cam,int x1,int y1,int x2,int y2,int w,int h)516 static int w9966_window(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h)
517 {
518 unsigned int enh_s, enh_e;
519 u8 scale_x, scale_y;
520 u8 regs[0x13];
521 int i;
522
523 // Modify width and height to match capture window and SRAM
524 w = MAX(W9966_WND_MIN_W, w);
525 h = MAX(W9966_WND_MIN_H, h);
526 w = MIN(cam->max_x - cam->min_x, w);
527 h = MIN(cam->max_y - cam->min_y, h);
528 w &= ~0x1;
529 if (w*h*2 > cam->sramsize)
530 h = cam->sramsize / (w*2);
531
532 cam->width = w;
533 cam->height = h;
534
535 enh_s = 0;
536 enh_e = w*h*2;
537
538 // Calculate downscaling
539 if (!w9966_calcscale(w, cam->min_x, cam->max_x, &x1, &x2, &scale_x) ||
540 !w9966_calcscale(h, cam->min_y, cam->max_y, &y1, &y2, &scale_y))
541 return 0;
542
543 DPRINTF("%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
544 w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80);
545
546 // Setup registers
547 regs[0x00] = 0x00; // Set normal operation
548 regs[0x01] = cam->cmask; // Capture mode
549 regs[0x02] = scale_y; // V-scaling
550 regs[0x03] = scale_x; // H-scaling
551
552 // Capture window
553 regs[0x04] = (x1 & 0x0ff); // X-start (8 low bits)
554 regs[0x05] = (x1 & 0x300)>>8; // X-start (2 high bits)
555 regs[0x06] = (y1 & 0x0ff); // Y-start (8 low bits)
556 regs[0x07] = (y1 & 0x300)>>8; // Y-start (2 high bits)
557 regs[0x08] = (x2 & 0x0ff); // X-end (8 low bits)
558 regs[0x09] = (x2 & 0x300)>>8; // X-end (2 high bits)
559 regs[0x0a] = (y2 & 0x0ff); // Y-end (8 low bits)
560
561 regs[0x0c] = cam->sramid; // SRAM layout
562
563 // Enhancement layer
564 regs[0x0d] = (enh_s& 0x000ff); // Enh. start (0-7)
565 regs[0x0e] = (enh_s& 0x0ff00)>>8; // Enh. start (8-15)
566 regs[0x0f] = (enh_s& 0x70000)>>16; // Enh. start (16-17/18??)
567 regs[0x10] = (enh_e& 0x000ff); // Enh. end (0-7)
568 regs[0x11] = (enh_e& 0x0ff00)>>8; // Enh. end (8-15)
569 regs[0x12] = (enh_e& 0x70000)>>16; // Enh. end (16-17/18??)
570
571 // Write regs to w9966cf chip
572 for (i = 0x01; i < 0x13; i++)
573 if (!w9966_wreg(cam, i, regs[i]))
574 return 0;
575
576 return 1;
577 }
578
579 // Detect and initialize saa7111 ccd-controller chip.
580 // expects a claimed parport
581 // expected to always return 1 unless error is _fatal_
582 // 1 on success, else 0
w9966_saa7111_init(struct w9966_dev * cam)583 static int w9966_saa7111_init(struct w9966_dev* cam)
584 {
585 // saa7111 regs 0x00 trough 0x12
586 const u8 regs[] = {
587 0x00, // not written
588 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00, 0x88, 0x10,
589 cam->brightness, // 0x0a
590 cam->contrast, // 0x0b
591 cam->color, // 0x0c
592 cam->hue, // 0x0d
593 0x01, 0x00, 0x48, 0x0c, 0x00,
594 };
595 int i;
596
597 if (w9966_flag_test(cam, W9966_STATE_DETECTED))
598 return 1;
599
600 // Write regs to saa7111 chip
601 for (i = 1; i < 0x13; i++)
602 if (!w9966_i2c_wreg(cam, W9966_SAA7111_ID, i, regs[i]))
603 return 1;
604
605 // Read back regs
606 for (i = 1; i < 0x13; i++)
607 if (w9966_i2c_rreg(cam, W9966_SAA7111_ID, i) != regs[i])
608 return 1;
609
610 // Fill in model specific data
611 cam->name = "Lifeview Flycam Supra";
612 cam->sramsize = 128 << 10; // 128 kib
613 cam->sramid = 0x02; // see w9966.pdf
614
615 cam->cmask = 0x18; // normal polarity
616 cam->min_x = 16; // empirically determined
617 cam->max_x = 705;
618 cam->min_y = 14;
619 cam->max_y = 253;
620 cam->image = &w9966_saa7111_image;
621
622 DPRINTF("Found and initialized a saa7111 chip.\n");
623 w9966_flag_set(cam, W9966_STATE_DETECTED);
624
625 return 1;
626 }
627
628 // Setup image properties (brightness, hue, etc.) for the saa7111 chip
629 // expects a claimed parport
630 // 1 on success, else 0
w9966_saa7111_image(struct w9966_dev * cam)631 static int w9966_saa7111_image(struct w9966_dev* cam)
632 {
633 if (!w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0a, cam->brightness) ||
634 !w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0b, cam->contrast) ||
635 !w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0c, cam->color) ||
636 !w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0d, cam->hue))
637 return 0;
638
639 return 1;
640 }
641
642 // Detect and initialize lc99053 ccd-controller chip.
643 // expects a claimed parport
644 // this is currently a hack, no detection is done, we just assume an Eyestar2
645 // 1 on success, else 0
w9966_lc99053_init(struct w9966_dev * cam)646 static int w9966_lc99053_init(struct w9966_dev* cam)
647 {
648 if (w9966_flag_test(cam, W9966_STATE_DETECTED))
649 return 1;
650
651 // Fill in model specific data
652 cam->name = "Microtek Eyestar2";
653 cam->sramsize = 128 << 10; // 128 kib
654 cam->sramid = 0x02; // w9966cf.pdf
655
656 cam->cmask = 0x10; // reverse polarity
657 cam->min_x = 16; // empirically determined
658 cam->max_x = 705;
659 cam->min_y = 14;
660 cam->max_y = 253;
661 cam->image = &w9966_lc99053_image;
662
663 DPRINTF("Found and initialized a lc99053 chip.\n");
664 w9966_flag_set(cam, W9966_STATE_DETECTED);
665
666 return 1;
667 }
668
669 // Setup image properties (brightness, hue, etc.) for the lc99053 chip
670 // expects a claimed parport
671 // 1 on success, else 0
w9966_lc99053_image(struct w9966_dev * cam)672 static int w9966_lc99053_image(struct w9966_dev* cam)
673 {
674 return 1;
675 }
676
677 /*
678 * Ugly and primitive i2c protocol functions
679 */
680
681 // Sets the data line on the i2c bus.
682 // Expects a claimed pdev.
w9966_i2c_setsda(struct w9966_dev * cam,int state)683 static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state)
684 {
685 if (state)
686 cam->i2c_state |= W9966_I2C_W_DATA;
687 else
688 cam->i2c_state &= ~W9966_I2C_W_DATA;
689
690 w9966_wreg(cam, 0x18, cam->i2c_state);
691 udelay(W9966_I2C_UDELAY);
692 }
693
694 // Get peripheral clock line
695 // Expects a claimed pdev.
w9966_i2c_getscl(struct w9966_dev * cam)696 static inline int w9966_i2c_getscl(struct w9966_dev* cam)
697 {
698 const u8 pins = w9966_rreg(cam, 0x18);
699 return ((pins & W9966_I2C_R_CLOCK) > 0);
700 }
701
702 // Sets the clock line on the i2c bus.
703 // Expects a claimed pdev.
704 // 1 on success, else 0
w9966_i2c_setscl(struct w9966_dev * cam,int state)705 static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state)
706 {
707 if (state)
708 cam->i2c_state |= W9966_I2C_W_CLOCK;
709 else
710 cam->i2c_state &= ~W9966_I2C_W_CLOCK;
711
712 w9966_wreg(cam, 0x18, cam->i2c_state);
713 udelay(W9966_I2C_UDELAY);
714
715 // when we go to high, we also expect the peripheral to ack.
716 if (state) {
717 const int timeout = jiffies + W9966_I2C_TIMEOUT;
718 while (!w9966_i2c_getscl(cam)) {
719 if (time_after(jiffies, timeout))
720 return 0;
721 }
722 }
723 return 1;
724 }
725
726 // Get peripheral data line
727 // Expects a claimed pdev.
w9966_i2c_getsda(struct w9966_dev * cam)728 static inline int w9966_i2c_getsda(struct w9966_dev* cam)
729 {
730 const u8 pins = w9966_rreg(cam, 0x18);
731 return ((pins & W9966_I2C_R_DATA) > 0);
732 }
733
734 // Write a byte with ack to the i2c bus.
735 // Expects a claimed pdev.
736 // 1 on success, else 0
w9966_i2c_wbyte(struct w9966_dev * cam,int data)737 static int w9966_i2c_wbyte(struct w9966_dev* cam, int data)
738 {
739 int i;
740 for (i = 7; i >= 0; i--) {
741 w9966_i2c_setsda(cam, (data >> i) & 0x01);
742
743 if (!w9966_i2c_setscl(cam, 1) ||
744 !w9966_i2c_setscl(cam, 0))
745 return 0;
746 }
747 w9966_i2c_setsda(cam, 1);
748
749 if (!w9966_i2c_setscl(cam, 1) ||
750 !w9966_i2c_setscl(cam, 0))
751 return 0;
752
753 return 1;
754 }
755
756 // Read a data byte with ack from the i2c-bus
757 // Expects a claimed pdev. -1 on error
w9966_i2c_rbyte(struct w9966_dev * cam)758 static int w9966_i2c_rbyte(struct w9966_dev* cam)
759 {
760 u8 data = 0x00;
761 int i;
762
763 w9966_i2c_setsda(cam, 1);
764
765 for (i = 0; i < 8; i++)
766 {
767 if (!w9966_i2c_setscl(cam, 1))
768 return -1;
769 data = data << 1;
770 if (w9966_i2c_getsda(cam))
771 data |= 0x01;
772
773 w9966_i2c_setscl(cam, 0);
774 }
775 return data;
776 }
777
778 // Read a register from the i2c device.
779 // Expects claimed pdev. -1 on error
w9966_i2c_rreg(struct w9966_dev * cam,int device,int reg)780 static int w9966_i2c_rreg(struct w9966_dev* cam, int device, int reg)
781 {
782 int data;
783
784 w9966_i2c_setsda(cam, 0);
785 w9966_i2c_setscl(cam, 0);
786
787 if (!w9966_i2c_wbyte(cam, device << 1) ||
788 !w9966_i2c_wbyte(cam, reg))
789 return -1;
790
791 w9966_i2c_setsda(cam, 1);
792 if (!w9966_i2c_setscl(cam, 1))
793 return -1;
794
795 w9966_i2c_setsda(cam, 0);
796 w9966_i2c_setscl(cam, 0);
797
798 if (!w9966_i2c_wbyte(cam, (device << 1) | 1) ||
799 (data = w9966_i2c_rbyte(cam)) == -1)
800 return -1;
801
802 w9966_i2c_setsda(cam, 0);
803
804 if (!w9966_i2c_setscl(cam, 1))
805 return -1;
806
807 w9966_i2c_setsda(cam, 1);
808
809 return data;
810 }
811
812 // Write a register to the i2c device.
813 // Expects claimed pdev.
814 // 1 on success, else 0
w9966_i2c_wreg(struct w9966_dev * cam,int device,int reg,int data)815 static int w9966_i2c_wreg(struct w9966_dev* cam, int device, int reg, int data)
816 {
817 w9966_i2c_setsda(cam, 0);
818 w9966_i2c_setscl(cam, 0);
819
820 if (!w9966_i2c_wbyte(cam, device << 1) ||
821 !w9966_i2c_wbyte(cam, reg) ||
822 !w9966_i2c_wbyte(cam, data))
823 return 0;
824
825 w9966_i2c_setsda(cam, 0);
826 if (!w9966_i2c_setscl(cam, 1))
827 return 0;
828
829 w9966_i2c_setsda(cam, 1);
830
831 return 1;
832 }
833
834 /*
835 * Video4linux interface
836 */
837
w9966_v4l_open(struct video_device * vdev,int flags)838 static int w9966_v4l_open(struct video_device *vdev, int flags)
839 {
840 struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
841
842 // Claim parport
843 if (!w9966_pdev_claim(cam)) {
844 DPRINTF("Unable to claim parport");
845 return -EFAULT;
846 }
847
848 // Allocate read buffer
849 cam->buffer = (u8*)kmalloc(W9966_RBUFFER, GFP_KERNEL);
850 if (cam->buffer == NULL) {
851 w9966_pdev_release(cam);
852 return -ENOMEM;
853 }
854 w9966_flag_set(cam, W9966_STATE_BUFFER);
855
856 return 0;
857 }
858
w9966_v4l_close(struct video_device * vdev)859 static void w9966_v4l_close(struct video_device *vdev)
860 {
861 struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
862
863 // Free read buffer
864 if (w9966_flag_test(cam, W9966_STATE_BUFFER)) {
865 kfree(cam->buffer);
866 w9966_flag_clear(cam, W9966_STATE_BUFFER);
867 }
868
869 // release parport
870 w9966_pdev_release(cam);
871 }
872
873 // expects a claimed parport
w9966_v4l_ioctl(struct video_device * vdev,unsigned int cmd,void * arg)874 static int w9966_v4l_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
875 {
876 struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
877
878 switch(cmd)
879 {
880 case VIDIOCGCAP:
881 {
882 struct video_capability vcap = {
883 W9966_DRIVERNAME, // name
884 VID_TYPE_CAPTURE | VID_TYPE_SCALES, // type
885 1, 0, // vid, aud channels
886 cam->max_x - cam->min_x,
887 cam->max_y - cam->min_y,
888 W9966_WND_MIN_W,
889 W9966_WND_MIN_H
890 };
891
892 if(copy_to_user(arg, &vcap, sizeof(vcap)) != 0)
893 return -EFAULT;
894
895 return 0;
896 }
897 case VIDIOCGCHAN:
898 {
899 struct video_channel vch;
900 if(copy_from_user(&vch, arg, sizeof(vch)) != 0)
901 return -EFAULT;
902
903 if(vch.channel != 0) // We only support one channel (#0)
904 return -EINVAL;
905
906 strcpy(vch.name, "CCD-input");
907 vch.flags = 0; // We have no tuner or audio
908 vch.tuners = 0;
909 vch.type = VIDEO_TYPE_CAMERA;
910 vch.norm = 0; // ???
911
912 if(copy_to_user(arg, &vch, sizeof(vch)) != 0)
913 return -EFAULT;
914
915 return 0;
916 }
917 case VIDIOCSCHAN:
918 {
919 struct video_channel vch;
920 if(copy_from_user(&vch, arg, sizeof(vch) ) != 0)
921 return -EFAULT;
922
923 if(vch.channel != 0)
924 return -EINVAL;
925
926 return 0;
927 }
928 case VIDIOCGTUNER:
929 {
930 struct video_tuner vtune;
931 if(copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
932 return -EFAULT;
933
934 if(vtune.tuner != 0)
935 return -EINVAL;
936
937 strcpy(vtune.name, "no tuner");
938 vtune.rangelow = 0;
939 vtune.rangehigh = 0;
940 vtune.flags = VIDEO_TUNER_NORM;
941 vtune.mode = VIDEO_MODE_AUTO;
942 vtune.signal = 0xffff;
943
944 if(copy_to_user(arg, &vtune, sizeof(vtune)) != 0)
945 return -EFAULT;
946
947 return 0;
948 }
949 case VIDIOCSTUNER:
950 {
951 struct video_tuner vtune;
952 if (copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
953 return -EFAULT;
954
955 if (vtune.tuner != 0)
956 return -EINVAL;
957
958 if (vtune.mode != VIDEO_MODE_AUTO)
959 return -EINVAL;
960
961 return 0;
962 }
963 case VIDIOCGPICT:
964 {
965 struct video_picture vpic = {
966 cam->brightness << 8, // brightness
967 (cam->hue + 128) << 8, // hue
968 cam->color << 9, // color
969 cam->contrast << 9, // contrast
970 0x8000, // whiteness
971 16, VIDEO_PALETTE_YUV422// bpp, palette format
972 };
973
974 if(copy_to_user(arg, &vpic, sizeof(vpic)) != 0)
975 return -EFAULT;
976
977 return 0;
978 }
979 case VIDIOCSPICT:
980 {
981 struct video_picture vpic;
982 if(copy_from_user(&vpic, arg, sizeof(vpic)) != 0)
983 return -EFAULT;
984
985 if (vpic.depth != 16 || vpic.palette != VIDEO_PALETTE_YUV422)
986 return -EINVAL;
987
988 cam->brightness = vpic.brightness >> 8;
989 cam->hue = (vpic.hue >> 8) - 128;
990 cam->color = vpic.colour >> 9;
991 cam->contrast = vpic.contrast >> 9;
992
993 if (!cam->image(cam))
994 return -EFAULT;
995
996 return 0;
997 }
998 case VIDIOCSWIN:
999 {
1000 struct video_window vwin;
1001
1002 if (copy_from_user(&vwin, arg, sizeof(vwin)) != 0)
1003 return -EFAULT;
1004 if (
1005 vwin.flags != 0 ||
1006 vwin.clipcount != 0)
1007 return -EINVAL;
1008
1009 if (vwin.width > cam->max_x - cam->min_x ||
1010 vwin.height > cam->max_y - cam->min_y ||
1011 vwin.width < W9966_WND_MIN_W ||
1012 vwin.height < W9966_WND_MIN_H)
1013 return -EINVAL;
1014
1015 // Update camera regs
1016 if (!w9966_window(cam, 0, 0, 1023, 1023, vwin.width, vwin.height))
1017 return -EFAULT;
1018
1019 return 0;
1020 }
1021 case VIDIOCGWIN:
1022 {
1023 struct video_window vwin;
1024 memset(&vwin, 0, sizeof(vwin));
1025
1026 vwin.width = cam->width;
1027 vwin.height = cam->height;
1028
1029 if(copy_to_user(arg, &vwin, sizeof(vwin)) != 0)
1030 return -EFAULT;
1031
1032 return 0;
1033 }
1034 // Unimplemented
1035 case VIDIOCCAPTURE:
1036 case VIDIOCGFBUF:
1037 case VIDIOCSFBUF:
1038 case VIDIOCKEY:
1039 case VIDIOCGFREQ:
1040 case VIDIOCSFREQ:
1041 case VIDIOCGAUDIO:
1042 case VIDIOCSAUDIO:
1043 return -EINVAL;
1044 default:
1045 return -ENOIOCTLCMD;
1046 }
1047 return 0;
1048 }
1049
1050 // Capture data
1051 // expects a claimed parport and allocated read buffer
w9966_v4l_read(struct video_device * vdev,char * buf,unsigned long count,int noblock)1052 static long w9966_v4l_read(struct video_device *vdev, char *buf, unsigned long count, int noblock)
1053 {
1054 struct w9966_dev *cam = (struct w9966_dev *)vdev->priv;
1055 const u8 addr = 0xa0; // ECP, read, CCD-transfer, 00000
1056 u8* dest = (u8*)buf;
1057 unsigned long dleft = count;
1058
1059 // Why would anyone want more than this??
1060 if (count > cam->width * cam->height * 2)
1061 count = cam->width * cam->height * 2;
1062
1063 w9966_wreg(cam, 0x00, 0x02); // Reset ECP-FIFO buffer
1064 w9966_wreg(cam, 0x00, 0x00); // Return to normal operation
1065 w9966_wreg(cam, 0x01, cam->cmask | 0x80); // Enable capture
1066
1067 // write special capture-addr and negotiate into data transfer
1068 if (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0 ||
1069 parport_write(cam->pport, &addr, 1) != 1 ||
1070 parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0) {
1071 DPRINTF("Unable to write capture-addr.\n");
1072 return -EFAULT;
1073 }
1074
1075 while(dleft > 0)
1076 {
1077 const size_t tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
1078
1079 if (parport_read(cam->pport, cam->buffer, tsize) < tsize)
1080 return -EFAULT;
1081
1082 if (copy_to_user(dest, cam->buffer, tsize) != 0)
1083 return -EFAULT;
1084
1085 dest += tsize;
1086 dleft -= tsize;
1087 }
1088
1089 w9966_wreg(cam, 0x01, cam->cmask); // Disable capture
1090
1091 return count;
1092 }
1093
1094 // Called once for every parport on init
w9966_attach(struct parport * port)1095 static void w9966_attach(struct parport *port)
1096 {
1097 int i;
1098
1099 for (i = 0; i < W9966_MAXCAMS; i++) {
1100 if (strcmp(pardev[i], "none") == 0 || // Skip if 'none' or if
1101 w9966_cams[i].dev_state != 0) // cam already assigned
1102 continue;
1103
1104 if (strcmp(pardev[i], "auto") == 0 ||
1105 strcmp(pardev[i], port->name) == 0) {
1106 if (!w9966_init(&w9966_cams[i], port, video_nr[i]))
1107 w9966_term(&w9966_cams[i]);
1108 break; // return
1109 }
1110 }
1111 }
1112
1113 // Called once for every parport on termination
w9966_detach(struct parport * port)1114 static void w9966_detach(struct parport *port)
1115 {
1116 int i;
1117 for (i = 0; i < W9966_MAXCAMS; i++)
1118 if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
1119 w9966_term(&w9966_cams[i]);
1120 }
1121
1122
1123 static struct parport_driver w9966_ppd = {
1124 W9966_DRIVERNAME,
1125 w9966_attach,
1126 w9966_detach,
1127 NULL
1128 };
1129
1130 // Module entry point
w9966_mod_init(void)1131 static int __init w9966_mod_init(void)
1132 {
1133 int i, err;
1134
1135 w9966_cams = kmalloc(
1136 sizeof(struct w9966_dev) * W9966_MAXCAMS, GFP_KERNEL);
1137
1138 if (!w9966_cams)
1139 return -ENOMEM;
1140
1141 for (i = 0; i < W9966_MAXCAMS; i++)
1142 w9966_cams[i].dev_state = 0;
1143
1144 // Register parport driver
1145 if ((err = parport_register_driver(&w9966_ppd)) != 0) {
1146 kfree(w9966_cams);
1147 w9966_cams = 0;
1148 return err;
1149 }
1150
1151 return 0;
1152 }
1153
1154 // Module cleanup
w9966_mod_term(void)1155 static void __exit w9966_mod_term(void)
1156 {
1157 if (w9966_cams)
1158 kfree(w9966_cams);
1159
1160 parport_unregister_driver(&w9966_ppd);
1161 }
1162
1163 module_init(w9966_mod_init);
1164 module_exit(w9966_mod_term);
1165