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