1#ifndef cpia_h
2#define cpia_h
3
4/*
5 * CPiA Parallel Port Video4Linux driver
6 *
7 * Supports CPiA based parallel port Video Camera's.
8 *
9 * (C) Copyright 1999 Bas Huisman,
10 *                    Peter Pregler,
11 *                    Scott J. Bertin,
12 *                    VLSI Vision Ltd.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */
28
29#define CPIA_MAJ_VER	0
30#define CPIA_MIN_VER    8
31#define CPIA_PATCH_VER	1
32
33#define CPIA_PP_MAJ_VER       0
34#define CPIA_PP_MIN_VER       8
35#define CPIA_PP_PATCH_VER     1
36
37#define CPIA_MAX_FRAME_SIZE_UNALIGNED	(352 * 288 * 4)   /* CIF at RGB32 */
38#define CPIA_MAX_FRAME_SIZE	((CPIA_MAX_FRAME_SIZE_UNALIGNED + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)) /* align above to PAGE_SIZE */
39
40#ifdef __KERNEL__
41
42#include <asm/uaccess.h>
43#include <linux/videodev.h>
44#include <linux/smp_lock.h>
45
46struct cpia_camera_ops
47{
48	/* open sets privdata to point to structure for this camera.
49         * Returns negative value on error, otherwise 0.
50	 */
51	int (*open)(void *privdata);
52
53	/* Registers callback function cb to be called with cbdata
54	 * when an image is ready.  If cb is NULL, only single image grabs
55	 * should be used.  cb should immediately call streamRead to read
56	 * the data or data may be lost. Returns negative value on error,
57	 * otherwise 0.
58	 */
59	int (*registerCallback)(void *privdata, void (*cb)(void *cbdata),
60	                        void *cbdata);
61
62	/* transferCmd sends commands to the camera.  command MUST point to
63	 * an  8 byte buffer in kernel space. data can be NULL if no extra
64	 * data is needed.  The size of the data is given by the last 2
65	 * bytes of command.  data must also point to memory in kernel space.
66	 * Returns negative value on error, otherwise 0.
67	 */
68	int (*transferCmd)(void *privdata, u8 *command, u8 *data);
69
70	/* streamStart initiates stream capture mode.
71	 * Returns negative value on error, otherwise 0.
72	 */
73	int (*streamStart)(void *privdata);
74
75	/* streamStop terminates stream capture mode.
76	 * Returns negative value on error, otherwise 0.
77	 */
78	int (*streamStop)(void *privdata);
79
80	/* streamRead reads a frame from the camera.  buffer points to a
81         * buffer large enough to hold a complete frame in kernel space.
82         * noblock indicates if this should be a non blocking read.
83	 * Returns the number of bytes read, or negative value on error.
84         */
85	int (*streamRead)(void *privdata, u8 *buffer, int noblock);
86
87	/* close disables the device until open() is called again.
88	 * Returns negative value on error, otherwise 0.
89	 */
90	int (*close)(void *privdata);
91
92	/* If wait_for_stream_ready is non-zero, wait until the streamState
93	 * is STREAM_READY before calling streamRead.
94	 */
95	int wait_for_stream_ready;
96};
97
98struct cpia_frame {
99	u8 *data;
100	int count;
101	int width;
102	int height;
103	volatile int state;
104};
105
106struct cam_params {
107	struct {
108		u8 firmwareVersion;
109		u8 firmwareRevision;
110		u8 vcVersion;
111		u8 vcRevision;
112	} version;
113	struct {
114		u16 vendor;
115		u16 product;
116		u16 deviceRevision;
117	} pnpID;
118	struct {
119		u8 vpVersion;
120		u8 vpRevision;
121		u16 cameraHeadID;
122	} vpVersion;
123	struct {
124		u8 systemState;
125		u8 grabState;
126		u8 streamState;
127		u8 fatalError;
128		u8 cmdError;
129		u8 debugFlags;
130		u8 vpStatus;
131		u8 errorCode;
132	} status;
133	struct {
134		u8 brightness;
135		u8 contrast;
136		u8 saturation;
137	} colourParams;
138	struct {
139		u8 gainMode;
140		u8 expMode;
141		u8 compMode;
142		u8 centreWeight;
143		u8 gain;
144		u8 fineExp;
145		u8 coarseExpLo;
146		u8 coarseExpHi;
147		u8 redComp;
148		u8 green1Comp;
149		u8 green2Comp;
150		u8 blueComp;
151	} exposure;
152	struct {
153		u8 balanceModeIsAuto;
154		u8 redGain;
155		u8 greenGain;
156		u8 blueGain;
157	} colourBalance;
158	struct {
159		u8 divisor;
160		u8 baserate;
161	} sensorFps;
162	struct {
163		u8 gain1;
164		u8 gain2;
165		u8 gain4;
166		u8 gain8;
167	} apcor;
168	struct {
169		u8 flickerMode;
170		u8 coarseJump;
171		u8 allowableOverExposure;
172	} flickerControl;
173	struct {
174		u8 gain1;
175		u8 gain2;
176		u8 gain4;
177		u8 gain8;
178	} vlOffset;
179	struct {
180		u8 mode;
181		u8 decimation;
182	} compression;
183	struct {
184		u8 frTargeting;
185		u8 targetFR;
186		u8 targetQ;
187	} compressionTarget;
188	struct {
189		u8 yThreshold;
190		u8 uvThreshold;
191	} yuvThreshold;
192	struct {
193		u8 hysteresis;
194		u8 threshMax;
195		u8 smallStep;
196		u8 largeStep;
197		u8 decimationHysteresis;
198		u8 frDiffStepThresh;
199		u8 qDiffStepThresh;
200		u8 decimationThreshMod;
201	} compressionParams;
202	struct {
203		u8 videoSize;		/* CIF/QCIF */
204		u8 subSample;
205		u8 yuvOrder;
206	} format;
207        struct {                        /* Intel QX3 specific data */
208                u8 qx3_detected;        /* a QX3 is present */
209                u8 toplight;            /* top light lit , R/W */
210                u8 bottomlight;         /* bottom light lit, R/W */
211                u8 button;              /* snapshot button pressed (R/O) */
212                u8 cradled;             /* microscope is in cradle (R/O) */
213        } qx3;
214	struct {
215		u8 colStart;		/* skip first 8*colStart pixels */
216		u8 colEnd;		/* finish at 8*colEnd pixels */
217		u8 rowStart;		/* skip first 4*rowStart lines */
218		u8 rowEnd;		/* finish at 4*rowEnd lines */
219	} roi;
220	u8 ecpTiming;
221	u8 streamStartLine;
222};
223
224enum v4l_camstates {
225	CPIA_V4L_IDLE = 0,
226	CPIA_V4L_ERROR,
227	CPIA_V4L_COMMAND,
228	CPIA_V4L_GRABBING,
229	CPIA_V4L_STREAMING,
230	CPIA_V4L_STREAMING_PAUSED,
231};
232
233#define FRAME_NUM	2	/* double buffering for now */
234
235struct cam_data {
236	struct cam_data **previous;
237	struct cam_data *next;
238
239        struct semaphore busy_lock;     /* guard against SMP multithreading */
240	struct cpia_camera_ops *ops;	/* lowlevel driver operations */
241	void *lowlevel_data;		/* private data for lowlevel driver */
242	u8 *raw_image;			/* buffer for raw image data */
243	struct cpia_frame decompressed_frame;
244                                        /* buffer to hold decompressed frame */
245	int image_size;		        /* sizeof last decompressed image */
246	int open_count;			/* # of process that have camera open */
247
248				/* camera status */
249	int fps;			/* actual fps reported by the camera */
250	int transfer_rate;		/* transfer rate from camera in kB/s */
251	u8 mainsFreq;			/* for flicker control */
252
253				/* proc interface */
254	struct semaphore param_lock;	/* params lock for this camera */
255	struct cam_params params;	/* camera settings */
256	struct proc_dir_entry *proc_entry;	/* /proc/cpia/videoX */
257
258					/* v4l */
259	int video_size;			/* VIDEO_SIZE_ */
260	volatile enum v4l_camstates camstate;	/* v4l layer status */
261	struct video_device vdev;	/* v4l videodev */
262	struct video_picture vp;	/* v4l camera settings */
263	struct video_window vw;		/* v4l capture area */
264
265				/* mmap interface */
266	int curframe;			/* the current frame to grab into */
267	u8 *frame_buf;			/* frame buffer data */
268        struct cpia_frame frame[FRAME_NUM];
269				/* FRAME_NUM-buffering, so we need a array */
270
271	int first_frame;
272	int mmap_kludge;		/* 'wrong' byte order for mmap */
273	volatile u32 cmd_queue;		/* queued commands */
274};
275
276/* cpia_register_camera is called by low level driver for each camera.
277 * A unique camera number is returned, or a negative value on error */
278struct cam_data *cpia_register_camera(struct cpia_camera_ops *ops, void *lowlevel);
279
280/* cpia_unregister_camera is called by low level driver when a camera
281 * is removed.  This must not fail. */
282void cpia_unregister_camera(struct cam_data *cam);
283
284/* raw CIF + 64 byte header + (2 bytes line_length + EOL) per line + 4*EOI +
285 * one byte 16bit DMA alignment
286 */
287#define CPIA_MAX_IMAGE_SIZE ((352*288*2)+64+(288*3)+5)
288
289/* constant value's */
290#define MAGIC_0		0x19
291#define MAGIC_1		0x68
292#define DATA_IN		0xC0
293#define DATA_OUT	0x40
294#define VIDEOSIZE_QCIF	0	/* 176x144 */
295#define VIDEOSIZE_CIF	1	/* 352x288 */
296#define VIDEOSIZE_SIF	2	/* 320x240 */
297#define VIDEOSIZE_QSIF	3	/* 160x120 */
298#define VIDEOSIZE_48_48		4 /* where no one has gone before, iconsize! */
299#define VIDEOSIZE_64_48		5
300#define VIDEOSIZE_128_96	6
301#define VIDEOSIZE_160_120	VIDEOSIZE_QSIF
302#define VIDEOSIZE_176_144	VIDEOSIZE_QCIF
303#define VIDEOSIZE_192_144	7
304#define VIDEOSIZE_224_168	8
305#define VIDEOSIZE_256_192	9
306#define VIDEOSIZE_288_216	10
307#define VIDEOSIZE_320_240	VIDEOSIZE_SIF
308#define VIDEOSIZE_352_288	VIDEOSIZE_CIF
309#define VIDEOSIZE_88_72		11 /* quarter CIF */
310#define SUBSAMPLE_420	0
311#define SUBSAMPLE_422	1
312#define YUVORDER_YUYV	0
313#define YUVORDER_UYVY	1
314#define NOT_COMPRESSED	0
315#define COMPRESSED	1
316#define NO_DECIMATION	0
317#define DECIMATION_ENAB	1
318#define EOI		0xff	/* End Of Image */
319#define EOL		0xfd	/* End Of Line */
320#define FRAME_HEADER_SIZE	64
321
322/* Image grab modes */
323#define CPIA_GRAB_SINGLE	0
324#define CPIA_GRAB_CONTINUOUS	1
325
326/* Compression parameters */
327#define CPIA_COMPRESSION_NONE	0
328#define CPIA_COMPRESSION_AUTO	1
329#define CPIA_COMPRESSION_MANUAL	2
330#define CPIA_COMPRESSION_TARGET_QUALITY         0
331#define CPIA_COMPRESSION_TARGET_FRAMERATE       1
332
333/* Return offsets for GetCameraState */
334#define SYSTEMSTATE	0
335#define GRABSTATE	1
336#define STREAMSTATE	2
337#define FATALERROR	3
338#define CMDERROR	4
339#define DEBUGFLAGS	5
340#define VPSTATUS	6
341#define ERRORCODE	7
342
343/* SystemState */
344#define UNINITIALISED_STATE	0
345#define PASS_THROUGH_STATE	1
346#define LO_POWER_STATE		2
347#define HI_POWER_STATE		3
348#define WARM_BOOT_STATE		4
349
350/* GrabState */
351#define GRAB_IDLE		0
352#define GRAB_ACTIVE		1
353#define GRAB_DONE		2
354
355/* StreamState */
356#define STREAM_NOT_READY	0
357#define STREAM_READY		1
358#define STREAM_OPEN		2
359#define STREAM_PAUSED		3
360#define STREAM_FINISHED		4
361
362/* Fatal Error, CmdError, and DebugFlags */
363#define CPIA_FLAG	  1
364#define SYSTEM_FLAG	  2
365#define INT_CTRL_FLAG	  4
366#define PROCESS_FLAG	  8
367#define COM_FLAG	 16
368#define VP_CTRL_FLAG	 32
369#define CAPTURE_FLAG	 64
370#define DEBUG_FLAG	128
371
372/* VPStatus */
373#define VP_STATE_OK			0x00
374
375#define VP_STATE_FAILED_VIDEOINIT	0x01
376#define VP_STATE_FAILED_AECACBINIT	0x02
377#define VP_STATE_AEC_MAX		0x04
378#define VP_STATE_ACB_BMAX		0x08
379
380#define VP_STATE_ACB_RMIN		0x10
381#define VP_STATE_ACB_GMIN		0x20
382#define VP_STATE_ACB_RMAX		0x40
383#define VP_STATE_ACB_GMAX		0x80
384
385/* ErrorCode */
386#define ERROR_FLICKER_BELOW_MIN_EXP     0x01 /*flicker exposure got below minimum exposure */
387
388#define ALOG(lineno,fmt,args...) printk(fmt,lineno,##args)
389#define LOG(fmt,args...) ALOG((__LINE__),KERN_INFO __FILE__":"__FUNCTION__"(%d):"fmt,##args)
390
391#ifdef _CPIA_DEBUG_
392#define ADBG(lineno,fmt,args...) printk(fmt, jiffies, lineno, ##args)
393#define DBG(fmt,args...) ADBG((__LINE__),KERN_DEBUG __FILE__"(%ld):"__FUNCTION__"(%d):"fmt,##args)
394#else
395#define DBG(fmn,args...) do {} while(0)
396#endif
397
398#define DEB_BYTE(p)\
399  DBG("%1d %1d %1d %1d %1d %1d %1d %1d \n",\
400      (p)&0x80?1:0, (p)&0x40?1:0, (p)&0x20?1:0, (p)&0x10?1:0,\
401        (p)&0x08?1:0, (p)&0x04?1:0, (p)&0x02?1:0, (p)&0x01?1:0);
402
403static inline void cpia_add_to_list(struct cam_data* l, struct cam_data* drv)
404{
405	drv->next = l;
406	drv->previous = &l;
407	l = drv;
408}
409
410static inline void cpia_remove_from_list(struct cam_data* drv)
411{
412	if (drv->previous != NULL) {
413		if (drv->next != NULL)
414			drv->next->previous = drv->previous;
415		*(drv->previous) = drv->next;
416		drv->previous = NULL;
417		drv->next = NULL;
418	}
419}
420
421#endif /* __KERNEL__ */
422
423#endif /* cpia_h */
424