[media] omap3isp: Fix build error in ispccdc.c
[pandora-kernel.git] / drivers / media / video / w9966.c
1 /*
2         Winbond w9966cf Webcam parport driver.
3
4         Version 0.33
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 <linux/slab.h>
62 #include <media/v4l2-common.h>
63 #include <media/v4l2-ioctl.h>
64 #include <media/v4l2-device.h>
65 #include <linux/parport.h>
66
67 /*#define DEBUG*/                               /* Undef me for production */
68
69 #ifdef DEBUG
70 #define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __func__ , ##a)
71 #else
72 #define DPRINTF(x...)
73 #endif
74
75 /*
76  *      Defines, simple typedefs etc.
77  */
78
79 #define W9966_DRIVERNAME        "W9966CF Webcam"
80 #define W9966_MAXCAMS           4       /* Maximum number of cameras */
81 #define W9966_RBUFFER           2048    /* Read buffer (must be an even number) */
82 #define W9966_SRAMSIZE          131072  /* 128kb */
83 #define W9966_SRAMID            0x02    /* check w9966cf.pdf */
84
85 /* Empirically determined window limits */
86 #define W9966_WND_MIN_X         16
87 #define W9966_WND_MIN_Y         14
88 #define W9966_WND_MAX_X         705
89 #define W9966_WND_MAX_Y         253
90 #define W9966_WND_MAX_W         (W9966_WND_MAX_X - W9966_WND_MIN_X)
91 #define W9966_WND_MAX_H         (W9966_WND_MAX_Y - W9966_WND_MIN_Y)
92
93 /* Keep track of our current state */
94 #define W9966_STATE_PDEV        0x01
95 #define W9966_STATE_CLAIMED     0x02
96 #define W9966_STATE_VDEV        0x04
97
98 #define W9966_I2C_W_ID          0x48
99 #define W9966_I2C_R_ID          0x49
100 #define W9966_I2C_R_DATA        0x08
101 #define W9966_I2C_R_CLOCK       0x04
102 #define W9966_I2C_W_DATA        0x02
103 #define W9966_I2C_W_CLOCK       0x01
104
105 struct w9966 {
106         struct v4l2_device v4l2_dev;
107         unsigned char dev_state;
108         unsigned char i2c_state;
109         unsigned short ppmode;
110         struct parport *pport;
111         struct pardevice *pdev;
112         struct video_device vdev;
113         unsigned short width;
114         unsigned short height;
115         unsigned char brightness;
116         signed char contrast;
117         signed char color;
118         signed char hue;
119         struct mutex lock;
120 };
121
122 /*
123  *      Module specific properties
124  */
125
126 MODULE_AUTHOR("Jakob Kemi <jakob.kemi@post.utfors.se>");
127 MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)");
128 MODULE_LICENSE("GPL");
129 MODULE_VERSION("0.33.1");
130
131 #ifdef MODULE
132 static const char *pardev[] = {[0 ... W9966_MAXCAMS] = ""};
133 #else
134 static const char *pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
135 #endif
136 module_param_array(pardev, charp, NULL, 0);
137 MODULE_PARM_DESC(pardev, "pardev: where to search for\n"
138                 "\teach camera. 'aggressive' means brute-force search.\n"
139                 "\tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n"
140                 "\tcam 1 to parport3 and search every parport for cam 2 etc...");
141
142 static int parmode;
143 module_param(parmode, int, 0);
144 MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
145
146 static int video_nr = -1;
147 module_param(video_nr, int, 0);
148
149 static struct w9966 w9966_cams[W9966_MAXCAMS];
150
151 /*
152  *      Private function defines
153  */
154
155
156 /* Set camera phase flags, so we know what to uninit when terminating */
157 static inline void w9966_set_state(struct w9966 *cam, int mask, int val)
158 {
159         cam->dev_state = (cam->dev_state & ~mask) ^ val;
160 }
161
162 /* Get camera phase flags */
163 static inline int w9966_get_state(struct w9966 *cam, int mask, int val)
164 {
165         return ((cam->dev_state & mask) == val);
166 }
167
168 /* Claim parport for ourself */
169 static void w9966_pdev_claim(struct w9966 *cam)
170 {
171         if (w9966_get_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
172                 return;
173         parport_claim_or_block(cam->pdev);
174         w9966_set_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
175 }
176
177 /* Release parport for others to use */
178 static void w9966_pdev_release(struct w9966 *cam)
179 {
180         if (w9966_get_state(cam, W9966_STATE_CLAIMED, 0))
181                 return;
182         parport_release(cam->pdev);
183         w9966_set_state(cam, W9966_STATE_CLAIMED, 0);
184 }
185
186 /* Read register from W9966 interface-chip
187    Expects a claimed pdev
188    -1 on error, else register data (byte) */
189 static int w9966_read_reg(struct w9966 *cam, int reg)
190 {
191         /* ECP, read, regtransfer, REG, REG, REG, REG, REG */
192         const unsigned char addr = 0x80 | (reg & 0x1f);
193         unsigned char val;
194
195         if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
196                 return -1;
197         if (parport_write(cam->pport, &addr, 1) != 1)
198                 return -1;
199         if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
200                 return -1;
201         if (parport_read(cam->pport, &val, 1) != 1)
202                 return -1;
203
204         return val;
205 }
206
207 /* Write register to W9966 interface-chip
208    Expects a claimed pdev
209    -1 on error */
210 static int w9966_write_reg(struct w9966 *cam, int reg, int data)
211 {
212         /* ECP, write, regtransfer, REG, REG, REG, REG, REG */
213         const unsigned char addr = 0xc0 | (reg & 0x1f);
214         const unsigned char val = data;
215
216         if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
217                 return -1;
218         if (parport_write(cam->pport, &addr, 1) != 1)
219                 return -1;
220         if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
221                 return -1;
222         if (parport_write(cam->pport, &val, 1) != 1)
223                 return -1;
224
225         return 0;
226 }
227
228 /*
229  *      Ugly and primitive i2c protocol functions
230  */
231
232 /* Sets the data line on the i2c bus.
233    Expects a claimed pdev. */
234 static void w9966_i2c_setsda(struct w9966 *cam, int state)
235 {
236         if (state)
237                 cam->i2c_state |= W9966_I2C_W_DATA;
238         else
239                 cam->i2c_state &= ~W9966_I2C_W_DATA;
240
241         w9966_write_reg(cam, 0x18, cam->i2c_state);
242         udelay(5);
243 }
244
245 /* Get peripheral clock line
246    Expects a claimed pdev. */
247 static int w9966_i2c_getscl(struct w9966 *cam)
248 {
249         const unsigned char state = w9966_read_reg(cam, 0x18);
250         return ((state & W9966_I2C_R_CLOCK) > 0);
251 }
252
253 /* Sets the clock line on the i2c bus.
254    Expects a claimed pdev. -1 on error */
255 static int w9966_i2c_setscl(struct w9966 *cam, int state)
256 {
257         unsigned long timeout;
258
259         if (state)
260                 cam->i2c_state |= W9966_I2C_W_CLOCK;
261         else
262                 cam->i2c_state &= ~W9966_I2C_W_CLOCK;
263
264         w9966_write_reg(cam, 0x18, cam->i2c_state);
265         udelay(5);
266
267         /* we go to high, we also expect the peripheral to ack. */
268         if (state) {
269                 timeout = jiffies + 100;
270                 while (!w9966_i2c_getscl(cam)) {
271                         if (time_after(jiffies, timeout))
272                                 return -1;
273                 }
274         }
275         return 0;
276 }
277
278 #if 0
279 /* Get peripheral data line
280    Expects a claimed pdev. */
281 static int w9966_i2c_getsda(struct w9966 *cam)
282 {
283         const unsigned char state = w9966_read_reg(cam, 0x18);
284         return ((state & W9966_I2C_R_DATA) > 0);
285 }
286 #endif
287
288 /* Write a byte with ack to the i2c bus.
289    Expects a claimed pdev. -1 on error */
290 static int w9966_i2c_wbyte(struct w9966 *cam, int data)
291 {
292         int i;
293
294         for (i = 7; i >= 0; i--) {
295                 w9966_i2c_setsda(cam, (data >> i) & 0x01);
296
297                 if (w9966_i2c_setscl(cam, 1) == -1)
298                         return -1;
299                 w9966_i2c_setscl(cam, 0);
300         }
301
302         w9966_i2c_setsda(cam, 1);
303
304         if (w9966_i2c_setscl(cam, 1) == -1)
305                 return -1;
306         w9966_i2c_setscl(cam, 0);
307
308         return 0;
309 }
310
311 /* Read a data byte with ack from the i2c-bus
312    Expects a claimed pdev. -1 on error */
313 #if 0
314 static int w9966_i2c_rbyte(struct w9966 *cam)
315 {
316         unsigned char data = 0x00;
317         int i;
318
319         w9966_i2c_setsda(cam, 1);
320
321         for (i = 0; i < 8; i++) {
322                 if (w9966_i2c_setscl(cam, 1) == -1)
323                         return -1;
324                 data = data << 1;
325                 if (w9966_i2c_getsda(cam))
326                         data |= 0x01;
327
328                 w9966_i2c_setscl(cam, 0);
329         }
330         return data;
331 }
332 #endif
333
334 /* Read a register from the i2c device.
335    Expects claimed pdev. -1 on error */
336 #if 0
337 static int w9966_read_reg_i2c(struct w9966 *cam, int reg)
338 {
339         int data;
340
341         w9966_i2c_setsda(cam, 0);
342         w9966_i2c_setscl(cam, 0);
343
344         if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
345             w9966_i2c_wbyte(cam, reg) == -1)
346                 return -1;
347
348         w9966_i2c_setsda(cam, 1);
349         if (w9966_i2c_setscl(cam, 1) == -1)
350                 return -1;
351         w9966_i2c_setsda(cam, 0);
352         w9966_i2c_setscl(cam, 0);
353
354         if (w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1)
355                 return -1;
356         data = w9966_i2c_rbyte(cam);
357         if (data == -1)
358                 return -1;
359
360         w9966_i2c_setsda(cam, 0);
361
362         if (w9966_i2c_setscl(cam, 1) == -1)
363                 return -1;
364         w9966_i2c_setsda(cam, 1);
365
366         return data;
367 }
368 #endif
369
370 /* Write a register to the i2c device.
371    Expects claimed pdev. -1 on error */
372 static int w9966_write_reg_i2c(struct w9966 *cam, int reg, int data)
373 {
374         w9966_i2c_setsda(cam, 0);
375         w9966_i2c_setscl(cam, 0);
376
377         if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
378                         w9966_i2c_wbyte(cam, reg) == -1 ||
379                         w9966_i2c_wbyte(cam, data) == -1)
380                 return -1;
381
382         w9966_i2c_setsda(cam, 0);
383         if (w9966_i2c_setscl(cam, 1) == -1)
384                 return -1;
385
386         w9966_i2c_setsda(cam, 1);
387
388         return 0;
389 }
390
391 /* Find a good length for capture window (used both for W and H)
392    A bit ugly but pretty functional. The capture length
393    have to match the downscale */
394 static int w9966_findlen(int near, int size, int maxlen)
395 {
396         int bestlen = size;
397         int besterr = abs(near - bestlen);
398         int len;
399
400         for (len = size + 1; len < maxlen; len++) {
401                 int err;
402                 if (((64 * size) % len) != 0)
403                         continue;
404
405                 err = abs(near - len);
406
407                 /* Only continue as long as we keep getting better values */
408                 if (err > besterr)
409                         break;
410
411                 besterr = err;
412                 bestlen = len;
413         }
414
415         return bestlen;
416 }
417
418 /* Modify capture window (if necessary)
419    and calculate downscaling
420    Return -1 on error */
421 static int w9966_calcscale(int size, int min, int max, int *beg, int *end, unsigned char *factor)
422 {
423         int maxlen = max - min;
424         int len = *end - *beg + 1;
425         int newlen = w9966_findlen(len, size, maxlen);
426         int err = newlen - len;
427
428         /* Check for bad format */
429         if (newlen > maxlen || newlen < size)
430                 return -1;
431
432         /* Set factor (6 bit fixed) */
433         *factor = (64 * size) / newlen;
434         if (*factor == 64)
435                 *factor = 0x00; /* downscale is disabled */
436         else
437                 *factor |= 0x80; /* set downscale-enable bit */
438
439         /* Modify old beginning and end */
440         *beg -= err / 2;
441         *end += err - (err / 2);
442
443         /* Move window if outside borders */
444         if (*beg < min) {
445                 *end += min - *beg;
446                 *beg += min - *beg;
447         }
448         if (*end > max) {
449                 *beg -= *end - max;
450                 *end -= *end - max;
451         }
452
453         return 0;
454 }
455
456 /* Setup the cameras capture window etc.
457    Expects a claimed pdev
458    return -1 on error */
459 static int w9966_setup(struct w9966 *cam, int x1, int y1, int x2, int y2, int w, int h)
460 {
461         unsigned int i;
462         unsigned int enh_s, enh_e;
463         unsigned char scale_x, scale_y;
464         unsigned char regs[0x1c];
465         unsigned char saa7111_regs[] = {
466                 0x21, 0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00,
467                 0x88, 0x10, 0x80, 0x40, 0x40, 0x00, 0x01, 0x00,
468                 0x48, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469                 0x00, 0x00, 0x00, 0x71, 0xe7, 0x00, 0x00, 0xc0
470         };
471
472
473         if (w * h * 2 > W9966_SRAMSIZE) {
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)
480                 w = 2;
481         if (h < 1)
482                 h = 1;
483         if (w > W9966_WND_MAX_W)
484                 w = W9966_WND_MAX_W;
485         if (h > W9966_WND_MAX_H)
486                 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 (w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
496                         w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0)
497                 return -1;
498
499         DPRINTF("%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
500                         w, h, x1, x2, y1, y2, scale_x & ~0x80, scale_y & ~0x80);
501
502         /* Setup registers */
503         regs[0x00] = 0x00;                      /* Set normal operation */
504         regs[0x01] = 0x18;                      /* Capture mode */
505         regs[0x02] = scale_y;                   /* V-scaling */
506         regs[0x03] = scale_x;                   /* H-scaling */
507
508         /* Capture window */
509         regs[0x04] = (x1 & 0x0ff);              /* X-start (8 low bits) */
510         regs[0x05] = (x1 & 0x300)>>8;           /* X-start (2 high bits) */
511         regs[0x06] = (y1 & 0x0ff);              /* Y-start (8 low bits) */
512         regs[0x07] = (y1 & 0x300)>>8;           /* Y-start (2 high bits) */
513         regs[0x08] = (x2 & 0x0ff);              /* X-end (8 low bits) */
514         regs[0x09] = (x2 & 0x300)>>8;           /* X-end (2 high bits) */
515         regs[0x0a] = (y2 & 0x0ff);              /* Y-end (8 low bits) */
516
517         regs[0x0c] = W9966_SRAMID;              /* SRAM-banks (1x 128kb) */
518
519         /* Enhancement layer */
520         regs[0x0d] = (enh_s & 0x000ff);         /* Enh. start (0-7) */
521         regs[0x0e] = (enh_s & 0x0ff00) >> 8;    /* Enh. start (8-15) */
522         regs[0x0f] = (enh_s & 0x70000) >> 16;   /* Enh. start (16-17/18??) */
523         regs[0x10] = (enh_e & 0x000ff);         /* Enh. end (0-7) */
524         regs[0x11] = (enh_e & 0x0ff00) >> 8;    /* Enh. end (8-15) */
525         regs[0x12] = (enh_e & 0x70000) >> 16;   /* Enh. end (16-17/18??) */
526
527         /* Misc */
528         regs[0x13] = 0x40;                      /* VEE control (raw 4:2:2) */
529         regs[0x17] = 0x00;                      /* ??? */
530         regs[0x18] = cam->i2c_state = 0x00;     /* Serial bus */
531         regs[0x19] = 0xff;                      /* I/O port direction control */
532         regs[0x1a] = 0xff;                      /* I/O port data register */
533         regs[0x1b] = 0x10;                      /* ??? */
534
535         /* SAA7111 chip settings */
536         saa7111_regs[0x0a] = cam->brightness;
537         saa7111_regs[0x0b] = cam->contrast;
538         saa7111_regs[0x0c] = cam->color;
539         saa7111_regs[0x0d] = cam->hue;
540
541         /* Reset (ECP-fifo & serial-bus) */
542         if (w9966_write_reg(cam, 0x00, 0x03) == -1)
543                 return -1;
544
545         /* Write regs to w9966cf chip */
546         for (i = 0; i < 0x1c; i++)
547                 if (w9966_write_reg(cam, i, regs[i]) == -1)
548                         return -1;
549
550         /* Write regs to saa7111 chip */
551         for (i = 0; i < 0x20; i++)
552                 if (w9966_write_reg_i2c(cam, i, saa7111_regs[i]) == -1)
553                         return -1;
554
555         return 0;
556 }
557
558 /*
559  *      Video4linux interfacing
560  */
561
562 static int cam_querycap(struct file *file, void  *priv,
563                                         struct v4l2_capability *vcap)
564 {
565         struct w9966 *cam = video_drvdata(file);
566
567         strlcpy(vcap->driver, cam->v4l2_dev.name, sizeof(vcap->driver));
568         strlcpy(vcap->card, W9966_DRIVERNAME, sizeof(vcap->card));
569         strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
570         vcap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
571         return 0;
572 }
573
574 static int cam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
575 {
576         if (vin->index > 0)
577                 return -EINVAL;
578         strlcpy(vin->name, "Camera", sizeof(vin->name));
579         vin->type = V4L2_INPUT_TYPE_CAMERA;
580         vin->audioset = 0;
581         vin->tuner = 0;
582         vin->std = 0;
583         vin->status = 0;
584         return 0;
585 }
586
587 static int cam_g_input(struct file *file, void *fh, unsigned int *inp)
588 {
589         *inp = 0;
590         return 0;
591 }
592
593 static int cam_s_input(struct file *file, void *fh, unsigned int inp)
594 {
595         return (inp > 0) ? -EINVAL : 0;
596 }
597
598 static int cam_queryctrl(struct file *file, void *priv,
599                                         struct v4l2_queryctrl *qc)
600 {
601         switch (qc->id) {
602         case V4L2_CID_BRIGHTNESS:
603                 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
604         case V4L2_CID_CONTRAST:
605                 return v4l2_ctrl_query_fill(qc, -64, 64, 1, 64);
606         case V4L2_CID_SATURATION:
607                 return v4l2_ctrl_query_fill(qc, -64, 64, 1, 64);
608         case V4L2_CID_HUE:
609                 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
610         }
611         return -EINVAL;
612 }
613
614 static int cam_g_ctrl(struct file *file, void *priv,
615                                         struct v4l2_control *ctrl)
616 {
617         struct w9966 *cam = video_drvdata(file);
618         int ret = 0;
619
620         switch (ctrl->id) {
621         case V4L2_CID_BRIGHTNESS:
622                 ctrl->value = cam->brightness;
623                 break;
624         case V4L2_CID_CONTRAST:
625                 ctrl->value = cam->contrast;
626                 break;
627         case V4L2_CID_SATURATION:
628                 ctrl->value = cam->color;
629                 break;
630         case V4L2_CID_HUE:
631                 ctrl->value = cam->hue;
632                 break;
633         default:
634                 ret = -EINVAL;
635                 break;
636         }
637         return ret;
638 }
639
640 static int cam_s_ctrl(struct file *file, void *priv,
641                                         struct v4l2_control *ctrl)
642 {
643         struct w9966 *cam = video_drvdata(file);
644         int ret = 0;
645
646         mutex_lock(&cam->lock);
647         switch (ctrl->id) {
648         case V4L2_CID_BRIGHTNESS:
649                 cam->brightness = ctrl->value;
650                 break;
651         case V4L2_CID_CONTRAST:
652                 cam->contrast = ctrl->value;
653                 break;
654         case V4L2_CID_SATURATION:
655                 cam->color = ctrl->value;
656                 break;
657         case V4L2_CID_HUE:
658                 cam->hue = ctrl->value;
659                 break;
660         default:
661                 ret = -EINVAL;
662                 break;
663         }
664
665         if (ret == 0) {
666                 w9966_pdev_claim(cam);
667
668                 if (w9966_write_reg_i2c(cam, 0x0a, cam->brightness) == -1 ||
669                     w9966_write_reg_i2c(cam, 0x0b, cam->contrast) == -1 ||
670                     w9966_write_reg_i2c(cam, 0x0c, cam->color) == -1 ||
671                     w9966_write_reg_i2c(cam, 0x0d, cam->hue) == -1) {
672                         ret = -EIO;
673                 }
674
675                 w9966_pdev_release(cam);
676         }
677         mutex_unlock(&cam->lock);
678         return ret;
679 }
680
681 static int cam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
682 {
683         struct w9966 *cam = video_drvdata(file);
684         struct v4l2_pix_format *pix = &fmt->fmt.pix;
685
686         pix->width = cam->width;
687         pix->height = cam->height;
688         pix->pixelformat = V4L2_PIX_FMT_YUYV;
689         pix->field = V4L2_FIELD_NONE;
690         pix->bytesperline = 2 * cam->width;
691         pix->sizeimage = 2 * cam->width * cam->height;
692         /* Just a guess */
693         pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
694         return 0;
695 }
696
697 static int cam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
698 {
699         struct v4l2_pix_format *pix = &fmt->fmt.pix;
700
701         if (pix->width < 2)
702                 pix->width = 2;
703         if (pix->height < 1)
704                 pix->height = 1;
705         if (pix->width > W9966_WND_MAX_W)
706                 pix->width = W9966_WND_MAX_W;
707         if (pix->height > W9966_WND_MAX_H)
708                 pix->height = W9966_WND_MAX_H;
709         pix->pixelformat = V4L2_PIX_FMT_YUYV;
710         pix->field = V4L2_FIELD_NONE;
711         pix->bytesperline = 2 * pix->width;
712         pix->sizeimage = 2 * pix->width * pix->height;
713         /* Just a guess */
714         pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
715         return 0;
716 }
717
718 static int cam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
719 {
720         struct w9966 *cam = video_drvdata(file);
721         struct v4l2_pix_format *pix = &fmt->fmt.pix;
722         int ret = cam_try_fmt_vid_cap(file, fh, fmt);
723
724         if (ret)
725                 return ret;
726
727         mutex_lock(&cam->lock);
728         /* Update camera regs */
729         w9966_pdev_claim(cam);
730         ret = w9966_setup(cam, 0, 0, 1023, 1023, pix->width, pix->height);
731         w9966_pdev_release(cam);
732         mutex_unlock(&cam->lock);
733         return ret;
734 }
735
736 static int cam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
737 {
738         static struct v4l2_fmtdesc formats[] = {
739                 { 0, 0, 0,
740                   "YUV 4:2:2", V4L2_PIX_FMT_YUYV,
741                   { 0, 0, 0, 0 }
742                 },
743         };
744         enum v4l2_buf_type type = fmt->type;
745
746         if (fmt->index > 0)
747                 return -EINVAL;
748
749         *fmt = formats[fmt->index];
750         fmt->type = type;
751         return 0;
752 }
753
754 /* Capture data */
755 static ssize_t w9966_v4l_read(struct file *file, char  __user *buf,
756                 size_t count, loff_t *ppos)
757 {
758         struct w9966 *cam = video_drvdata(file);
759         unsigned char addr = 0xa0;      /* ECP, read, CCD-transfer, 00000 */
760         unsigned char __user *dest = (unsigned char __user *)buf;
761         unsigned long dleft = count;
762         unsigned char *tbuf;
763
764         /* Why would anyone want more than this?? */
765         if (count > cam->width * cam->height * 2)
766                 return -EINVAL;
767
768         mutex_lock(&cam->lock);
769         w9966_pdev_claim(cam);
770         w9966_write_reg(cam, 0x00, 0x02);       /* Reset ECP-FIFO buffer */
771         w9966_write_reg(cam, 0x00, 0x00);       /* Return to normal operation */
772         w9966_write_reg(cam, 0x01, 0x98);       /* Enable capture */
773
774         /* write special capture-addr and negotiate into data transfer */
775         if ((parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0) ||
776                         (parport_write(cam->pport, &addr, 1) != 1) ||
777                         (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0)) {
778                 w9966_pdev_release(cam);
779                 mutex_unlock(&cam->lock);
780                 return -EFAULT;
781         }
782
783         tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
784         if (tbuf == NULL) {
785                 count = -ENOMEM;
786                 goto out;
787         }
788
789         while (dleft > 0) {
790                 unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
791
792                 if (parport_read(cam->pport, tbuf, tsize) < tsize) {
793                         count = -EFAULT;
794                         goto out;
795                 }
796                 if (copy_to_user(dest, tbuf, tsize) != 0) {
797                         count = -EFAULT;
798                         goto out;
799                 }
800                 dest += tsize;
801                 dleft -= tsize;
802         }
803
804         w9966_write_reg(cam, 0x01, 0x18);       /* Disable capture */
805
806 out:
807         kfree(tbuf);
808         w9966_pdev_release(cam);
809         mutex_unlock(&cam->lock);
810
811         return count;
812 }
813
814 static const struct v4l2_file_operations w9966_fops = {
815         .owner          = THIS_MODULE,
816         .unlocked_ioctl = video_ioctl2,
817         .read           = w9966_v4l_read,
818 };
819
820 static const struct v4l2_ioctl_ops w9966_ioctl_ops = {
821         .vidioc_querycap                    = cam_querycap,
822         .vidioc_g_input                     = cam_g_input,
823         .vidioc_s_input                     = cam_s_input,
824         .vidioc_enum_input                  = cam_enum_input,
825         .vidioc_queryctrl                   = cam_queryctrl,
826         .vidioc_g_ctrl                      = cam_g_ctrl,
827         .vidioc_s_ctrl                      = cam_s_ctrl,
828         .vidioc_enum_fmt_vid_cap            = cam_enum_fmt_vid_cap,
829         .vidioc_g_fmt_vid_cap               = cam_g_fmt_vid_cap,
830         .vidioc_s_fmt_vid_cap               = cam_s_fmt_vid_cap,
831         .vidioc_try_fmt_vid_cap             = cam_try_fmt_vid_cap,
832 };
833
834
835 /* Initialize camera device. Setup all internal flags, set a
836    default video mode, setup ccd-chip, register v4l device etc..
837    Also used for 'probing' of hardware.
838    -1 on error */
839 static int w9966_init(struct w9966 *cam, struct parport *port)
840 {
841         struct v4l2_device *v4l2_dev = &cam->v4l2_dev;
842
843         if (cam->dev_state != 0)
844                 return -1;
845
846         strlcpy(v4l2_dev->name, "w9966", sizeof(v4l2_dev->name));
847
848         if (v4l2_device_register(NULL, v4l2_dev) < 0) {
849                 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
850                 return -1;
851         }
852         cam->pport = port;
853         cam->brightness = 128;
854         cam->contrast = 64;
855         cam->color = 64;
856         cam->hue = 0;
857
858         /* Select requested transfer mode */
859         switch (parmode) {
860         default:        /* Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) */
861         case 0:
862                 if (port->modes & PARPORT_MODE_ECP)
863                         cam->ppmode = IEEE1284_MODE_ECP;
864                 else if (port->modes & PARPORT_MODE_EPP)
865                         cam->ppmode = IEEE1284_MODE_EPP;
866                 else
867                         cam->ppmode = IEEE1284_MODE_ECP;
868                 break;
869         case 1:         /* hw- or sw-ecp */
870                 cam->ppmode = IEEE1284_MODE_ECP;
871                 break;
872         case 2:         /* hw- or sw-epp */
873                 cam->ppmode = IEEE1284_MODE_EPP;
874                 break;
875         }
876
877         /* Tell the parport driver that we exists */
878         cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
879         if (cam->pdev == NULL) {
880                 DPRINTF("parport_register_device() failed\n");
881                 return -1;
882         }
883         w9966_set_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
884
885         w9966_pdev_claim(cam);
886
887         /* Setup a default capture mode */
888         if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
889                 DPRINTF("w9966_setup() failed.\n");
890                 return -1;
891         }
892
893         w9966_pdev_release(cam);
894
895         /* Fill in the video_device struct and register us to v4l */
896         strlcpy(cam->vdev.name, W9966_DRIVERNAME, sizeof(cam->vdev.name));
897         cam->vdev.v4l2_dev = v4l2_dev;
898         cam->vdev.fops = &w9966_fops;
899         cam->vdev.ioctl_ops = &w9966_ioctl_ops;
900         cam->vdev.release = video_device_release_empty;
901         video_set_drvdata(&cam->vdev, cam);
902
903         mutex_init(&cam->lock);
904
905         if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
906                 return -1;
907
908         w9966_set_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
909
910         /* All ok */
911         v4l2_info(v4l2_dev, "Found and initialized a webcam on %s.\n",
912                         cam->pport->name);
913         return 0;
914 }
915
916
917 /* Terminate everything gracefully */
918 static void w9966_term(struct w9966 *cam)
919 {
920         /* Unregister from v4l */
921         if (w9966_get_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
922                 video_unregister_device(&cam->vdev);
923                 w9966_set_state(cam, W9966_STATE_VDEV, 0);
924         }
925
926         /* Terminate from IEEE1284 mode and release pdev block */
927         if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
928                 w9966_pdev_claim(cam);
929                 parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
930                 w9966_pdev_release(cam);
931         }
932
933         /* Unregister from parport */
934         if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
935                 parport_unregister_device(cam->pdev);
936                 w9966_set_state(cam, W9966_STATE_PDEV, 0);
937         }
938         memset(cam, 0, sizeof(*cam));
939 }
940
941
942 /* Called once for every parport on init */
943 static void w9966_attach(struct parport *port)
944 {
945         int i;
946
947         for (i = 0; i < W9966_MAXCAMS; i++) {
948                 if (w9966_cams[i].dev_state != 0)       /* Cam is already assigned */
949                         continue;
950                 if (strcmp(pardev[i], "aggressive") == 0 || strcmp(pardev[i], port->name) == 0) {
951                         if (w9966_init(&w9966_cams[i], port) != 0)
952                                 w9966_term(&w9966_cams[i]);
953                         break;  /* return */
954                 }
955         }
956 }
957
958 /* Called once for every parport on termination */
959 static void w9966_detach(struct parport *port)
960 {
961         int i;
962
963         for (i = 0; i < W9966_MAXCAMS; i++)
964                 if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
965                         w9966_term(&w9966_cams[i]);
966 }
967
968
969 static struct parport_driver w9966_ppd = {
970         .name = W9966_DRIVERNAME,
971         .attach = w9966_attach,
972         .detach = w9966_detach,
973 };
974
975 /* Module entry point */
976 static int __init w9966_mod_init(void)
977 {
978         int i;
979
980         for (i = 0; i < W9966_MAXCAMS; i++)
981                 w9966_cams[i].dev_state = 0;
982
983         return parport_register_driver(&w9966_ppd);
984 }
985
986 /* Module cleanup */
987 static void __exit w9966_mod_term(void)
988 {
989         parport_unregister_driver(&w9966_ppd);
990 }
991
992 module_init(w9966_mod_init);
993 module_exit(w9966_mod_term);