Merge branch 'suspend' into release
[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 inode *inode, struct file *file,
731                               unsigned int cmd, void *arg)
732 {
733         struct w9966_dev *cam = video_drvdata(file);
734
735         switch(cmd)
736         {
737         case VIDIOCGCAP:
738         {
739                 static struct video_capability vcap = {
740                         .name      = W9966_DRIVERNAME,
741                         .type      = VID_TYPE_CAPTURE | VID_TYPE_SCALES,
742                         .channels  = 1,
743                         .maxwidth  = W9966_WND_MAX_W,
744                         .maxheight = W9966_WND_MAX_H,
745                         .minwidth  = 2,
746                         .minheight = 1,
747                 };
748                 struct video_capability *cap = arg;
749                 *cap = vcap;
750                 return 0;
751         }
752         case VIDIOCGCHAN:
753         {
754                 struct video_channel *vch = arg;
755                 if(vch->channel != 0)   // We only support one channel (#0)
756                         return -EINVAL;
757                 memset(vch,0,sizeof(*vch));
758                 strcpy(vch->name, "CCD-input");
759                 vch->type = VIDEO_TYPE_CAMERA;
760                 return 0;
761         }
762         case VIDIOCSCHAN:
763         {
764                 struct video_channel *vch = arg;
765                 if(vch->channel != 0)
766                         return -EINVAL;
767                 return 0;
768         }
769         case VIDIOCGTUNER:
770         {
771                 struct video_tuner *vtune = arg;
772                 if(vtune->tuner != 0)
773                         return -EINVAL;
774                 strcpy(vtune->name, "no tuner");
775                 vtune->rangelow = 0;
776                 vtune->rangehigh = 0;
777                 vtune->flags = VIDEO_TUNER_NORM;
778                 vtune->mode = VIDEO_MODE_AUTO;
779                 vtune->signal = 0xffff;
780                 return 0;
781         }
782         case VIDIOCSTUNER:
783         {
784                 struct video_tuner *vtune = arg;
785                 if (vtune->tuner != 0)
786                         return -EINVAL;
787                 if (vtune->mode != VIDEO_MODE_AUTO)
788                         return -EINVAL;
789                 return 0;
790         }
791         case VIDIOCGPICT:
792         {
793                 struct video_picture vpic = {
794                         cam->brightness << 8,   // brightness
795                         (cam->hue + 128) << 8,  // hue
796                         cam->color << 9,        // color
797                         cam->contrast << 9,     // contrast
798                         0x8000,                 // whiteness
799                         16, VIDEO_PALETTE_YUV422// bpp, palette format
800                 };
801                 struct video_picture *pic = arg;
802                 *pic = vpic;
803                 return 0;
804         }
805         case VIDIOCSPICT:
806         {
807                 struct video_picture *vpic = arg;
808                 if (vpic->depth != 16 || (vpic->palette != VIDEO_PALETTE_YUV422 && vpic->palette != VIDEO_PALETTE_YUYV))
809                         return -EINVAL;
810
811                 cam->brightness = vpic->brightness >> 8;
812                 cam->hue = (vpic->hue >> 8) - 128;
813                 cam->color = vpic->colour >> 9;
814                 cam->contrast = vpic->contrast >> 9;
815
816                 w9966_pdev_claim(cam);
817
818                 if (
819                         w9966_wReg_i2c(cam, 0x0a, cam->brightness) == -1 ||
820                         w9966_wReg_i2c(cam, 0x0b, cam->contrast) == -1 ||
821                         w9966_wReg_i2c(cam, 0x0c, cam->color) == -1 ||
822                         w9966_wReg_i2c(cam, 0x0d, cam->hue) == -1
823                 ) {
824                         w9966_pdev_release(cam);
825                         return -EIO;
826                 }
827
828                 w9966_pdev_release(cam);
829                 return 0;
830         }
831         case VIDIOCSWIN:
832         {
833                 int ret;
834                 struct video_window *vwin = arg;
835
836                 if (vwin->flags != 0)
837                         return -EINVAL;
838                 if (vwin->clipcount != 0)
839                         return -EINVAL;
840                 if (vwin->width < 2 || vwin->width > W9966_WND_MAX_W)
841                         return -EINVAL;
842                 if (vwin->height < 1 || vwin->height > W9966_WND_MAX_H)
843                         return -EINVAL;
844
845                 // Update camera regs
846                 w9966_pdev_claim(cam);
847                 ret = w9966_setup(cam, 0, 0, 1023, 1023, vwin->width, vwin->height);
848                 w9966_pdev_release(cam);
849
850                 if (ret != 0) {
851                         DPRINTF("VIDIOCSWIN: w9966_setup() failed.\n");
852                         return -EIO;
853                 }
854
855                 return 0;
856         }
857         case VIDIOCGWIN:
858         {
859                 struct video_window *vwin = arg;
860                 memset(vwin, 0, sizeof(*vwin));
861                 vwin->width = cam->width;
862                 vwin->height = cam->height;
863                 return 0;
864         }
865         // Unimplemented
866         case VIDIOCCAPTURE:
867         case VIDIOCGFBUF:
868         case VIDIOCSFBUF:
869         case VIDIOCKEY:
870         case VIDIOCGFREQ:
871         case VIDIOCSFREQ:
872         case VIDIOCGAUDIO:
873         case VIDIOCSAUDIO:
874                 return -EINVAL;
875         default:
876                 return -ENOIOCTLCMD;
877         }
878         return 0;
879 }
880
881 static int w9966_v4l_ioctl(struct inode *inode, struct file *file,
882                            unsigned int cmd, unsigned long arg)
883 {
884         return video_usercopy(inode, file, cmd, arg, w9966_v4l_do_ioctl);
885 }
886
887 // Capture data
888 static ssize_t w9966_v4l_read(struct file *file, char  __user *buf,
889                               size_t count, loff_t *ppos)
890 {
891         struct w9966_dev *cam = video_drvdata(file);
892         unsigned char addr = 0xa0;      // ECP, read, CCD-transfer, 00000
893         unsigned char __user *dest = (unsigned char __user *)buf;
894         unsigned long dleft = count;
895         unsigned char *tbuf;
896
897         // Why would anyone want more than this??
898         if (count > cam->width * cam->height * 2)
899                 return -EINVAL;
900
901         w9966_pdev_claim(cam);
902         w9966_wReg(cam, 0x00, 0x02);    // Reset ECP-FIFO buffer
903         w9966_wReg(cam, 0x00, 0x00);    // Return to normal operation
904         w9966_wReg(cam, 0x01, 0x98);    // Enable capture
905
906         // write special capture-addr and negotiate into data transfer
907         if (
908                 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0  )||
909                 (parport_write(cam->pport, &addr, 1) != 1                                               )||
910                 (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0  )
911         ) {
912                 w9966_pdev_release(cam);
913                 return -EFAULT;
914         }
915
916         tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
917         if (tbuf == NULL) {
918                 count = -ENOMEM;
919                 goto out;
920         }
921
922         while(dleft > 0)
923         {
924                 unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
925
926                 if (parport_read(cam->pport, tbuf, tsize) < tsize) {
927                         count = -EFAULT;
928                         goto out;
929                 }
930                 if (copy_to_user(dest, tbuf, tsize) != 0) {
931                         count = -EFAULT;
932                         goto out;
933                 }
934                 dest += tsize;
935                 dleft -= tsize;
936         }
937
938         w9966_wReg(cam, 0x01, 0x18);    // Disable capture
939
940 out:
941         kfree(tbuf);
942         w9966_pdev_release(cam);
943
944         return count;
945 }
946
947
948 // Called once for every parport on init
949 static void w9966_attach(struct parport *port)
950 {
951         int i;
952
953         for (i = 0; i < W9966_MAXCAMS; i++)
954         {
955                 if (w9966_cams[i].dev_state != 0)       // Cam is already assigned
956                         continue;
957                 if (
958                         strcmp(pardev[i], "aggressive") == 0 ||
959                         strcmp(pardev[i], port->name) == 0
960                 ) {
961                         if (w9966_init(&w9966_cams[i], port) != 0)
962                         w9966_term(&w9966_cams[i]);
963                         break;  // return
964                 }
965         }
966 }
967
968 // Called once for every parport on termination
969 static void w9966_detach(struct parport *port)
970 {
971         int i;
972         for (i = 0; i < W9966_MAXCAMS; i++)
973         if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
974                 w9966_term(&w9966_cams[i]);
975 }
976
977
978 static struct parport_driver w9966_ppd = {
979         .name = W9966_DRIVERNAME,
980         .attach = w9966_attach,
981         .detach = w9966_detach,
982 };
983
984 // Module entry point
985 static int __init w9966_mod_init(void)
986 {
987         int i;
988         for (i = 0; i < W9966_MAXCAMS; i++)
989                 w9966_cams[i].dev_state = 0;
990
991         return parport_register_driver(&w9966_ppd);
992 }
993
994 // Module cleanup
995 static void __exit w9966_mod_term(void)
996 {
997         parport_unregister_driver(&w9966_ppd);
998 }
999
1000 module_init(w9966_mod_init);
1001 module_exit(w9966_mod_term);