1/*
2	Winbond w9966cf Webcam parport driver.
3
4	Copyright (C) 2001 Jakob Kemi <jakob.kemi@telia.com>
5
6	This program is free software; you can redistribute it and/or modify
7	it under the terms of the GNU General Public License as published by
8	the Free Software Foundation; either version 2 of the License, or
9	(at your option) any later version.
10
11	This program is distributed in the hope that it will be useful,
12	but WITHOUT ANY WARRANTY; without even the implied warranty of
13	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14	GNU General Public License for more details.
15
16	You should have received a copy of the GNU General Public License
17	along with this program; if not, write to the Free Software
18	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20/*
21	Supported devices:
22	  * Lifeview Flycam Supra (Philips saa7111a chip)
23
24	  * Mikrotek Eyestar2 (Sanyo lc99053 chip)
25	    Very rudimentary support, total lack of ccd-control chip settings.
26	    Only green video data and no image properties (brightness, etc..)
27	    If anyone can parse the Japanese data-sheet for the Sanyo lc99053
28	    chip, feel free to help.
29	    <http://service.semic.sanyo.co.jp/semi/ds_pdf_j/LC99053.pdf>
30	    Thanks to Steven Griffiths <steve@sgriff.com> and
31	    James Murray <jsm@jsm-net.demon.co.uk> for testing.
32
33	Todo:
34	  * Add a working EPP mode (Is this a parport or a w9966 issue?)
35	  * Add proper probing. IEEE1284 probing of w9966 chips haven't
36	    worked since parport drivers changed in 2.4.x.
37	  * Probe for onboard SRAM, port directions etc. (possible?)
38
39	Changes:
40
41	Alan Cox:	Removed RGB mode for kernel merge, added THIS_MODULE
42			and owner support for newer module locks
43*/
44
45#include <linux/module.h>
46#include <linux/init.h>
47#include <linux/delay.h>
48#include <linux/videodev.h>
49#include <linux/parport.h>
50#include <linux/types.h>
51#include <linux/slab.h>
52
53//#define DEBUG				// Define for debug output.
54
55#ifdef DEBUG
56#   define DPRINTF(f, a...)						\
57        do {								\
58            printk ("%s%s, %d (DEBUG) %s(): ",				\
59                KERN_DEBUG, __FILE__, __LINE__, __func__);		\
60            printk (f, ##a);						\
61        } while (0)
62#   define DASSERT(x)							\
63        do {								\
64            if (!x)							\
65                DPRINTF("Assertion failed at line %d.\n", __LINE__);	\
66        } while (0)
67#else
68#   define DPRINTF(f, a...) do {} while(0)
69#   define DASSERT(f, a...) do {} while(0)
70#endif
71
72/*
73 *	Defines, simple typedefs etc.
74 */
75
76#define W9966_DRIVERNAME	"w9966cf"
77#define W9966_MAXCAMS		4	// Maximum number of cameras
78#define W9966_RBUFFER		8096	// Read buffer (must be an even number)
79
80#define W9966_WND_MIN_W		2
81#define W9966_WND_MIN_H		1
82
83// Keep track of our current state
84#define W9966_STATE_PDEV	0x01	// pdev registered
85#define W9966_STATE_CLAIMED	0x02	// pdev claimed
86#define W9966_STATE_VDEV	0x04	// vdev registered
87#define W9966_STATE_BUFFER	0x08	// buffer allocated
88#define W9966_STATE_DETECTED	0x10	// model identified
89
90#define W9966_SAA7111_ID	0x24	// I2C device id
91
92#define W9966_I2C_UDELAY	5
93#define W9966_I2C_TIMEOUT	100
94#define W9966_I2C_R_DATA	0x08
95#define W9966_I2C_R_CLOCK	0x04
96#define W9966_I2C_W_DATA	0x02
97#define W9966_I2C_W_CLOCK	0x01
98
99#define MAX(a, b) ((a > b) ? a : b)
100#define MIN(a, b) ((a > b) ? b : a)
101
102struct w9966_dev {
103	struct video_device vdev;
104	struct parport*     pport;
105	struct pardevice*   pdev;
106	int ppmode;
107
108	u8* buffer;
109	u8  dev_state;
110	u8  i2c_state;
111	u16 width;
112	u16 height;
113
114	// Image properties
115	u8 brightness;
116	s8 contrast;
117	s8 color;
118	s8 hue;
119
120	// Model specific:
121	const char* name;
122	u32 sramsize;
123	u8  sramid;		// reg 0x0c, bank layout
124	u8  cmask;		// reg 0x01, for polarity
125	u16 min_x, max_x;	// Capture window limits
126	u16 min_y, max_y;
127	int (*image)(struct w9966_dev* cam);
128};
129
130/*
131 *	Module properties
132 */
133
134MODULE_AUTHOR("Jakob Kemi <jakob.kemi@telia.com>");
135MODULE_DESCRIPTION("Winbond w9966cf webcam driver (Flycam Supra and others)");
136MODULE_LICENSE("GPL");
137
138
139static const char* pardev[] = {[0 ... W9966_MAXCAMS-1] = "auto"};
140MODULE_PARM(pardev, "0-" __MODULE_STRING(W9966_MAXCAMS) "s");
141MODULE_PARM_DESC(pardev,"\n\
142<auto|name|none[,...]> Where to find cameras.\n\
143  auto = probe all parports for camera (default)\n\
144  name = name of parport (eg parport0)\n\
145  none = don't use this camera\n\
146You can specify all cameras this way, for example:\n\
147  pardev=parport2,auto,none,parport0 would search for cam1 on parport2, search\n\
148  for cam2 on all parports, skip cam3 and search for cam4 on parport0");
149
150static int parmode = 1;
151MODULE_PARM(parmode, "i");
152MODULE_PARM_DESC(parmode, "\n<0|1|2|3> transfer mode (0=auto, 1=ecp(default), 2=epp, 3=forced hw-ecp)");
153
154static int video_nr[] = {[0 ... W9966_MAXCAMS-1] = -1};
155MODULE_PARM(video_nr, "0-" __MODULE_STRING(W9966_MAXCAMS) "i");
156MODULE_PARM_DESC(video_nr,"\n\
157<-1|n[,...]> Specify V4L minor mode number.\n\
158  -1 = use next available (default)\n\
159   n = use minor number n (integer >= 0)\n\
160You can specify all cameras this way, for example:\n\
161  video_nr=-1,2,-1 would assign minor number 2 for cam2 and use auto for cam1,\n\
162  cam3 and cam4");
163
164/*
165 *	Private data
166 */
167
168static struct w9966_dev* w9966_cams;
169
170/*
171 *	Private function declarations
172 */
173
174static inline void w9966_flag_set(struct w9966_dev* cam, int flag) {
175	cam->dev_state |= flag;}
176
177static inline void w9966_flag_clear(struct w9966_dev* cam, int flag) {
178	cam->dev_state &= ~flag;}
179
180static inline int  w9966_flag_test(struct w9966_dev* cam, int flag) {
181	return (cam->dev_state & flag);}
182
183static inline int  w9966_pdev_claim(struct w9966_dev *vdev);
184static inline void w9966_pdev_release(struct w9966_dev *vdev);
185
186static int w9966_rreg(struct w9966_dev* cam, int reg);
187static int w9966_wreg(struct w9966_dev* cam, int reg, int data);
188
189static int  w9966_init(struct w9966_dev* cam, struct parport* port, int vidnr);
190static void w9966_term(struct w9966_dev* cam);
191static int  w9966_setup(struct w9966_dev* cam);
192static int  w9966_findlen(int near, int size, int maxlen);
193static int  w9966_calcscale(int size, int min, int max,
194			int* beg, int* end, u8* factor);
195static int  w9966_window(struct w9966_dev* cam, int x1, int y1,
196			int x2, int y2, int w, int h);
197
198static int w9966_saa7111_init(struct w9966_dev* cam);
199static int w9966_saa7111_image(struct w9966_dev* cam);
200static int w9966_lc99053_init(struct w9966_dev* cam);
201static int w9966_lc99053_image(struct w9966_dev* cam);
202
203static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state);
204static inline int  w9966_i2c_setscl(struct w9966_dev* cam, int state);
205static inline int  w9966_i2c_getsda(struct w9966_dev* cam);
206static inline int  w9966_i2c_getscl(struct w9966_dev* cam);
207static int w9966_i2c_wbyte(struct w9966_dev* cam, int data);
208static int w9966_i2c_rbyte(struct w9966_dev* cam);
209static int w9966_i2c_rreg(struct w9966_dev* cam, int device, int reg);
210static int w9966_i2c_wreg(struct w9966_dev* cam, int device, int reg, int data);
211
212static int  w9966_v4l_open(struct video_device *vdev, int mode);
213static void w9966_v4l_close(struct video_device *vdev);
214static int  w9966_v4l_ioctl(struct video_device *vdev,
215			unsigned int cmd, void *arg);
216static long w9966_v4l_read(struct video_device *vdev,
217			char *buf, unsigned long count, int noblock);
218
219/*
220 *	Private function definitions
221 */
222
223// Claim parport for ourself
224// 1 on success, else 0
225static inline int w9966_pdev_claim(struct w9966_dev* cam)
226{
227	if (w9966_flag_test(cam, W9966_STATE_CLAIMED))
228		return 1;
229	if (parport_claim_or_block(cam->pdev) < 0)
230		return 0;
231	w9966_flag_set(cam, W9966_STATE_CLAIMED);
232	return 1;
233}
234
235// Release parport for others to use
236static inline void w9966_pdev_release(struct w9966_dev* cam)
237{
238	if (!w9966_flag_test(cam, W9966_STATE_CLAIMED))
239		return;
240	parport_release(cam->pdev);
241	w9966_flag_clear(cam, W9966_STATE_CLAIMED);
242}
243
244// Read register from w9966 interface-chip
245// Expects a claimed pdev
246// -1 on error, else register data (byte)
247static int w9966_rreg(struct w9966_dev* cam, int reg)
248{
249	// ECP, read, regtransfer, REG, REG, REG, REG, REG
250	const u8 addr = 0x80 | (reg & 0x1f);
251	u8 val;
252
253	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0 ||
254	    parport_write(cam->pport, &addr, 1) != 1 ||
255	    parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0 ||
256	    parport_read(cam->pport, &val, 1) != 1)
257		return -1;
258
259	return val;
260}
261
262// Write register to w9966 interface-chip
263// Expects a claimed pdev
264// 1 on success, else 0
265static int w9966_wreg(struct w9966_dev* cam, int reg, int data)
266{
267	// ECP, write, regtransfer, REG, REG, REG, REG, REG
268	const u8 addr = 0xc0 | (reg & 0x1f);
269	const u8 val = data;
270
271	if (parport_negotiate(cam->pport, cam->ppmode | IEEE1284_ADDR) != 0 ||
272	    parport_write(cam->pport, &addr, 1) != 1 ||
273	    parport_negotiate(cam->pport, cam->ppmode | IEEE1284_DATA) != 0 ||
274	    parport_write(cam->pport, &val, 1) != 1)
275		return 0;
276
277	return 1;
278}
279
280// Initialize camera device. Setup all internal flags, set a
281// default video mode, setup ccd-chip, register v4l device etc..
282// Also used for 'probing' of hardware.
283// 1 on success, else 0
284static int w9966_init(struct w9966_dev* cam, struct parport* port, int vidnr)
285{
286	if (cam->dev_state != 0)
287		return 0;
288
289	cam->pport = port;
290	cam->brightness = 128;
291	cam->contrast = 64;
292	cam->color = 64;
293	cam->hue = 0;
294
295	// Select requested transfer mode
296	switch(parmode)
297	{
298	default:	// Auto-detect (priority: hw-ecp, hw-epp, sw-ecp)
299	case 0:
300		if (port->modes & PARPORT_MODE_ECP)
301			cam->ppmode = IEEE1284_MODE_ECP;
302		else if (port->modes & PARPORT_MODE_EPP)
303			cam->ppmode = IEEE1284_MODE_EPP;
304		else
305			cam->ppmode = IEEE1284_MODE_ECPSWE;
306		break;
307	case 1:		// hw- or sw-ecp
308		if (port->modes & PARPORT_MODE_ECP)
309			cam->ppmode = IEEE1284_MODE_ECP;
310		else
311			cam->ppmode = IEEE1284_MODE_ECPSWE;
312		break;
313	case 2:		// hw- or sw-epp
314		if (port->modes & PARPORT_MODE_EPP)
315			cam->ppmode = IEEE1284_MODE_EPP;
316		else
317			cam->ppmode = IEEE1284_MODE_EPPSWE;
318		break;
319	case 3:		// hw-ecp
320		cam->ppmode = IEEE1284_MODE_ECP;
321		break;
322	}
323
324	// Tell the parport driver that we exists
325	cam->pdev = parport_register_device(
326	    port, W9966_DRIVERNAME, NULL, NULL, NULL, 0, NULL);
327
328	if (cam->pdev == NULL) {
329		DPRINTF("parport_register_device() failed.\n");
330		return 0;
331	}
332	w9966_flag_set(cam, W9966_STATE_PDEV);
333
334	// Claim parport
335	if (!w9966_pdev_claim(cam)) {
336		DPRINTF("w9966_pdev_claim() failed.\n");
337		return 0;
338	}
339
340	// Perform initial w9966 setup
341	if (!w9966_setup(cam)) {
342		DPRINTF("w9966_setup() failed.\n");
343		return 0;
344	}
345
346	// Detect model
347	if (!w9966_saa7111_init(cam)) {
348		DPRINTF("w9966_saa7111_init() failed.\n");
349		return 0;
350	}
351	if (!w9966_lc99053_init(cam)) {
352		DPRINTF("w9966_lc99053_init() failed.\n");
353		return 0;
354	}
355	if (!w9966_flag_test(cam, W9966_STATE_DETECTED)) {
356		DPRINTF("Camera model not identified.\n");
357		return 0;
358	}
359
360	// Setup w9966 with a default capture mode (QCIF res.)
361	if (!w9966_window(cam, 0, 0, 1023, 1023, 176, 144)) {
362		DPRINTF("w9966_window() failed.\n");
363		return 0;
364	}
365	w9966_pdev_release(cam);
366
367	// Fill in the video_device struct and register us to v4l
368	memset(&cam->vdev, 0, sizeof(struct video_device));
369	strcpy(cam->vdev.name, W9966_DRIVERNAME);
370	cam->vdev.type = VID_TYPE_CAPTURE | VID_TYPE_SCALES;
371	cam->vdev.hardware = VID_HARDWARE_W9966;
372	cam->vdev.open = &w9966_v4l_open;
373	cam->vdev.close = &w9966_v4l_close;
374	cam->vdev.read = &w9966_v4l_read;
375	cam->vdev.ioctl = &w9966_v4l_ioctl;
376	cam->vdev.priv = (void*)cam;
377	cam->vdev.owner = THIS_MODULE;
378
379	if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, vidnr) == -1) {
380		DPRINTF("video_register_device() failed (minor: %d).\n", vidnr);
381		return 0;
382	}
383	w9966_flag_set(cam, W9966_STATE_VDEV);
384
385	// All ok
386	printk("w9966: Found and initialized %s on %s.\n",
387		cam->name, cam->pport->name);
388	return 1;
389}
390
391// Terminate everything gracefully
392static void w9966_term(struct w9966_dev* cam)
393{
394	// Delete allocated buffer
395	if (w9966_flag_test(cam, W9966_STATE_BUFFER))
396		kfree(cam->buffer);
397
398	// Unregister from v4l
399	if (w9966_flag_test(cam, W9966_STATE_VDEV))
400		video_unregister_device(&cam->vdev);
401
402	// Terminate from IEEE1284 mode and unregister from parport
403	if (w9966_flag_test(cam, W9966_STATE_PDEV)) {
404		if (w9966_pdev_claim(cam))
405			parport_negotiate(cam->pport, IEEE1284_MODE_COMPAT);
406
407		w9966_pdev_release(cam);
408		parport_unregister_device(cam->pdev);
409	}
410
411	cam->dev_state = 0x00;
412}
413
414// Do initial setup for the w9966 chip, init i2c bus, etc.
415// this is generic for all models
416// expects a claimed pdev
417// 1 on success, else 0
418static int w9966_setup(struct w9966_dev* cam)
419{
420	const u8 i2c = cam->i2c_state = W9966_I2C_W_DATA | W9966_I2C_W_CLOCK;
421	const u8 regs[] = {
422		0x40,			// 0x13 - VEE control (raw 4:2:2)
423		0x00, 0x00, 0x00,	// 0x14 - 0x16
424		0x00,			// 0x17 - ???
425		i2c,			// 0x18 - Serial bus
426		0xff,			// 0x19 - I/O port direction control
427		0xff,			// 0x1a - I/O port data register
428		0x10			// 0x1b - ???
429	};
430	int i;
431
432	DASSERT(w9966_flag_test(cam, W9966_STATE_CLAIMED));
433
434	// Reset (ECP-fifo & serial-bus)
435	if (!w9966_wreg(cam, 0x00, 0x03) ||
436	    !w9966_wreg(cam, 0x00, 0x00))
437		return 0;
438
439	// Write regs to w9966cf chip
440	for (i = 0x13; i < 0x1c; i++)
441		if (!w9966_wreg(cam, i, regs[i-0x13]))
442			return 0;
443
444	return 1;
445}
446
447// Find a good length for capture window (used both for W and H)
448// A bit ugly but pretty functional. The capture length
449// have to match the downscale
450static int w9966_findlen(int near, int size, int maxlen)
451{
452	int bestlen = size;
453	int besterr = abs(near - bestlen);
454	int len;
455
456	for(len = size+1; len < maxlen; len++)
457	{
458		int err;
459		if ( ((64*size) %len) != 0)
460			continue;
461
462		err = abs(near - len);
463
464		// Only continue as long as we keep getting better values
465		if (err > besterr)
466			break;
467
468		besterr = err;
469		bestlen = len;
470	}
471
472	return bestlen;
473}
474
475// Modify capture window (if necessary)
476// and calculate downscaling
477// 1 on success, else 0
478static int w9966_calcscale(int size, int min, int max, int* beg, int* end, u8* factor)
479{
480	const int maxlen = max - min;
481	const int len = *end - *beg + 1;
482	const int newlen = w9966_findlen(len, size, maxlen);
483	const int err = newlen - len;
484
485	// Check for bad format
486	if (newlen > maxlen || newlen < size)
487		return 0;
488
489	// Set factor (6 bit fixed)
490	*factor = (64*size) / newlen;
491	if (*factor == 64)
492		*factor = 0x00;	// downscale is disabled
493	else
494		*factor |= 0x80; // set downscale-enable bit
495
496	// Modify old beginning and end
497	*beg -= err / 2;
498	*end += err - (err / 2);
499
500	// Move window if outside borders
501	if (*beg < min) {
502		*end += min - *beg;
503		*beg += min - *beg;
504	}
505	if (*end > max) {
506		*beg -= *end - max;
507		*end -= *end - max;
508	}
509
510	return 1;
511}
512
513// Setup the w9966 capture window and also set SRAM settings
514// expects a claimed pdev and detected camera model
515// 1 on success, else 0
516static int w9966_window(struct w9966_dev* cam, int x1, int y1, int x2, int y2, int w, int h)
517{
518	unsigned int enh_s, enh_e;
519	u8 scale_x, scale_y;
520	u8 regs[0x13];
521	int i;
522
523	// Modify width and height to match capture window and SRAM
524	w = MAX(W9966_WND_MIN_W, w);
525	h = MAX(W9966_WND_MIN_H, h);
526	w = MIN(cam->max_x - cam->min_x, w);
527	h = MIN(cam->max_y - cam->min_y, h);
528	w &= ~0x1;
529	if (w*h*2 > cam->sramsize)
530		h = cam->sramsize / (w*2);
531
532	cam->width = w;
533	cam->height = h;
534
535	enh_s = 0;
536	enh_e = w*h*2;
537
538	// Calculate downscaling
539	if (!w9966_calcscale(w, cam->min_x, cam->max_x, &x1, &x2, &scale_x) ||
540	    !w9966_calcscale(h, cam->min_y, cam->max_y, &y1, &y2, &scale_y))
541		return 0;
542
543	DPRINTF("%dx%d, x: %d<->%d, y: %d<->%d, sx: %d/64, sy: %d/64.\n",
544		w, h, x1, x2, y1, y2, scale_x&~0x80, scale_y&~0x80);
545
546	// Setup registers
547	regs[0x00] = 0x00;			// Set normal operation
548	regs[0x01] = cam->cmask;		// Capture mode
549	regs[0x02] = scale_y;			// V-scaling
550	regs[0x03] = scale_x;			// H-scaling
551
552	// Capture window
553	regs[0x04] = (x1 & 0x0ff);		// X-start (8 low bits)
554	regs[0x05] = (x1 & 0x300)>>8;		// X-start (2 high bits)
555	regs[0x06] = (y1 & 0x0ff);		// Y-start (8 low bits)
556	regs[0x07] = (y1 & 0x300)>>8;		// Y-start (2 high bits)
557	regs[0x08] = (x2 & 0x0ff);		// X-end (8 low bits)
558	regs[0x09] = (x2 & 0x300)>>8;		// X-end (2 high bits)
559	regs[0x0a] = (y2 & 0x0ff);		// Y-end (8 low bits)
560
561	regs[0x0c] = cam->sramid;		// SRAM layout
562
563	// Enhancement layer
564	regs[0x0d] = (enh_s& 0x000ff);		// Enh. start (0-7)
565	regs[0x0e] = (enh_s& 0x0ff00)>>8;	// Enh. start (8-15)
566	regs[0x0f] = (enh_s& 0x70000)>>16;	// Enh. start (16-17/18??)
567	regs[0x10] = (enh_e& 0x000ff);		// Enh. end (0-7)
568	regs[0x11] = (enh_e& 0x0ff00)>>8;	// Enh. end (8-15)
569	regs[0x12] = (enh_e& 0x70000)>>16;	// Enh. end (16-17/18??)
570
571	// Write regs to w9966cf chip
572	for (i = 0x01; i < 0x13; i++)
573		if (!w9966_wreg(cam, i, regs[i]))
574			return 0;
575
576	return 1;
577}
578
579// Detect and initialize saa7111 ccd-controller chip.
580// expects a claimed parport
581// expected to always return 1 unless error is _fatal_
582// 1 on success, else 0
583static int w9966_saa7111_init(struct w9966_dev* cam)
584{
585	// saa7111 regs 0x00 trough 0x12
586	const u8 regs[] = {
587		0x00, // not written
588		0x00, 0xd8, 0x23, 0x00, 0x80, 0x80, 0x00, 0x88, 0x10,
589		cam->brightness,	// 0x0a
590		cam->contrast,		// 0x0b
591		cam->color,		// 0x0c
592		cam->hue,		// 0x0d
593		0x01, 0x00, 0x48, 0x0c, 0x00,
594	};
595	int i;
596
597	if (w9966_flag_test(cam, W9966_STATE_DETECTED))
598		return 1;
599
600	// Write regs to saa7111 chip
601	for (i = 1; i < 0x13; i++)
602		if (!w9966_i2c_wreg(cam, W9966_SAA7111_ID, i, regs[i]))
603			return 1;
604
605	// Read back regs
606	for (i = 1; i < 0x13; i++)
607		if (w9966_i2c_rreg(cam, W9966_SAA7111_ID, i) != regs[i])
608			return 1;
609
610	// Fill in model specific data
611	cam->name = "Lifeview Flycam Supra";
612	cam->sramsize = 128 << 10;	// 128 kib
613	cam->sramid = 0x02;		// see w9966.pdf
614
615	cam->cmask = 0x18;		// normal polarity
616	cam->min_x = 16;		// empirically determined
617	cam->max_x = 705;
618	cam->min_y = 14;
619	cam->max_y = 253;
620	cam->image = &w9966_saa7111_image;
621
622	DPRINTF("Found and initialized a saa7111 chip.\n");
623	w9966_flag_set(cam, W9966_STATE_DETECTED);
624
625	return 1;
626}
627
628// Setup image properties (brightness, hue, etc.) for the saa7111 chip
629// expects a claimed parport
630// 1 on success, else 0
631static int w9966_saa7111_image(struct w9966_dev* cam)
632{
633	if (!w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0a, cam->brightness) ||
634	    !w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0b, cam->contrast) ||
635	    !w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0c, cam->color) ||
636	    !w9966_i2c_wreg(cam, W9966_SAA7111_ID, 0x0d, cam->hue))
637		return 0;
638
639	return 1;
640}
641
642// Detect and initialize lc99053 ccd-controller chip.
643// expects a claimed parport
644// this is currently a hack, no detection is done, we just assume an Eyestar2
645// 1 on success, else 0
646static int w9966_lc99053_init(struct w9966_dev* cam)
647{
648	if (w9966_flag_test(cam, W9966_STATE_DETECTED))
649		return 1;
650
651	// Fill in model specific data
652	cam->name = "Microtek Eyestar2";
653	cam->sramsize = 128 << 10;	// 128 kib
654	cam->sramid = 0x02;		// w9966cf.pdf
655
656	cam->cmask = 0x10;		// reverse polarity
657	cam->min_x = 16;		// empirically determined
658	cam->max_x = 705;
659	cam->min_y = 14;
660	cam->max_y = 253;
661	cam->image = &w9966_lc99053_image;
662
663	DPRINTF("Found and initialized a lc99053 chip.\n");
664	w9966_flag_set(cam, W9966_STATE_DETECTED);
665
666	return 1;
667}
668
669// Setup image properties (brightness, hue, etc.) for the lc99053 chip
670// expects a claimed parport
671// 1 on success, else 0
672static int w9966_lc99053_image(struct w9966_dev* cam)
673{
674	return 1;
675}
676
677/*
678 *	Ugly and primitive i2c protocol functions
679 */
680
681// Sets the data line on the i2c bus.
682// Expects a claimed pdev.
683static inline void w9966_i2c_setsda(struct w9966_dev* cam, int state)
684{
685	if (state)
686		cam->i2c_state |= W9966_I2C_W_DATA;
687	else
688		cam->i2c_state &= ~W9966_I2C_W_DATA;
689
690	w9966_wreg(cam, 0x18, cam->i2c_state);
691	udelay(W9966_I2C_UDELAY);
692}
693
694// Sets the clock line on the i2c bus.
695// Expects a claimed pdev.
696// 1 on success, else 0
697static inline int w9966_i2c_setscl(struct w9966_dev* cam, int state)
698{
699	if (state)
700		cam->i2c_state |= W9966_I2C_W_CLOCK;
701	else
702		cam->i2c_state &= ~W9966_I2C_W_CLOCK;
703
704	w9966_wreg(cam, 0x18, cam->i2c_state);
705	udelay(W9966_I2C_UDELAY);
706
707	// when we go to high, we also expect the peripheral to ack.
708	if (state) {
709		const int timeout = jiffies + W9966_I2C_TIMEOUT;
710		while (!w9966_i2c_getscl(cam)) {
711			if (time_after(jiffies, timeout))
712				return 0;
713		}
714	}
715	return 1;
716}
717
718// Get peripheral data line
719// Expects a claimed pdev.
720static inline int w9966_i2c_getsda(struct w9966_dev* cam)
721{
722	const u8 pins = w9966_rreg(cam, 0x18);
723	return ((pins & W9966_I2C_R_DATA) > 0);
724}
725
726// Get peripheral clock line
727// Expects a claimed pdev.
728static inline int w9966_i2c_getscl(struct w9966_dev* cam)
729{
730	const u8 pins = w9966_rreg(cam, 0x18);
731	return ((pins & W9966_I2C_R_CLOCK) > 0);
732}
733
734// Write a byte with ack to the i2c bus.
735// Expects a claimed pdev.
736// 1 on success, else 0
737static int w9966_i2c_wbyte(struct w9966_dev* cam, int data)
738{
739	int i;
740	for (i = 7; i >= 0; i--) {
741		w9966_i2c_setsda(cam, (data >> i) & 0x01);
742
743		if (!w9966_i2c_setscl(cam, 1) ||
744		    !w9966_i2c_setscl(cam, 0))
745			return 0;
746	}
747	w9966_i2c_setsda(cam, 1);
748
749	if (!w9966_i2c_setscl(cam, 1) ||
750	    !w9966_i2c_setscl(cam, 0))
751		return 0;
752
753	return 1;
754}
755
756// Read a data byte with ack from the i2c-bus
757// Expects a claimed pdev. -1 on error
758static int w9966_i2c_rbyte(struct w9966_dev* cam)
759{
760	u8 data = 0x00;
761	int i;
762
763	w9966_i2c_setsda(cam, 1);
764
765	for (i = 0; i < 8; i++)
766	{
767		if (!w9966_i2c_setscl(cam, 1))
768			return -1;
769		data = data << 1;
770		if (w9966_i2c_getsda(cam))
771			data |= 0x01;
772
773		w9966_i2c_setscl(cam, 0);
774	}
775	return data;
776}
777
778// Read a register from the i2c device.
779// Expects claimed pdev. -1 on error
780static int w9966_i2c_rreg(struct w9966_dev* cam, int device, int reg)
781{
782	int data;
783
784	w9966_i2c_setsda(cam, 0);
785	w9966_i2c_setscl(cam, 0);
786
787	if (!w9966_i2c_wbyte(cam, device << 1) ||
788	    !w9966_i2c_wbyte(cam, reg))
789		return -1;
790
791	w9966_i2c_setsda(cam, 1);
792	if (!w9966_i2c_setscl(cam, 1))
793		return -1;
794
795	w9966_i2c_setsda(cam, 0);
796	w9966_i2c_setscl(cam, 0);
797
798	if (!w9966_i2c_wbyte(cam, (device << 1) | 1) ||
799	    (data = w9966_i2c_rbyte(cam)) == -1)
800		return -1;
801
802	w9966_i2c_setsda(cam, 0);
803
804	if (!w9966_i2c_setscl(cam, 1))
805		return -1;
806
807	w9966_i2c_setsda(cam, 1);
808
809	return data;
810}
811
812// Write a register to the i2c device.
813// Expects claimed pdev.
814// 1 on success, else 0
815static int w9966_i2c_wreg(struct w9966_dev* cam, int device, int reg, int data)
816{
817	w9966_i2c_setsda(cam, 0);
818	w9966_i2c_setscl(cam, 0);
819
820	if (!w9966_i2c_wbyte(cam, device << 1) ||
821	    !w9966_i2c_wbyte(cam, reg) ||
822	    !w9966_i2c_wbyte(cam, data))
823		return 0;
824
825	w9966_i2c_setsda(cam, 0);
826	if (!w9966_i2c_setscl(cam, 1))
827		return 0;
828
829	w9966_i2c_setsda(cam, 1);
830
831	return 1;
832}
833
834/*
835 *	Video4linux interface
836 */
837
838static int w9966_v4l_open(struct video_device *vdev, int flags)
839{
840	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
841
842	// Claim parport
843	if (!w9966_pdev_claim(cam)) {
844		DPRINTF("Unable to claim parport");
845		return -EFAULT;
846	}
847
848	// Allocate read buffer
849	cam->buffer = (u8*)kmalloc(W9966_RBUFFER, GFP_KERNEL);
850	if (cam->buffer == NULL) {
851		w9966_pdev_release(cam);
852		return -ENOMEM;
853	}
854	w9966_flag_set(cam, W9966_STATE_BUFFER);
855
856	return 0;
857}
858
859static void w9966_v4l_close(struct video_device *vdev)
860{
861	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
862
863	// Free read buffer
864	if (w9966_flag_test(cam, W9966_STATE_BUFFER)) {
865		kfree(cam->buffer);
866		w9966_flag_clear(cam, W9966_STATE_BUFFER);
867	}
868
869	// release parport
870	w9966_pdev_release(cam);
871}
872
873// expects a claimed parport
874static int w9966_v4l_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
875{
876	struct w9966_dev *cam = (struct w9966_dev*)vdev->priv;
877
878	switch(cmd)
879	{
880	case VIDIOCGCAP:
881	{
882		struct video_capability vcap = {
883			W9966_DRIVERNAME,	// name
884			VID_TYPE_CAPTURE | VID_TYPE_SCALES,	// type
885			1, 0,			// vid, aud channels
886			cam->max_x - cam->min_x,
887			cam->max_y - cam->min_y,
888			W9966_WND_MIN_W,
889			W9966_WND_MIN_H
890		};
891
892		if(copy_to_user(arg, &vcap, sizeof(vcap)) != 0)
893			return -EFAULT;
894
895		return 0;
896	}
897	case VIDIOCGCHAN:
898	{
899		struct video_channel vch;
900		if(copy_from_user(&vch, arg, sizeof(vch)) != 0)
901			return -EFAULT;
902
903		if(vch.channel != 0)	// We only support one channel (#0)
904			return -EINVAL;
905
906		strcpy(vch.name, "CCD-input");
907		vch.flags = 0;		// We have no tuner or audio
908		vch.tuners = 0;
909		vch.type = VIDEO_TYPE_CAMERA;
910		vch.norm = 0;		// ???
911
912		if(copy_to_user(arg, &vch, sizeof(vch)) != 0)
913			return -EFAULT;
914
915		return 0;
916	}
917	case VIDIOCSCHAN:
918	{
919		struct video_channel vch;
920		if(copy_from_user(&vch, arg, sizeof(vch) ) != 0)
921			return -EFAULT;
922
923		if(vch.channel != 0)
924			return -EINVAL;
925
926		return 0;
927	}
928	case VIDIOCGTUNER:
929	{
930		struct video_tuner vtune;
931		if(copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
932			return -EFAULT;
933
934		if(vtune.tuner != 0);
935			return -EINVAL;
936
937		strcpy(vtune.name, "no tuner");
938		vtune.rangelow = 0;
939		vtune.rangehigh = 0;
940		vtune.flags = VIDEO_TUNER_NORM;
941		vtune.mode = VIDEO_MODE_AUTO;
942		vtune.signal = 0xffff;
943
944		if(copy_to_user(arg, &vtune, sizeof(vtune)) != 0)
945			return -EFAULT;
946
947		return 0;
948	}
949	case VIDIOCSTUNER:
950	{
951		struct video_tuner vtune;
952		if (copy_from_user(&vtune, arg, sizeof(vtune)) != 0)
953			return -EFAULT;
954
955		if (vtune.tuner != 0)
956			return -EINVAL;
957
958		if (vtune.mode != VIDEO_MODE_AUTO)
959			return -EINVAL;
960
961		return 0;
962	}
963	case VIDIOCGPICT:
964	{
965		struct video_picture vpic = {
966			cam->brightness << 8,	// brightness
967			(cam->hue + 128) << 8,	// hue
968			cam->color << 9,	// color
969			cam->contrast << 9,	// contrast
970			0x8000,			// whiteness
971			16, VIDEO_PALETTE_YUV422// bpp, palette format
972		};
973
974		if(copy_to_user(arg, &vpic, sizeof(vpic)) != 0)
975			return -EFAULT;
976
977		return 0;
978	}
979	case VIDIOCSPICT:
980	{
981		struct video_picture vpic;
982		if(copy_from_user(&vpic, arg, sizeof(vpic)) != 0)
983			return -EFAULT;
984
985		if (vpic.depth != 16 || vpic.palette != VIDEO_PALETTE_YUV422)
986			return -EINVAL;
987
988		cam->brightness = vpic.brightness >> 8;
989		cam->hue = (vpic.hue >> 8) - 128;
990		cam->color = vpic.colour >> 9;
991		cam->contrast = vpic.contrast >> 9;
992
993		if (!cam->image(cam))
994			return -EFAULT;
995
996		return 0;
997	}
998	case VIDIOCSWIN:
999	{
1000		struct video_window vwin;
1001
1002		if (copy_from_user(&vwin, arg, sizeof(vwin)) != 0)
1003			return -EFAULT;
1004		if (
1005		  vwin.flags != 0 ||
1006		  vwin.clipcount != 0)
1007			return -EINVAL;
1008
1009		if (vwin.width  > cam->max_x - cam->min_x ||
1010		    vwin.height > cam->max_y - cam->min_y ||
1011		    vwin.width  < W9966_WND_MIN_W ||
1012		    vwin.height < W9966_WND_MIN_H)
1013			return -EINVAL;
1014
1015		// Update camera regs
1016		if (!w9966_window(cam, 0, 0, 1023, 1023, vwin.width, vwin.height))
1017			return -EFAULT;
1018
1019		return 0;
1020	}
1021	case VIDIOCGWIN:
1022	{
1023		struct video_window vwin;
1024		memset(&vwin, 0, sizeof(vwin));
1025
1026		vwin.width = cam->width;
1027		vwin.height = cam->height;
1028
1029		if(copy_to_user(arg, &vwin, sizeof(vwin)) != 0)
1030			return -EFAULT;
1031
1032		return 0;
1033	}
1034	// Unimplemented
1035	case VIDIOCCAPTURE:
1036	case VIDIOCGFBUF:
1037	case VIDIOCSFBUF:
1038	case VIDIOCKEY:
1039	case VIDIOCGFREQ:
1040	case VIDIOCSFREQ:
1041	case VIDIOCGAUDIO:
1042	case VIDIOCSAUDIO:
1043		return -EINVAL;
1044	default:
1045		return -ENOIOCTLCMD;
1046	}
1047	return 0;
1048}
1049
1050// Capture data
1051// expects a claimed parport and allocated read buffer
1052static long w9966_v4l_read(struct video_device *vdev, char *buf, unsigned long count,  int noblock)
1053{
1054	struct w9966_dev *cam = (struct w9966_dev *)vdev->priv;
1055	const u8 addr = 0xa0;	// ECP, read, CCD-transfer, 00000
1056	u8* dest = (u8*)buf;
1057	unsigned long dleft = count;
1058
1059	// Why would anyone want more than this??
1060	if (count > cam->width * cam->height * 2)
1061		count = cam->width * cam->height * 2;
1062
1063	w9966_wreg(cam, 0x00, 0x02);	// Reset ECP-FIFO buffer
1064	w9966_wreg(cam, 0x00, 0x00);	// Return to normal operation
1065	w9966_wreg(cam, 0x01, cam->cmask | 0x80);	// Enable capture
1066
1067	// write special capture-addr and negotiate into data transfer
1068	if (parport_negotiate(cam->pport, cam->ppmode|IEEE1284_ADDR) != 0 ||
1069	    parport_write(cam->pport, &addr, 1) != 1 ||
1070	    parport_negotiate(cam->pport, cam->ppmode|IEEE1284_DATA) != 0) {
1071		DPRINTF("Unable to write capture-addr.\n");
1072		return -EFAULT;
1073	}
1074
1075	while(dleft > 0)
1076	{
1077		const size_t tsize = (dleft > W9966_RBUFFER) ? W9966_RBUFFER : dleft;
1078
1079		if (parport_read(cam->pport, cam->buffer, tsize) < tsize)
1080			return -EFAULT;
1081
1082		if (copy_to_user(dest, cam->buffer, tsize) != 0)
1083			return -EFAULT;
1084
1085		dest += tsize;
1086		dleft -= tsize;
1087	}
1088
1089	w9966_wreg(cam, 0x01, cam->cmask);	// Disable capture
1090
1091	return count;
1092}
1093
1094// Called once for every parport on init
1095static void w9966_attach(struct parport *port)
1096{
1097	int i;
1098
1099	for (i = 0; i < W9966_MAXCAMS; i++) {
1100		if (strcmp(pardev[i], "none") == 0 ||	// Skip if 'none' or if
1101		    w9966_cams[i].dev_state != 0)	// cam already assigned
1102			continue;
1103
1104		if (strcmp(pardev[i], "auto") == 0 ||
1105		    strcmp(pardev[i], port->name) == 0) {
1106			if (!w9966_init(&w9966_cams[i], port, video_nr[i]))
1107				w9966_term(&w9966_cams[i]);
1108			break;	// return
1109		}
1110	}
1111}
1112
1113// Called once for every parport on termination
1114static void w9966_detach(struct parport *port)
1115{
1116	int i;
1117	for (i = 0; i < W9966_MAXCAMS; i++)
1118	if (w9966_cams[i].dev_state != 0 && w9966_cams[i].pport == port)
1119		w9966_term(&w9966_cams[i]);
1120}
1121
1122
1123static struct parport_driver w9966_ppd = {
1124	W9966_DRIVERNAME,
1125	w9966_attach,
1126	w9966_detach,
1127	NULL
1128};
1129
1130// Module entry point
1131static int __init w9966_mod_init(void)
1132{
1133	int i, err;
1134
1135	w9966_cams = kmalloc(
1136		sizeof(struct w9966_dev) * W9966_MAXCAMS, GFP_KERNEL);
1137
1138	if (!w9966_cams)
1139		return -ENOMEM;
1140
1141	for (i = 0; i < W9966_MAXCAMS; i++)
1142		w9966_cams[i].dev_state = 0;
1143
1144	// Register parport driver
1145	if ((err = parport_register_driver(&w9966_ppd)) != 0) {
1146		kfree(w9966_cams);
1147		w9966_cams = 0;
1148		return err;
1149	}
1150
1151	return 0;
1152}
1153
1154// Module cleanup
1155static void __exit w9966_mod_term(void)
1156{
1157	if (w9966_cams)
1158		kfree(w9966_cams);
1159
1160	parport_unregister_driver(&w9966_ppd);
1161}
1162
1163module_init(w9966_mod_init);
1164module_exit(w9966_mod_term);
1165