Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
w9966.c
Go to the documentation of this file.
1 /*
2  Winbond w9966cf Webcam parport driver.
3 
4  Version 0.33
5 
6  Copyright (C) 2001 Jakob Kemi <[email protected]>
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 /*
23  Supported devices:
24  *Lifeview FlyCam Supra (using the Philips saa7111a chip)
25 
26  Does any other model using the w9966 interface chip exist ?
27 
28  Todo:
29 
30  *Add a working EPP mode, since DMA ECP read isn't implemented
31  in the parport drivers. (That's why it's so sloow)
32 
33  *Add support for other ccd-control chips than the saa7111
34  please send me feedback on what kind of chips you have.
35 
36  *Add proper probing. I don't know what's wrong with the IEEE1284
37  parport drivers but (IEEE1284_MODE_NIBBLE|IEEE1284_DEVICE_ID)
38  and nibble read seems to be broken for some peripherals.
39 
40  *Add probing for onboard SRAM, port directions etc. (if possible)
41 
42  *Add support for the hardware compressed modes (maybe using v4l2)
43 
44  *Fix better support for the capture window (no skewed images, v4l
45  interface to capt. window)
46 
47  *Probably some bugs that I don't know of
48 
49  Please support me by sending feedback!
50 
51  Changes:
52 
53  Alan Cox: Removed RGB mode for kernel merge, added THIS_MODULE
54  and owner support for newer module locks
55 */
56 
57 #include <linux/module.h>
58 #include <linux/init.h>
59 #include <linux/delay.h>
60 #include <linux/videodev2.h>
61 #include <linux/slab.h>
62 #include <media/v4l2-common.h>
63 #include <media/v4l2-ioctl.h>
64 #include <media/v4l2-device.h>
65 #include <media/v4l2-fh.h>
66 #include <media/v4l2-ctrls.h>
67 #include <media/v4l2-event.h>
68 #include <linux/parport.h>
69 
70 /*#define DEBUG*/ /* Undef me for production */
71 
72 #ifdef DEBUG
73 #define DPRINTF(x, a...) printk(KERN_DEBUG "W9966: %s(): "x, __func__ , ##a)
74 #else
75 #define DPRINTF(x...)
76 #endif
77 
78 /*
79  * Defines, simple typedefs etc.
80  */
81 
82 #define W9966_DRIVERNAME "W9966CF Webcam"
83 #define W9966_MAXCAMS 4 /* Maximum number of cameras */
84 #define W9966_RBUFFER 2048 /* Read buffer (must be an even number) */
85 #define W9966_SRAMSIZE 131072 /* 128kb */
86 #define W9966_SRAMID 0x02 /* check w9966cf.pdf */
87 
88 /* Empirically determined window limits */
89 #define W9966_WND_MIN_X 16
90 #define W9966_WND_MIN_Y 14
91 #define W9966_WND_MAX_X 705
92 #define W9966_WND_MAX_Y 253
93 #define W9966_WND_MAX_W (W9966_WND_MAX_X - W9966_WND_MIN_X)
94 #define W9966_WND_MAX_H (W9966_WND_MAX_Y - W9966_WND_MIN_Y)
95 
96 /* Keep track of our current state */
97 #define W9966_STATE_PDEV 0x01
98 #define W9966_STATE_CLAIMED 0x02
99 #define W9966_STATE_VDEV 0x04
100 
101 #define W9966_I2C_W_ID 0x48
102 #define W9966_I2C_R_ID 0x49
103 #define W9966_I2C_R_DATA 0x08
104 #define W9966_I2C_R_CLOCK 0x04
105 #define W9966_I2C_W_DATA 0x02
106 #define W9966_I2C_W_CLOCK 0x01
107 
108 struct w9966 {
111  unsigned char dev_state;
112  unsigned char i2c_state;
113  unsigned short ppmode;
114  struct parport *pport;
115  struct pardevice *pdev;
117  unsigned short width;
118  unsigned short height;
119  unsigned char brightness;
120  signed char contrast;
121  signed char color;
122  signed char hue;
123  struct mutex lock;
124 };
125 
126 /*
127  * Module specific properties
128  */
129 
130 MODULE_AUTHOR("Jakob Kemi <[email protected]>");
131 MODULE_DESCRIPTION("Winbond w9966cf WebCam driver (0.32)");
132 MODULE_LICENSE("GPL");
133 MODULE_VERSION("0.33.1");
134 
135 #ifdef MODULE
136 static char *pardev[] = {[0 ... W9966_MAXCAMS] = ""};
137 #else
138 static char *pardev[] = {[0 ... W9966_MAXCAMS] = "aggressive"};
139 #endif
140 module_param_array(pardev, charp, NULL, 0);
141 MODULE_PARM_DESC(pardev, "pardev: where to search for\n"
142  "\teach camera. 'aggressive' means brute-force search.\n"
143  "\tEg: >pardev=parport3,aggressive,parport2,parport1< would assign\n"
144  "\tcam 1 to parport3 and search every parport for cam 2 etc...");
145 
146 static int parmode;
147 module_param(parmode, int, 0);
148 MODULE_PARM_DESC(parmode, "parmode: transfer mode (0=auto, 1=ecp, 2=epp");
149 
150 static int video_nr = -1;
151 module_param(video_nr, int, 0);
152 
153 static struct w9966 w9966_cams[W9966_MAXCAMS];
154 
155 /*
156  * Private function defines
157  */
158 
159 
160 /* Set camera phase flags, so we know what to uninit when terminating */
161 static inline void w9966_set_state(struct w9966 *cam, int mask, int val)
162 {
163  cam->dev_state = (cam->dev_state & ~mask) ^ val;
164 }
165 
166 /* Get camera phase flags */
167 static inline int w9966_get_state(struct w9966 *cam, int mask, int val)
168 {
169  return ((cam->dev_state & mask) == val);
170 }
171 
172 /* Claim parport for ourself */
173 static void w9966_pdev_claim(struct w9966 *cam)
174 {
175  if (w9966_get_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
176  return;
178  w9966_set_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
179 }
180 
181 /* Release parport for others to use */
182 static void w9966_pdev_release(struct w9966 *cam)
183 {
184  if (w9966_get_state(cam, W9966_STATE_CLAIMED, 0))
185  return;
186  parport_release(cam->pdev);
187  w9966_set_state(cam, W9966_STATE_CLAIMED, 0);
188 }
189 
190 /* Read register from W9966 interface-chip
191  Expects a claimed pdev
192  -1 on error, else register data (byte) */
193 static int w9966_read_reg(struct w9966 *cam, int reg)
194 {
195  /* ECP, read, regtransfer, REG, REG, REG, REG, REG */
196  const unsigned char addr = 0x80 | (reg & 0x1f);
197  unsigned char val;
198 
199  if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
200  return -1;
201  if (parport_write(cam->pport, &addr, 1) != 1)
202  return -1;
203  if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
204  return -1;
205  if (parport_read(cam->pport, &val, 1) != 1)
206  return -1;
207 
208  return val;
209 }
210 
211 /* Write register to W9966 interface-chip
212  Expects a claimed pdev
213  -1 on error */
214 static int w9966_write_reg(struct w9966 *cam, int reg, int data)
215 {
216  /* ECP, write, regtransfer, REG, REG, REG, REG, REG */
217  const unsigned char addr = 0xc0 | (reg & 0x1f);
218  const unsigned char val = data;
219 
220  if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0)
221  return -1;
222  if (parport_write(cam->pport, &addr, 1) != 1)
223  return -1;
224  if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0)
225  return -1;
226  if (parport_write(cam->pport, &val, 1) != 1)
227  return -1;
228 
229  return 0;
230 }
231 
232 /*
233  * Ugly and primitive i2c protocol functions
234  */
235 
236 /* Sets the data line on the i2c bus.
237  Expects a claimed pdev. */
238 static void w9966_i2c_setsda(struct w9966 *cam, int state)
239 {
240  if (state)
241  cam->i2c_state |= W9966_I2C_W_DATA;
242  else
243  cam->i2c_state &= ~W9966_I2C_W_DATA;
244 
245  w9966_write_reg(cam, 0x18, cam->i2c_state);
246  udelay(5);
247 }
248 
249 /* Get peripheral clock line
250  Expects a claimed pdev. */
251 static int w9966_i2c_getscl(struct w9966 *cam)
252 {
253  const unsigned char state = w9966_read_reg(cam, 0x18);
254  return ((state & W9966_I2C_R_CLOCK) > 0);
255 }
256 
257 /* Sets the clock line on the i2c bus.
258  Expects a claimed pdev. -1 on error */
259 static int w9966_i2c_setscl(struct w9966 *cam, int state)
260 {
261  unsigned long timeout;
262 
263  if (state)
265  else
266  cam->i2c_state &= ~W9966_I2C_W_CLOCK;
267 
268  w9966_write_reg(cam, 0x18, cam->i2c_state);
269  udelay(5);
270 
271  /* we go to high, we also expect the peripheral to ack. */
272  if (state) {
273  timeout = jiffies + 100;
274  while (!w9966_i2c_getscl(cam)) {
275  if (time_after(jiffies, timeout))
276  return -1;
277  }
278  }
279  return 0;
280 }
281 
282 #if 0
283 /* Get peripheral data line
284  Expects a claimed pdev. */
285 static int w9966_i2c_getsda(struct w9966 *cam)
286 {
287  const unsigned char state = w9966_read_reg(cam, 0x18);
288  return ((state & W9966_I2C_R_DATA) > 0);
289 }
290 #endif
291 
292 /* Write a byte with ack to the i2c bus.
293  Expects a claimed pdev. -1 on error */
294 static int w9966_i2c_wbyte(struct w9966 *cam, int data)
295 {
296  int i;
297 
298  for (i = 7; i >= 0; i--) {
299  w9966_i2c_setsda(cam, (data >> i) & 0x01);
300 
301  if (w9966_i2c_setscl(cam, 1) == -1)
302  return -1;
303  w9966_i2c_setscl(cam, 0);
304  }
305 
306  w9966_i2c_setsda(cam, 1);
307 
308  if (w9966_i2c_setscl(cam, 1) == -1)
309  return -1;
310  w9966_i2c_setscl(cam, 0);
311 
312  return 0;
313 }
314 
315 /* Read a data byte with ack from the i2c-bus
316  Expects a claimed pdev. -1 on error */
317 #if 0
318 static int w9966_i2c_rbyte(struct w9966 *cam)
319 {
320  unsigned char data = 0x00;
321  int i;
322 
323  w9966_i2c_setsda(cam, 1);
324 
325  for (i = 0; i < 8; i++) {
326  if (w9966_i2c_setscl(cam, 1) == -1)
327  return -1;
328  data = data << 1;
329  if (w9966_i2c_getsda(cam))
330  data |= 0x01;
331 
332  w9966_i2c_setscl(cam, 0);
333  }
334  return data;
335 }
336 #endif
337 
338 /* Read a register from the i2c device.
339  Expects claimed pdev. -1 on error */
340 #if 0
341 static int w9966_read_reg_i2c(struct w9966 *cam, int reg)
342 {
343  int data;
344 
345  w9966_i2c_setsda(cam, 0);
346  w9966_i2c_setscl(cam, 0);
347 
348  if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
349  w9966_i2c_wbyte(cam, reg) == -1)
350  return -1;
351 
352  w9966_i2c_setsda(cam, 1);
353  if (w9966_i2c_setscl(cam, 1) == -1)
354  return -1;
355  w9966_i2c_setsda(cam, 0);
356  w9966_i2c_setscl(cam, 0);
357 
358  if (w9966_i2c_wbyte(cam, W9966_I2C_R_ID) == -1)
359  return -1;
360  data = w9966_i2c_rbyte(cam);
361  if (data == -1)
362  return -1;
363 
364  w9966_i2c_setsda(cam, 0);
365 
366  if (w9966_i2c_setscl(cam, 1) == -1)
367  return -1;
368  w9966_i2c_setsda(cam, 1);
369 
370  return data;
371 }
372 #endif
373 
374 /* Write a register to the i2c device.
375  Expects claimed pdev. -1 on error */
376 static int w9966_write_reg_i2c(struct w9966 *cam, int reg, int data)
377 {
378  w9966_i2c_setsda(cam, 0);
379  w9966_i2c_setscl(cam, 0);
380 
381  if (w9966_i2c_wbyte(cam, W9966_I2C_W_ID) == -1 ||
382  w9966_i2c_wbyte(cam, reg) == -1 ||
383  w9966_i2c_wbyte(cam, data) == -1)
384  return -1;
385 
386  w9966_i2c_setsda(cam, 0);
387  if (w9966_i2c_setscl(cam, 1) == -1)
388  return -1;
389 
390  w9966_i2c_setsda(cam, 1);
391 
392  return 0;
393 }
394 
395 /* Find a good length for capture window (used both for W and H)
396  A bit ugly but pretty functional. The capture length
397  have to match the downscale */
398 static int w9966_findlen(int near, int size, int maxlen)
399 {
400  int bestlen = size;
401  int besterr = abs(near - bestlen);
402  int len;
403 
404  for (len = size + 1; len < maxlen; len++) {
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 *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  DPRINTF("capture window exceeds SRAM size!.\n");
479  w = 200; h = 160; /* Pick default values */
480  }
481 
482  w &= ~0x1;
483  if (w < 2)
484  w = 2;
485  if (h < 1)
486  h = 1;
487  if (w > W9966_WND_MAX_W)
488  w = W9966_WND_MAX_W;
489  if (h > W9966_WND_MAX_H)
490  h = W9966_WND_MAX_H;
491 
492  cam->width = w;
493  cam->height = h;
494 
495  enh_s = 0;
496  enh_e = w * h * 2;
497 
498  /* Modify capture window if necessary and calculate downscaling */
499  if (w9966_calcscale(w, W9966_WND_MIN_X, W9966_WND_MAX_X, &x1, &x2, &scale_x) != 0 ||
500  w9966_calcscale(h, W9966_WND_MIN_Y, W9966_WND_MAX_Y, &y1, &y2, &scale_y) != 0)
501  return -1;
502 
503  DPRINTF("%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
504  w, h, x1, x2, y1, y2, scale_x & ~0x80, scale_y & ~0x80);
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_write_reg(cam, 0x00, 0x03) == -1)
547  return -1;
548 
549  /* Write regs to w9966cf chip */
550  for (i = 0; i < 0x1c; i++)
551  if (w9966_write_reg(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_write_reg_i2c(cam, i, saa7111_regs[i]) == -1)
557  return -1;
558 
559  return 0;
560 }
561 
562 /*
563  * Video4linux interfacing
564  */
565 
566 static int cam_querycap(struct file *file, void *priv,
567  struct v4l2_capability *vcap)
568 {
569  struct w9966 *cam = video_drvdata(file);
570 
571  strlcpy(vcap->driver, cam->v4l2_dev.name, sizeof(vcap->driver));
572  strlcpy(vcap->card, W9966_DRIVERNAME, sizeof(vcap->card));
573  strlcpy(vcap->bus_info, "parport", sizeof(vcap->bus_info));
576  return 0;
577 }
578 
579 static int cam_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
580 {
581  if (vin->index > 0)
582  return -EINVAL;
583  strlcpy(vin->name, "Camera", sizeof(vin->name));
585  vin->audioset = 0;
586  vin->tuner = 0;
587  vin->std = 0;
588  vin->status = 0;
589  return 0;
590 }
591 
592 static int cam_g_input(struct file *file, void *fh, unsigned int *inp)
593 {
594  *inp = 0;
595  return 0;
596 }
597 
598 static int cam_s_input(struct file *file, void *fh, unsigned int inp)
599 {
600  return (inp > 0) ? -EINVAL : 0;
601 }
602 
603 static int cam_s_ctrl(struct v4l2_ctrl *ctrl)
604 {
605  struct w9966 *cam =
606  container_of(ctrl->handler, struct w9966, hdl);
607  int ret = 0;
608 
609  mutex_lock(&cam->lock);
610  switch (ctrl->id) {
611  case V4L2_CID_BRIGHTNESS:
612  cam->brightness = ctrl->val;
613  break;
614  case V4L2_CID_CONTRAST:
615  cam->contrast = ctrl->val;
616  break;
617  case V4L2_CID_SATURATION:
618  cam->color = ctrl->val;
619  break;
620  case V4L2_CID_HUE:
621  cam->hue = ctrl->val;
622  break;
623  default:
624  ret = -EINVAL;
625  break;
626  }
627 
628  if (ret == 0) {
629  w9966_pdev_claim(cam);
630 
631  if (w9966_write_reg_i2c(cam, 0x0a, cam->brightness) == -1 ||
632  w9966_write_reg_i2c(cam, 0x0b, cam->contrast) == -1 ||
633  w9966_write_reg_i2c(cam, 0x0c, cam->color) == -1 ||
634  w9966_write_reg_i2c(cam, 0x0d, cam->hue) == -1) {
635  ret = -EIO;
636  }
637 
638  w9966_pdev_release(cam);
639  }
640  mutex_unlock(&cam->lock);
641  return ret;
642 }
643 
644 static int cam_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
645 {
646  struct w9966 *cam = video_drvdata(file);
647  struct v4l2_pix_format *pix = &fmt->fmt.pix;
648 
649  pix->width = cam->width;
650  pix->height = cam->height;
652  pix->field = V4L2_FIELD_NONE;
653  pix->bytesperline = 2 * cam->width;
654  pix->sizeimage = 2 * cam->width * cam->height;
655  /* Just a guess */
657  return 0;
658 }
659 
660 static int cam_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
661 {
662  struct v4l2_pix_format *pix = &fmt->fmt.pix;
663 
664  if (pix->width < 2)
665  pix->width = 2;
666  if (pix->height < 1)
667  pix->height = 1;
668  if (pix->width > W9966_WND_MAX_W)
669  pix->width = W9966_WND_MAX_W;
670  if (pix->height > W9966_WND_MAX_H)
671  pix->height = W9966_WND_MAX_H;
673  pix->field = V4L2_FIELD_NONE;
674  pix->bytesperline = 2 * pix->width;
675  pix->sizeimage = 2 * pix->width * pix->height;
676  /* Just a guess */
678  return 0;
679 }
680 
681 static int cam_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
682 {
683  struct w9966 *cam = video_drvdata(file);
684  struct v4l2_pix_format *pix = &fmt->fmt.pix;
685  int ret = cam_try_fmt_vid_cap(file, fh, fmt);
686 
687  if (ret)
688  return ret;
689 
690  mutex_lock(&cam->lock);
691  /* Update camera regs */
692  w9966_pdev_claim(cam);
693  ret = w9966_setup(cam, 0, 0, 1023, 1023, pix->width, pix->height);
694  w9966_pdev_release(cam);
695  mutex_unlock(&cam->lock);
696  return ret;
697 }
698 
699 static int cam_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
700 {
701  static struct v4l2_fmtdesc formats[] = {
702  { 0, 0, 0,
703  "YUV 4:2:2", V4L2_PIX_FMT_YUYV,
704  { 0, 0, 0, 0 }
705  },
706  };
707  enum v4l2_buf_type type = fmt->type;
708 
709  if (fmt->index > 0)
710  return -EINVAL;
711 
712  *fmt = formats[fmt->index];
713  fmt->type = type;
714  return 0;
715 }
716 
717 /* Capture data */
718 static ssize_t w9966_v4l_read(struct file *file, char __user *buf,
719  size_t count, loff_t *ppos)
720 {
721  struct w9966 *cam = video_drvdata(file);
722  unsigned char addr = 0xa0; /* ECP, read, CCD-transfer, 00000 */
723  unsigned char __user *dest = (unsigned char __user *)buf;
724  unsigned long dleft = count;
725  unsigned char *tbuf;
726 
727  /* Why would anyone want more than this?? */
728  if (count > cam->width * cam->height * 2)
729  return -EINVAL;
730 
731  mutex_lock(&cam->lock);
732  w9966_pdev_claim(cam);
733  w9966_write_reg(cam, 0x00, 0x02); /* Reset ECP-FIFO buffer */
734  w9966_write_reg(cam, 0x00, 0x00); /* Return to normal operation */
735  w9966_write_reg(cam, 0x01, 0x98); /* Enable capture */
736 
737  /* write special capture-addr and negotiate into data transfer */
738  if ((parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0) ||
739  (parport_write(cam->pport, &addr, 1) != 1) ||
740  (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0)) {
741  w9966_pdev_release(cam);
742  mutex_unlock(&cam->lock);
743  return -EFAULT;
744  }
745 
747  if (tbuf == NULL) {
748  count = -ENOMEM;
749  goto out;
750  }
751 
752  while (dleft > 0) {
753  unsigned long tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
754 
755  if (parport_read(cam->pport, tbuf, tsize) < tsize) {
756  count = -EFAULT;
757  goto out;
758  }
759  if (copy_to_user(dest, tbuf, tsize) != 0) {
760  count = -EFAULT;
761  goto out;
762  }
763  dest += tsize;
764  dleft -= tsize;
765  }
766 
767  w9966_write_reg(cam, 0x01, 0x18); /* Disable capture */
768 
769 out:
770  kfree(tbuf);
771  w9966_pdev_release(cam);
772  mutex_unlock(&cam->lock);
773 
774  return count;
775 }
776 
777 static const struct v4l2_file_operations w9966_fops = {
778  .owner = THIS_MODULE,
779  .open = v4l2_fh_open,
780  .release = v4l2_fh_release,
781  .poll = v4l2_ctrl_poll,
782  .unlocked_ioctl = video_ioctl2,
783  .read = w9966_v4l_read,
784 };
785 
786 static const struct v4l2_ioctl_ops w9966_ioctl_ops = {
787  .vidioc_querycap = cam_querycap,
788  .vidioc_g_input = cam_g_input,
789  .vidioc_s_input = cam_s_input,
790  .vidioc_enum_input = cam_enum_input,
791  .vidioc_enum_fmt_vid_cap = cam_enum_fmt_vid_cap,
792  .vidioc_g_fmt_vid_cap = cam_g_fmt_vid_cap,
793  .vidioc_s_fmt_vid_cap = cam_s_fmt_vid_cap,
794  .vidioc_try_fmt_vid_cap = cam_try_fmt_vid_cap,
795  .vidioc_log_status = v4l2_ctrl_log_status,
796  .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
797  .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
798 };
799 
800 static const struct v4l2_ctrl_ops cam_ctrl_ops = {
801  .s_ctrl = cam_s_ctrl,
802 };
803 
804 
805 /* Initialize camera device. Setup all internal flags, set a
806  default video mode, setup ccd-chip, register v4l device etc..
807  Also used for 'probing' of hardware.
808  -1 on error */
809 static int w9966_init(struct w9966 *cam, struct parport *port)
810 {
811  struct v4l2_device *v4l2_dev = &cam->v4l2_dev;
812 
813  if (cam->dev_state != 0)
814  return -1;
815 
816  strlcpy(v4l2_dev->name, "w9966", sizeof(v4l2_dev->name));
817 
818  if (v4l2_device_register(NULL, v4l2_dev) < 0) {
819  v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
820  return -1;
821  }
822 
823  v4l2_ctrl_handler_init(&cam->hdl, 4);
824  v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
825  V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
826  v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
827  V4L2_CID_CONTRAST, -64, 64, 1, 64);
828  v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
829  V4L2_CID_SATURATION, -64, 64, 1, 64);
830  v4l2_ctrl_new_std(&cam->hdl, &cam_ctrl_ops,
831  V4L2_CID_HUE, -128, 127, 1, 0);
832  if (cam->hdl.error) {
833  v4l2_err(v4l2_dev, "couldn't register controls\n");
834  return -1;
835  }
836  cam->pport = port;
837  cam->brightness = 128;
838  cam->contrast = 64;
839  cam->color = 64;
840  cam->hue = 0;
841 
842  /* Select requested transfer mode */
843  switch (parmode) {
844  default: /* Auto-detect (priority: hw-ecp, hw-epp, sw-ecp) */
845  case 0:
846  if (port->modes & PARPORT_MODE_ECP)
847  cam->ppmode = IEEE1284_MODE_ECP;
848  else if (port->modes & PARPORT_MODE_EPP)
849  cam->ppmode = IEEE1284_MODE_EPP;
850  else
851  cam->ppmode = IEEE1284_MODE_ECP;
852  break;
853  case 1: /* hw- or sw-ecp */
854  cam->ppmode = IEEE1284_MODE_ECP;
855  break;
856  case 2: /* hw- or sw-epp */
857  cam->ppmode = IEEE1284_MODE_EPP;
858  break;
859  }
860 
861  /* Tell the parport driver that we exists */
862  cam->pdev = parport_register_device(port, "w9966", NULL, NULL, NULL, 0, NULL);
863  if (cam->pdev == NULL) {
864  DPRINTF("parport_register_device() failed\n");
865  return -1;
866  }
867  w9966_set_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV);
868 
869  w9966_pdev_claim(cam);
870 
871  /* Setup a default capture mode */
872  if (w9966_setup(cam, 0, 0, 1023, 1023, 200, 160) != 0) {
873  DPRINTF("w9966_setup() failed.\n");
874  return -1;
875  }
876 
877  w9966_pdev_release(cam);
878 
879  /* Fill in the video_device struct and register us to v4l */
880  strlcpy(cam->vdev.name, W9966_DRIVERNAME, sizeof(cam->vdev.name));
881  cam->vdev.v4l2_dev = v4l2_dev;
882  cam->vdev.fops = &w9966_fops;
883  cam->vdev.ioctl_ops = &w9966_ioctl_ops;
884  cam->vdev.release = video_device_release_empty;
885  cam->vdev.ctrl_handler = &cam->hdl;
886  set_bit(V4L2_FL_USE_FH_PRIO, &cam->vdev.flags);
887  video_set_drvdata(&cam->vdev, cam);
888 
889  mutex_init(&cam->lock);
890 
891  if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
892  return -1;
893 
894  w9966_set_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV);
895 
896  /* All ok */
897  v4l2_info(v4l2_dev, "Found and initialized a webcam on %s.\n",
898  cam->pport->name);
899  return 0;
900 }
901 
902 
903 /* Terminate everything gracefully */
904 static void w9966_term(struct w9966 *cam)
905 {
906  /* Unregister from v4l */
907  if (w9966_get_state(cam, W9966_STATE_VDEV, W9966_STATE_VDEV)) {
909  w9966_set_state(cam, W9966_STATE_VDEV, 0);
910  }
911 
913 
914  /* Terminate from IEEE1284 mode and release pdev block */
915  if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
916  w9966_pdev_claim(cam);
918  w9966_pdev_release(cam);
919  }
920 
921  /* Unregister from parport */
922  if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
924  w9966_set_state(cam, W9966_STATE_PDEV, 0);
925  }
926  memset(cam, 0, sizeof(*cam));
927 }
928 
929 
930 /* Called once for every parport on init */
931 static void w9966_attach(struct parport *port)
932 {
933  int i;
934 
935  for (i = 0; i < W9966_MAXCAMS; i++) {
936  if (w9966_cams[i].dev_state != 0) /* Cam is already assigned */
937  continue;
938  if (strcmp(pardev[i], "aggressive") == 0 || strcmp(pardev[i], port->name) == 0) {
939  if (w9966_init(&w9966_cams[i], port) != 0)
940  w9966_term(&w9966_cams[i]);
941  break; /* return */
942  }
943  }
944 }
945 
946 /* Called once for every parport on termination */
947 static void w9966_detach(struct parport *port)
948 {
949  int i;
950 
951  for (i = 0; i < W9966_MAXCAMS; i++)
952  if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
953  w9966_term(&w9966_cams[i]);
954 }
955 
956 
957 static struct parport_driver w9966_ppd = {
958  .name = W9966_DRIVERNAME,
959  .attach = w9966_attach,
960  .detach = w9966_detach,
961 };
962 
963 /* Module entry point */
964 static int __init w9966_mod_init(void)
965 {
966  int i;
967 
968  for (i = 0; i < W9966_MAXCAMS; i++)
969  w9966_cams[i].dev_state = 0;
970 
971  return parport_register_driver(&w9966_ppd);
972 }
973 
974 /* Module cleanup */
975 static void __exit w9966_mod_term(void)
976 {
977  parport_unregister_driver(&w9966_ppd);
978 }
979 
980 module_init(w9966_mod_init);
981 module_exit(w9966_mod_term);