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