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