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