• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 	Winbond w9966cf Webcam parport driver.
3 
4 	Version 0.33
5 
6 	Copyright (C) 2001 Jakob Kemi <jakob.kemi@post.utfors.se>
7 
8 	This program is free software; you can redistribute it and/or modify
9 	it under the terms of the GNU General Public License as published by
10 	the Free Software Foundation; either version 2 of the License, or
11 	(at your option) any later version.
12 
13 	This program is distributed in the hope that it will be useful,
14 	but WITHOUT ANY WARRANTY; without even the implied warranty of
15 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 	GNU General Public License for more details.
17 
18 	You should have received a copy of the GNU General Public License
19 	along with this program; if not, write to the Free Software
20 	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 /*
23 	Supported devices:
24 	*Lifeview FlyCam Supra (using the Philips saa7111a chip)
25 
26 	Does any other model using the w9966 interface chip exist ?
27 
28 	Todo:
29 
30 	*Add a working EPP mode, since DMA ECP read isn't implemented
31 	in the parport drivers. (That's why it's so sloow)
32 
33 	*Add support for other ccd-control chips than the saa7111
34 	please send me feedback on what kind of chips you have.
35 
36 	*Add proper probing. I don't know what's wrong with the IEEE1284
37 	parport drivers but (IEEE1284_MODE_NIBBLE|IEEE1284_DEVICE_ID)
38 	and nibble read seems to be broken for some peripherals.
39 
40 	*Add probing for onboard SRAM, port directions etc. (if possible)
41 
42 	*Add support for the hardware compressed modes (maybe using v4l2)
43 
44 	*Fix better support for the capture window (no skewed images, v4l
45 	interface to capt. window)
46 
47 	*Probably some bugs that I don't know of
48 
49 	Please support me by sending feedback!
50 
51 	Changes:
52 
53 	Alan Cox:	Removed RGB mode for kernel merge, added THIS_MODULE
54 			and owner support for newer module locks
55 */
56 
57 #include <linux/module.h>
58 #include <linux/init.h>
59 #include <linux/delay.h>
60 #include <linux/videodev2.h>
61 #include <linux/slab.h>
62 #include <media/v4l2-common.h>
63 #include <media/v4l2-ioctl.h>
64 #include <media/v4l2-device.h>
65 #include <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 {
109 	struct v4l2_device v4l2_dev;
110 	struct v4l2_ctrl_handler hdl;
111 	unsigned char dev_state;
112 	unsigned char i2c_state;
113 	unsigned short ppmode;
114 	struct parport *pport;
115 	struct pardevice *pdev;
116 	struct video_device vdev;
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 <jakob.kemi@post.utfors.se>");
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 */
w9966_set_state(struct w9966 * cam,int mask,int val)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 */
w9966_get_state(struct w9966 * cam,int mask,int val)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 */
w9966_pdev_claim(struct w9966 * cam)173 static void w9966_pdev_claim(struct w9966 *cam)
174 {
175 	if (w9966_get_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED))
176 		return;
177 	parport_claim_or_block(cam->pdev);
178 	w9966_set_state(cam, W9966_STATE_CLAIMED, W9966_STATE_CLAIMED);
179 }
180 
181 /* Release parport for others to use */
w9966_pdev_release(struct w9966 * cam)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) */
w9966_read_reg(struct w9966 * cam,int reg)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 */
w9966_write_reg(struct w9966 * cam,int reg,int data)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. */
w9966_i2c_setsda(struct w9966 * cam,int state)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. */
w9966_i2c_getscl(struct w9966 * cam)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 */
w9966_i2c_setscl(struct w9966 * cam,int state)259 static int w9966_i2c_setscl(struct w9966 *cam, int state)
260 {
261 	unsigned long timeout;
262 
263 	if (state)
264 		cam->i2c_state |= W9966_I2C_W_CLOCK;
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 */
w9966_i2c_wbyte(struct w9966 * cam,int data)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 */
w9966_write_reg_i2c(struct w9966 * cam,int reg,int data)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 */
w9966_findlen(int near,int size,int maxlen)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 */
w9966_calcscale(int size,int min,int max,int * beg,int * end,unsigned char * factor)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 */
w9966_setup(struct w9966 * cam,int x1,int y1,int x2,int y2,int w,int h)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 
cam_querycap(struct file * file,void * priv,struct v4l2_capability * vcap)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));
574 	vcap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
575 	vcap->capabilities = vcap->device_caps | V4L2_CAP_DEVICE_CAPS;
576 	return 0;
577 }
578 
cam_enum_input(struct file * file,void * fh,struct v4l2_input * vin)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));
584 	vin->type = V4L2_INPUT_TYPE_CAMERA;
585 	vin->audioset = 0;
586 	vin->tuner = 0;
587 	vin->std = 0;
588 	vin->status = 0;
589 	return 0;
590 }
591 
cam_g_input(struct file * file,void * fh,unsigned int * inp)592 static int cam_g_input(struct file *file, void *fh, unsigned int *inp)
593 {
594 	*inp = 0;
595 	return 0;
596 }
597 
cam_s_input(struct file * file,void * fh,unsigned int inp)598 static int cam_s_input(struct file *file, void *fh, unsigned int inp)
599 {
600 	return (inp > 0) ? -EINVAL : 0;
601 }
602 
cam_s_ctrl(struct v4l2_ctrl * ctrl)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 
cam_g_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)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;
651 	pix->pixelformat = V4L2_PIX_FMT_YUYV;
652 	pix->field = V4L2_FIELD_NONE;
653 	pix->bytesperline = 2 * cam->width;
654 	pix->sizeimage = 2 * cam->width * cam->height;
655 	/* Just a guess */
656 	pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
657 	return 0;
658 }
659 
cam_try_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)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;
672 	pix->pixelformat = V4L2_PIX_FMT_YUYV;
673 	pix->field = V4L2_FIELD_NONE;
674 	pix->bytesperline = 2 * pix->width;
675 	pix->sizeimage = 2 * pix->width * pix->height;
676 	/* Just a guess */
677 	pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
678 	return 0;
679 }
680 
cam_s_fmt_vid_cap(struct file * file,void * fh,struct v4l2_format * fmt)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 
cam_enum_fmt_vid_cap(struct file * file,void * fh,struct v4l2_fmtdesc * fmt)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 */
w9966_v4l_read(struct file * file,char __user * buf,size_t count,loff_t * ppos)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 
746 	tbuf = kmalloc(W9966_RBUFFER, GFP_KERNEL);
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 */
w9966_init(struct w9966 * cam,struct parport * port)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 */
w9966_term(struct w9966 * cam)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)) {
908 		video_unregister_device(&cam->vdev);
909 		w9966_set_state(cam, W9966_STATE_VDEV, 0);
910 	}
911 
912 	v4l2_ctrl_handler_free(&cam->hdl);
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);
917 		parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
918 		w9966_pdev_release(cam);
919 	}
920 
921 	/* Unregister from parport */
922 	if (w9966_get_state(cam, W9966_STATE_PDEV, W9966_STATE_PDEV)) {
923 		parport_unregister_device(cam->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 */
w9966_attach(struct parport * port)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 */
w9966_detach(struct parport * port)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 */
w9966_mod_init(void)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 */
w9966_mod_term(void)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);
982