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