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