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