V4L/DVB (9584): Support different GPIO/GPO registers for newer devices
[linux-2.6] / drivers / media / video / w9966.c
1 /*
2         Winbond w9966cf Webcam parport driver.
3
4         Version 0.32
5
6         Copyright (C) 2001 Jakob Kemi <jakob.kemi@post.utfors.se>
7
8         This program is free software; you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation; either version 2 of the License, or
11         (at your option) any later version.
12
13         This program is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with this program; if not, write to the Free Software
20         Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 /*
23         Supported devices:
24         *Lifeview FlyCam Supra (using the Philips saa7111a chip)
25
26         Does any other model using the w9966 interface chip exist ?
27
28         Todo:
29
30         *Add a working EPP mode, since DMA ECP read isn't implemented
31         in the parport drivers. (That's why it's so sloow)
32
33         *Add support for other ccd-control chips than the saa7111
34         please send me feedback on what kind of chips you have.
35
36         *Add proper probing. I don't know what's wrong with the IEEE1284
37         parport drivers but (IEEE1284_MODE_NIBBLE|IEEE1284_DEVICE_ID)
38         and nibble read seems to be broken for some peripherals.
39
40         *Add probing for onboard SRAM, port directions etc. (if possible)
41
42         *Add support for the hardware compressed modes (maybe using v4l2)
43
44         *Fix better support for the capture window (no skewed images, v4l
45         interface to capt. window)
46
47         *Probably some bugs that I don't know of
48
49         Please support me by sending feedback!
50
51         Changes:
52
53         Alan Cox:       Removed RGB mode for kernel merge, added THIS_MODULE
54                         and owner support for newer module locks
55 */
56
57 #include <linux/module.h>
58 #include <linux/init.h>
59 #include <linux/delay.h>
60 #include <linux/videodev2.h>
61 #include <media/v4l2-common.h>
62 #include <media/v4l2-ioctl.h>
63 #include <linux/parport.h>
64
65 /*#define DEBUG*/                               /* Undef me for production */
66
67 #ifdef DEBUG
68 #define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __func__ , ##a)
69 #else
70 #define DPRINTF(x...)
71 #endif
72
73 /*
74  *      Defines, simple typedefs etc.
75  */
76
77 #define W9966_DRIVERNAME        "W9966CF Webcam"
78 #define W9966_MAXCAMS           4       // Maximum number of cameras
79 #define W9966_RBUFFER           2048    // Read buffer (must be an even number)
80 #define W9966_SRAMSIZE          131072  // 128kb
81 #define W9966_SRAMID            0x02    // check w9966cf.pdf
82
83 // Empirically determined window limits
84 #define W9966_WND_MIN_X         16
85 #define W9966_WND_MIN_Y         14
86 #define W9966_WND_MAX_X         705
87 #define W9966_WND_MAX_Y         253
88 #define W9966_WND_MAX_W         (W9966_WND_MAX_X - W9966_WND_MIN_X)
89 #define W9966_WND_MAX_H         (W9966_WND_MAX_Y - W9966_WND_MIN_Y)
90
91 // Keep track of our current state
92 #define W9966_STATE_PDEV        0x01
93 #define W9966_STATE_CLAIMED     0x02
94 #define W9966_STATE_VDEV        0x04
95
96 #define W9966_I2C_W_ID          0x48
97 #define W9966_I2C_R_ID          0x49
98 #define W9966_I2C_R_DATA        0x08
99 #define W9966_I2C_R_CLOCK       0x04
100 #define W9966_I2C_W_DATA        0x02
101 #define W9966_I2C_W_CLOCK       0x01
102
103 struct w9966_dev {
104         unsigned char dev_state;
105         unsigned char i2c_state;
106         unsigned short ppmode;
107         struct parport* pport;
108         struct pardevice* pdev;
109         struct video_device vdev;
110         unsigned short width;
111         unsigned short height;
112         unsigned char brightness;
113         signed char contrast;
114         signed char color;
115         signed char hue;
116         unsigned long in_use;
117 };
118
119 /*
120  *      Module specific properties
121  */
122
123 MODULE_AUTHOR("Jakob Kemi <jakob.kemi@post.utfors.se>");
124 MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)");
125 MODULE_LICENSE("GPL");
126
127
128 #ifdef MODULE
129 static const char* pardev[] = {[0 ... W9966_MAXCAMS] = ""};
130 #else
131 static const char* pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
132 #endif
133 module_param_array(pardev, charp, NULL, 0);
134 MODULE_PARM_DESC(pardev, "pardev: where to search for\n\
135 \teach camera. 'aggressive' means brute-force search.\n\
136 \tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n\
137 \tcam 1 to parport3 and search every parport for cam 2 etc...");
138
139 static int parmode;
140 module_param(parmode, int, 0);
141 MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
142
143 static int video_nr = -1;
144 module_param(video_nr, int, 0);
145
146 /*
147  *      Private data
148  */
149
150 static struct w9966_dev w9966_cams[W9966_MAXCAMS];
151
152 /*
153  *      Private function declares
154  */
155
156 static inline void w9966_setState(struct w9966_dev* cam, int mask, int val);
157 static inline int  w9966_getState(struct w9966_dev* cam, int mask, int val);
158 static inline void w9966_pdev_claim(struct w9966_dev *vdev);
159 static inline void w9966_pdev_release(struct w9966_dev *vdev);
160
161 static int w9966_rReg(struct w9966_dev* cam, int reg);
162 static int w9966_wReg(struct w9966_dev* cam, int reg, int data);
163 #if 0
164 static int w9966_rReg_i2c(struct w9966_dev* cam, int reg);
165 #endif
166 static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data);
167 static int w9966_findlen(int near, int size, int maxlen);
168 static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor);
169 static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h);
170
171 static int  w9966_init(struct w9966_dev* cam, struct parport* port);
172 static void w9966_term(struct w9966_dev* cam);
173
174 static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state);
175 static inline int  w9966_i2c_setscl(struct w9966_dev* cam, int state);
176 static inline int  w9966_i2c_getsda(struct w9966_dev* cam);
177 static inline int  w9966_i2c_getscl(struct w9966_dev* cam);
178 static int w9966_i2c_wbyte(struct w9966_dev* cam, int data);
179 #if 0
180 static int w9966_i2c_rbyte(struct w9966_dev* cam);
181 #endif
182
183 static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
184                            unsigned int cmd, unsigned long arg);
185 static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
186                               size_t count, loff_t *ppos);
187
188 static int w9966_exclusive_open(struct inode *inode, struct file *file)
189 {
190         struct w9966_dev *cam = video_drvdata(file);
191
192         return test_and_set_bit(0, &cam->in_use) ? -EBUSY : 0;
193 }
194
195 static int w9966_exclusive_release(struct inode *inode, struct file *file)
196 {
197         struct w9966_dev *cam = video_drvdata(file);
198
199         clear_bit(0, &cam->in_use);
200         return 0;
201 }
202
203 static const struct file_operations w9966_fops = {
204         .owner          = THIS_MODULE,
205         .open           = w9966_exclusive_open,
206         .release        = w9966_exclusive_release,
207         .ioctl          = w9966_v4l_ioctl,
208 #ifdef CONFIG_COMPAT
209         .compat_ioctl   = v4l_compat_ioctl32,
210 #endif
211         .read           = w9966_v4l_read,
212         .llseek         = no_llseek,
213 };
214 static struct video_device w9966_template = {
215         .name           = W9966_DRIVERNAME,
216         .fops           = &w9966_fops,
217         .release        = video_device_release_empty,
218 };
219
220 /*
221  *      Private function defines
222  */
223
224
225 // Set camera phase flags, so we know what to uninit when terminating
226 static inline void w9966_setState(struct w9966_dev* cam, int mask, int val)
227 {
228         cam->dev_state = (cam->dev_state & ~mask) ^ val;
229 }
230
231 // Get camera phase flags
232 static inline int w9966_getState(struct w9966_dev* cam, int mask, int val)
233 {
234         return ((cam->dev_state & mask) == val);
235 }
236
237 // Claim parport for ourself
238 static inline void w9966_pdev_claim(struct w9966_dev* cam)
239 {
240         if (w9966_getState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
241                 return;
242         parport_claim_or_block(cam->pdev);
243         w9966_setState(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
244 }
245
246 // Release parport for others to use
247 static inline void w9966_pdev_release(struct w9966_dev* cam)
248 {
249         if (w9966_getState(cam, W9966_STATE_CLAIMED, 0))
250                 return;
251         parport_release(cam->pdev);
252         w9966_setState(cam, W9966_STATE_CLAIMED, 0);
253 }
254
255 // Read register from W9966 interface-chip
256 // Expects a claimed pdev
257 // -1 on error, else register data (byte)
258 static int w9966_rReg(struct w9966_dev* cam, int reg)
259 {
260         // ECP, read, regtransfer, REG, REG, REG, REG, REG
261         const unsigned char addr = 0x80 | (reg & 0x1f);
262         unsigned char val;
263
264         if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
265                 return -1;
266         if (parport_write(cam->pport, &addr, 1) != 1)
267                 return -1;
268         if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
269                 return -1;
270         if (parport_read(cam->pport, &val, 1) != 1)
271                 return -1;
272
273         return val;
274 }
275
276 // Write register to W9966 interface-chip
277 // Expects a claimed pdev
278 // -1 on error
279 static int w9966_wReg(struct w9966_dev* cam, int reg, int data)
280 {
281         // ECP, write, regtransfer, REG, REG, REG, REG, REG
282         const unsigned char addr = 0xc0 | (reg & 0x1f);
283         const unsigned char val = data;
284
285         if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
286                 return -1;
287         if (parport_write(cam->pport, &addr, 1) != 1)
288                 return -1;
289         if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
290                 return -1;
291         if (parport_write(cam->pport, &val, 1) != 1)
292                 return -1;
293
294         return 0;
295 }
296
297 // Initialize camera device. Setup all internal flags, set a
298 // default video mode, setup ccd-chip, register v4l device etc..
299 // Also used for 'probing' of hardware.
300 // -1 on error
301 static int w9966_init(struct w9966_dev* cam, struct parport* port)
302 {
303         if (cam->dev_state != 0)
304                 return -1;
305
306         cam->pport = port;
307         cam->brightness = 128;
308         cam->contrast = 64;
309         cam->color = 64;
310         cam->hue = 0;
311
312 // Select requested transfer mode
313         switch(parmode)
314         {
315         default:        // Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
316         case 0:
317                 if (port->modes & PARPORT_MODE_ECP)
318                         cam->ppmode = IEEE1284_MODE_ECP;
319                 else if (port->modes & PARPORT_MODE_EPP)
320                         cam->ppmode = IEEE1284_MODE_EPP;
321                 else
322                         cam->ppmode = IEEE1284_MODE_ECP;
323                 break;
324         case 1:         // hw- or sw-ecp
325                 cam->ppmode = IEEE1284_MODE_ECP;
326                 break;
327         case 2:         // hw- or sw-epp
328                 cam->ppmode = IEEE1284_MODE_EPP;
329         break;
330         }
331
332 // Tell the parport driver that we exists
333         cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
334         if (cam->pdev == NULL) {
335                 DPRINTF("parport_register_device() failed\n");
336                 return -1;
337         }
338         w9966_setState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
339
340         w9966_pdev_claim(cam);
341
342 // Setup a default capture mode
343         if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
344                 DPRINTF("w9966_setup() failed.\n");
345                 return -1;
346         }
347
348         w9966_pdev_release(cam);
349
350 // Fill in the video_device struct and register us to v4l
351         memcpy(&cam->vdev, &w9966_template, sizeof(struct video_device));
352         video_set_drvdata(&cam->vdev, cam);
353
354         if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
355                 return -1;
356
357         w9966_setState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
358
359         // All ok
360         printk(
361                 "w9966cf: Found and initialized a webcam on %s.\n",
362                 cam->pport->name
363         );
364         return 0;
365 }
366
367
368 // Terminate everything gracefully
369 static void w9966_term(struct w9966_dev* cam)
370 {
371 // Unregister from v4l
372         if (w9966_getState(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
373                 video_unregister_device(&cam->vdev);
374                 w9966_setState(cam, W9966_STATE_VDEV, 0);
375         }
376
377 // Terminate from IEEE1284 mode and release pdev block
378         if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
379                 w9966_pdev_claim(cam);
380                 parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
381                 w9966_pdev_release(cam);
382         }
383
384 // Unregister from parport
385         if (w9966_getState(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
386                 parport_unregister_device(cam->pdev);
387                 w9966_setState(cam, W9966_STATE_PDEV, 0);
388         }
389 }
390
391
392 // Find a good length for capture window (used both for W and H)
393 // A bit ugly but pretty functional. The capture length
394 // have to match the downscale
395 static int w9966_findlen(int near, int size, int maxlen)
396 {
397         int bestlen = size;
398         int besterr = abs(near - bestlen);
399         int len;
400
401         for(len = size+1;len < maxlen;len++)
402         {
403                 int err;
404                 if ( ((64*size) %len) != 0)
405                         continue;
406
407                 err = abs(near - len);
408
409                 // Only continue as long as we keep getting better values
410                 if (err > besterr)
411                         break;
412
413                 besterr = err;
414                 bestlen = len;
415         }
416
417         return bestlen;
418 }
419
420 // Modify capture window (if necessary)
421 // and calculate downscaling
422 // Return -1 on error
423 static int w9966_calcscale(int size, int min, int max, int* beg, int* end, unsigned char* factor)
424 {
425         int maxlen = max - min;
426         int len = *end - *beg + 1;
427         int newlen = w9966_findlen(len, size, maxlen);
428         int err = newlen - len;
429
430         // Check for bad format
431         if (newlen > maxlen || newlen < size)
432                 return -1;
433
434         // Set factor (6 bit fixed)
435         *factor = (64*size) / newlen;
436         if (*factor == 64)
437                 *factor = 0x00; // downscale is disabled
438         else
439                 *factor |= 0x80; // set downscale-enable bit
440
441         // Modify old beginning and end
442         *beg -= err / 2;
443         *end += err - (err / 2);
444
445         // Move window if outside borders
446         if (*beg < min) {
447                 *end += min - *beg;
448                 *beg += min - *beg;
449         }
450         if (*end > max) {
451                 *beg -= *end - max;
452                 *end -= *end - max;
453         }
454
455         return 0;
456 }
457
458 // Setup the cameras capture window etc.
459 // Expects a claimed pdev
460 // return -1 on error
461 static int w9966_setup(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h)
462 {
463         unsigned int i;
464         unsigned int enh_s, enh_e;
465         unsigned char scale_x, scale_y;
466         unsigned char regs[0x1c];
467         unsigned char saa7111_regs[] = {
468                 0x21, 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00,
469                 0x88, 0x10, 0x80, 0x40, 0x40, 0x00, 0x01, 0x00,
470                 0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471                 0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0
472         };
473
474
475         if (w*h*2 > W9966_SRAMSIZE)
476         {
477                 DPRINTF("capture window exceeds SRAM size!.\n");
478                 w = 200; h = 160;       // Pick default values
479         }
480
481         w &= ~0x1;
482         if (w < 2) w = 2;
483         if (h < 1) h = 1;
484         if (w > W9966_WND_MAX_W) w = W9966_WND_MAX_W;
485         if (h > W9966_WND_MAX_H) h = W9966_WND_MAX_H;
486
487         cam->width = w;
488         cam->height = h;
489
490         enh_s = 0;
491         enh_e = w*h*2;
492
493 // Modify capture window if necessary and calculate downscaling
494         if (
495                 w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
496                 w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0
497         ) return -1;
498
499         DPRINTF(
500                 "%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
501                 w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80
502         );
503
504 // Setup registers
505         regs[0x00] = 0x00;                      // Set normal operation
506         regs[0x01] = 0x18;                      // Capture mode
507         regs[0x02] = scale_y;                   // V-scaling
508         regs[0x03] = scale_x;                   // H-scaling
509
510         // Capture window
511         regs[0x04] = (x1 & 0x0ff);              // X-start (8 low bits)
512         regs[0x05] = (x1 & 0x300)>>8;           // X-start (2 high bits)
513         regs[0x06] = (y1 & 0x0ff);              // Y-start (8 low bits)
514         regs[0x07] = (y1 & 0x300)>>8;           // Y-start (2 high bits)
515         regs[0x08] = (x2 & 0x0ff);              // X-end (8 low bits)
516         regs[0x09] = (x2 & 0x300)>>8;           // X-end (2 high bits)
517         regs[0x0a] = (y2 & 0x0ff);              // Y-end (8 low bits)
518
519         regs[0x0c] = W9966_SRAMID;              // SRAM-banks (1x 128kb)
520
521         // Enhancement layer
522         regs[0x0d] = (enh_s& 0x000ff);          // Enh. start (0-7)
523         regs[0x0e] = (enh_s& 0x0ff00)>>8;       // Enh. start (8-15)
524         regs[0x0f] = (enh_s& 0x70000)>>16;      // Enh. start (16-17/18??)
525         regs[0x10] = (enh_e& 0x000ff);          // Enh. end (0-7)
526         regs[0x11] = (enh_e& 0x0ff00)>>8;       // Enh. end (8-15)
527         regs[0x12] = (enh_e& 0x70000)>>16;      // Enh. end (16-17/18??)
528
529         // Misc
530         regs[0x13] = 0x40;                      // VEE control (raw 4:2:2)
531         regs[0x17] = 0x00;                      // ???
532         regs[0x18] = cam->i2c_state = 0x00;     // Serial bus
533         regs[0x19] = 0xff;                      // I/O port direction control
534         regs[0x1a] = 0xff;                      // I/O port data register
535         regs[0x1b] = 0x10;                      // ???
536
537         // SAA7111 chip settings
538         saa7111_regs[0x0a] = cam->brightness;
539         saa7111_regs[0x0b] = cam->contrast;
540         saa7111_regs[0x0c] = cam->color;
541         saa7111_regs[0x0d] = cam->hue;
542
543 // Reset (ECP-fifo & serial-bus)
544         if (w9966_wReg(cam, 0x00, 0x03) == -1)
545                 return -1;
546
547 // Write regs to w9966cf chip
548         for (i = 0; i < 0x1c; i++)
549                 if (w9966_wReg(cam, i, regs[i]) == -1)
550                         return -1;
551
552 // Write regs to saa7111 chip
553         for (i = 0; i < 0x20; i++)
554                 if (w9966_wReg_i2c(cam, i, saa7111_regs[i]) == -1)
555                         return -1;
556
557         return 0;
558 }
559
560 /*
561  *      Ugly and primitive i2c protocol functions
562  */
563
564 // Sets the data line on the i2c bus.
565 // Expects a claimed pdev.
566 static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state)
567 {
568         if (state)
569                 cam->i2c_state |= W9966_I2C_W_DATA;
570         else
571                 cam->i2c_state &= ~W9966_I2C_W_DATA;
572
573         w9966_wReg(cam, 0x18, cam->i2c_state);
574         udelay(5);
575 }
576
577 // Get peripheral clock line
578 // Expects a claimed pdev.
579 static inline int w9966_i2c_getscl(struct w9966_dev* cam)
580 {
581         const unsigned char state = w9966_rReg(cam, 0x18);
582         return ((state & W9966_I2C_R_CLOCK) > 0);
583 }
584
585 // Sets the clock line on the i2c bus.
586 // Expects a claimed pdev. -1 on error
587 static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state)
588 {
589         unsigned long timeout;
590
591         if (state)
592                 cam->i2c_state |= W9966_I2C_W_CLOCK;
593         else
594                 cam->i2c_state &= ~W9966_I2C_W_CLOCK;
595
596         w9966_wReg(cam, 0x18, cam->i2c_state);
597         udelay(5);
598
599         // we go to high, we also expect the peripheral to ack.
600         if (state) {
601                 timeout = jiffies + 100;
602                 while (!w9966_i2c_getscl(cam)) {
603                         if (time_after(jiffies, timeout))
604                                 return -1;
605                 }
606         }
607         return 0;
608 }
609
610 // Get peripheral data line
611 // Expects a claimed pdev.
612 static inline int w9966_i2c_getsda(struct w9966_dev* cam)
613 {
614         const unsigned char state = w9966_rReg(cam, 0x18);
615         return ((state & W9966_I2C_R_DATA) > 0);
616 }
617
618 // Write a byte with ack to the i2c bus.
619 // Expects a claimed pdev. -1 on error
620 static int w9966_i2c_wbyte(struct w9966_dev* cam, int data)
621 {
622         int i;
623         for (i = 7; i >= 0; i--)
624         {
625                 w9966_i2c_setsda(cam, (data >> i) & 0x01);
626
627                 if (w9966_i2c_setscl(cam, 1) == -1)
628                         return -1;
629                 w9966_i2c_setscl(cam, 0);
630         }
631
632         w9966_i2c_setsda(cam, 1);
633
634         if (w9966_i2c_setscl(cam, 1) == -1)
635                 return -1;
636         w9966_i2c_setscl(cam, 0);
637
638         return 0;
639 }
640
641 // Read a data byte with ack from the i2c-bus
642 // Expects a claimed pdev. -1 on error
643 #if 0
644 static int w9966_i2c_rbyte(struct w9966_dev* cam)
645 {
646         unsigned char data = 0x00;
647         int i;
648
649         w9966_i2c_setsda(cam, 1);
650
651         for (i = 0; i < 8; i++)
652         {
653                 if (w9966_i2c_setscl(cam, 1) == -1)
654                         return -1;
655                 data = data << 1;
656                 if (w9966_i2c_getsda(cam))
657                         data |= 0x01;
658
659                 w9966_i2c_setscl(cam, 0);
660         }
661         return data;
662 }
663 #endif
664
665 // Read a register from the i2c device.
666 // Expects claimed pdev. -1 on error
667 #if 0
668 static int w9966_rReg_i2c(struct w9966_dev* cam, int reg)
669 {
670         int data;
671
672         w9966_i2c_setsda(cam, 0);
673         w9966_i2c_setscl(cam, 0);
674
675         if (
676                 w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
677                 w9966_i2c_wbyte(cam, reg) == -1
678         )
679                 return -1;
680
681         w9966_i2c_setsda(cam, 1);
682         if (w9966_i2c_setscl(cam, 1) == -1)
683                 return -1;
684         w9966_i2c_setsda(cam, 0);
685         w9966_i2c_setscl(cam, 0);
686
687         if (
688                 w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1 ||
689                 (data = w9966_i2c_rbyte(cam)) == -1
690         )
691                 return -1;
692
693         w9966_i2c_setsda(cam, 0);
694
695         if (w9966_i2c_setscl(cam, 1) == -1)
696                 return -1;
697         w9966_i2c_setsda(cam, 1);
698
699         return data;
700 }
701 #endif
702
703 // Write a register to the i2c device.
704 // Expects claimed pdev. -1 on error
705 static int w9966_wReg_i2c(struct w9966_dev* cam, int reg, int data)
706 {
707         w9966_i2c_setsda(cam, 0);
708         w9966_i2c_setscl(cam, 0);
709
710         if (
711                 w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
712                 w9966_i2c_wbyte(cam, reg) == -1 ||
713                 w9966_i2c_wbyte(cam, data) == -1
714         )
715                 return -1;
716
717         w9966_i2c_setsda(cam, 0);
718         if (w9966_i2c_setscl(cam, 1) == -1)
719                 return -1;
720
721         w9966_i2c_setsda(cam, 1);
722
723         return 0;
724 }
725
726 /*
727  *      Video4linux interfacing
728  */
729
730 static int w9966_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg)
731 {
732         struct w9966_dev *cam = video_drvdata(file);
733
734         switch(cmd)
735         {
736         case VIDIOCGCAP:
737         {
738                 static struct video_capability vcap = {
739                         .name      = W9966_DRIVERNAME,
740                         .type      = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
741                         .channels  = 1,
742                         .maxwidth  = W9966_WND_MAX_W,
743                         .maxheight = W9966_WND_MAX_H,
744                         .minwidth  = 2,
745                         .minheight = 1,
746                 };
747                 struct video_capability *cap = arg;
748                 *cap = vcap;
749                 return 0;
750         }
751         case VIDIOCGCHAN:
752         {
753                 struct video_channel *vch = arg;
754                 if(vch->channel != 0)   // We only support one channel (#0)
755                         return -EINVAL;
756                 memset(vch,0,sizeof(*vch));
757                 strcpy(vch->name, "CCD-input");
758                 vch->type = VIDEO_TYPE_CAMERA;
759                 return 0;
760         }
761         case VIDIOCSCHAN:
762         {
763                 struct video_channel *vch = arg;
764                 if(vch->channel != 0)
765                         return -EINVAL;
766                 return 0;
767         }
768         case VIDIOCGTUNER:
769         {
770                 struct video_tuner *vtune = arg;
771                 if(vtune->tuner != 0)
772                         return -EINVAL;
773                 strcpy(vtune->name, "no tuner");
774                 vtune->rangelow = 0;
775                 vtune->rangehigh = 0;
776                 vtune->flags = VIDEO_TUNER_NORM;
777                 vtune->mode = VIDEO_MODE_AUTO;
778                 vtune->signal = 0xffff;
779                 return 0;
780         }
781         case VIDIOCSTUNER:
782         {
783                 struct video_tuner *vtune = arg;
784                 if (vtune->tuner != 0)
785                         return -EINVAL;
786                 if (vtune->mode != VIDEO_MODE_AUTO)
787                         return -EINVAL;
788                 return 0;
789         }
790         case VIDIOCGPICT:
791         {
792                 struct video_picture vpic = {
793                         cam->brightness << 8,   // brightness
794                         (cam->hue + 128) << 8,  // hue
795                         cam->color << 9,        // color
796                         cam->contrast << 9,     // contrast
797                         0x8000,                 // whiteness
798                         16, VIDEO_PALETTE_YUV422// bpp, palette format
799                 };
800                 struct video_picture *pic = arg;
801                 *pic = vpic;
802                 return 0;
803         }
804         case VIDIOCSPICT:
805         {
806                 struct video_picture *vpic = arg;
807                 if (vpic->depth != 16 || (vpic->palette != VIDEO_PALETTE_YUV422 && vpic->palette != VIDEO_PALETTE_YUYV))
808                         return -EINVAL;
809
810                 cam->brightness = vpic->brightness >> 8;
811                 cam->hue = (vpic->hue >> 8) - 128;
812                 cam->color = vpic->colour >> 9;
813                 cam->contrast = vpic->contrast >> 9;
814
815                 w9966_pdev_claim(cam);
816
817                 if (
818                         w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 ||
819                         w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
820                         w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
821                         w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
822                 ) {
823                         w9966_pdev_release(cam);
824                         return -EIO;
825                 }
826
827                 w9966_pdev_release(cam);
828                 return 0;
829         }
830         case VIDIOCSWIN:
831         {
832                 int ret;
833                 struct video_window *vwin = arg;
834
835                 if (vwin->flags != 0)
836                         return -EINVAL;
837                 if (vwin->clipcount != 0)
838                         return -EINVAL;
839                 if (vwin->width < 2 || vwin->width > W9966_WND_MAX_W)
840                         return -EINVAL;
841                 if (vwin->height < 1 || vwin->height > W9966_WND_MAX_H)
842                         return -EINVAL;
843
844                 // Update camera regs
845                 w9966_pdev_claim(cam);
846                 ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin->width, vwin->height);
847                 w9966_pdev_release(cam);
848
849                 if (ret != 0) {
850                         DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n");
851                         return -EIO;
852                 }
853
854                 return 0;
855         }
856         case VIDIOCGWIN:
857         {
858                 struct video_window *vwin = arg;
859                 memset(vwin, 0, sizeof(*vwin));
860                 vwin->width = cam->width;
861                 vwin->height = cam->height;
862                 return 0;
863         }
864         // Unimplemented
865         case VIDIOCCAPTURE:
866         case VIDIOCGFBUF:
867         case VIDIOCSFBUF:
868         case VIDIOCKEY:
869         case VIDIOCGFREQ:
870         case VIDIOCSFREQ:
871         case VIDIOCGAUDIO:
872         case VIDIOCSAUDIO:
873                 return -EINVAL;
874         default:
875                 return -ENOIOCTLCMD;
876         }
877         return 0;
878 }
879
880 static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
881                            unsigned int cmd, unsigned long arg)
882 {
883         return video_usercopy(file, cmd, arg, w9966_v4l_do_ioctl);
884 }
885
886 // Capture data
887 static ssize_t w9966_v4l_read(struct file *file, char  __user *buf,
888                               size_t count, loff_t *ppos)
889 {
890         struct w9966_dev *cam = video_drvdata(file);
891         unsigned char addr = 0xa0;      // ECP, read, CCD-transfer, 00000
892         unsigned char __user *dest = (unsigned char __user *)buf;
893         unsigned long dleft = count;
894         unsigned char *tbuf;
895
896         // Why would anyone want more than this??
897         if (count > cam->width * cam->height * 2)
898                 return -EINVAL;
899
900         w9966_pdev_claim(cam);
901         w9966_wReg(cam, 0x00, 0x02);    // Reset ECP-FIFO buffer
902         w9966_wReg(cam, 0x00, 0x00);    // Return to normal operation
903         w9966_wReg(cam, 0x01, 0x98);    // Enable capture
904
905         // write special capture-addr and negotiate into data transfer
906         if (
907                 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0  )||
908                 (parport_write(cam->pport, &addr, 1) != 1                                               )||
909                 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0  )
910         ) {
911                 w9966_pdev_release(cam);
912                 return -EFAULT;
913         }
914
915         tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
916         if (tbuf == NULL) {
917                 count = -ENOMEM;
918                 goto out;
919         }
920
921         while(dleft > 0)
922         {
923                 unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
924
925                 if (parport_read(cam->pport, tbuf, tsize) < tsize) {
926                         count = -EFAULT;
927                         goto out;
928                 }
929                 if (copy_to_user(dest, tbuf, tsize) != 0) {
930                         count = -EFAULT;
931                         goto out;
932                 }
933                 dest += tsize;
934                 dleft -= tsize;
935         }
936
937         w9966_wReg(cam, 0x01, 0x18);    // Disable capture
938
939 out:
940         kfree(tbuf);
941         w9966_pdev_release(cam);
942
943         return count;
944 }
945
946
947 // Called once for every parport on init
948 static void w9966_attach(struct parport *port)
949 {
950         int i;
951
952         for (i = 0; i < W9966_MAXCAMS; i++)
953         {
954                 if (w9966_cams[i].dev_state != 0)       // Cam is already assigned
955                         continue;
956                 if (
957                         strcmp(pardev[i], "aggressive") == 0 ||
958                         strcmp(pardev[i], port->name) == 0
959                 ) {
960                         if (w9966_init(&w9966_cams[i], port) != 0)
961                         w9966_term(&w9966_cams[i]);
962                         break;  // return
963                 }
964         }
965 }
966
967 // Called once for every parport on termination
968 static void w9966_detach(struct parport *port)
969 {
970         int i;
971         for (i = 0; i < W9966_MAXCAMS; i++)
972         if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
973                 w9966_term(&w9966_cams[i]);
974 }
975
976
977 static struct parport_driver w9966_ppd = {
978         .name = W9966_DRIVERNAME,
979         .attach = w9966_attach,
980         .detach = w9966_detach,
981 };
982
983 // Module entry point
984 static int __init w9966_mod_init(void)
985 {
986         int i;
987         for (i = 0; i < W9966_MAXCAMS; i++)
988                 w9966_cams[i].dev_state = 0;
989
990         return parport_register_driver(&w9966_ppd);
991 }
992
993 // Module cleanup
994 static void __exit w9966_mod_term(void)
995 {
996         parport_unregister_driver(&w9966_ppd);
997 }
998
999 module_init(w9966_mod_init);
1000 module_exit(w9966_mod_term);