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