/* Header file for Frame Grabber device driver */
/* Frame Grabber:  CX100, ImageNation Corporation */
/* Documentation in second half of this file. */

#ifndef _CX100_H_
#define _CX100_H_

/* Various ioctl() requests */
#define FG_NOP							0x00
#define FG_BOARD_ON					0x01
#define FG_BOARD_OFF					0x02
#define FG_SET_BASE_PORT   		0x03
#define FG_GET_BASE_PORT   		0x04
#define FG_SET_ADDRESS				0x05
#define FG_GET_ADDRESS				0x06
#define FG_ACQUIRE					0x07
#define FG_ACQUIREF					0x08
#define FG_IS_CCIR					0x09
#define FG_GRAB						0x0A
#define FG_GRAB_FIELD				0x0B
#define FG_WAITVB						0x0C
#define FG_CX100						0x0D
#define FG_DELAY						0x0E
#define FG_SET_RAM					0x0F
#define FG_SET_VERTICAL_ACCESS	0x10
#define FG_SET_RESOLUTION			0x11		/* 0 - low  1 - high */
#define FG_GET_RESOLUTION			0x12
#define FG_GET_RGB_LUT				0x13
#define FG_SET_PAGE					0x14
#define FG_GET_PAGE					0x15
#define FG_IMAGEWIDTH				0x16
#define FG_IMAGEHEIGHT				0x17

#define FG_SET_MODE					0x20


/* Different modes of operation for I/O calls */
#define FG_MODE_NORMAL				0x00
#define FG_MODE_OVERLAY				0x01
#define FG_MODE_OUTPUTLUT			0x02
#define FG_MODE_INPUTLUT			0x03

#define FG_MODE_MAX					0x04



/***************************************************************/

/* Programmer's note:
	I strongly discourage use of these ioctl() calls directly.  In
	normal circumstances, the cxlib library should be sufficient.  If
	you think something should be added to the library, feel free to
	request it or send me your modifications to the library.

	It also makes your code MUCH easier to read without millions of
	ioctl()'s lying all over the place.
*/

/*

The more important functions:
	FG_BOARD_ON
		no argument
		Turns the frame grabber on.
	FG_BOARD_OFF
		no argument
		Turns the frame grabber off.
	FG_SET_RESOLUTION
		You have two choices for "arg": 1 for high resolution, and 0 for
		low resolution.
	FG_GET_RESOLUTION
		Returns the current resolution.  (1 for high, 0 for low)
	FG_IMAGEWIDTH
		Returns the image width for the current resolution
	FG_IMAGEHEIGHT
		Returns the image height for the current resolution
	FG_SET_RAM
		If "arg" is 1, this will make the RAM address of the frame
		grabber accessible.  This should always be on when the frame
		grabber is on.
	FG_SET_VERTICAL_ACCESS
		Seetting "arg" to 1 changes the orientation of the frame
		grabber's address space.  If vertical access is enabled, reading a
		contiguous set of bytes will correspond to a vertical column of
		data.
	FG_IS_CCIR
		Returns the video format of the camera.  It will return 1 if it
		is in CCIR mode.


The following functions are safe, but it usually shouldn't be necessary
to call these:

	FG_CX100
		This turns on the board and puts in in CX100 mode.  Note: This
		is done automatically with every FG_BOARD_ON call.  It should
		not normally be necessary to use this function.
	FG_GRAB
		Causes a frame grab
	FG_GRAB_FIELD
		Grabs just one page (the current one)
	FG_DELAY
		Produces a delay of "arg" units long.  A "unit" is somewhere on
		the order of a microsecond.  However, it seems to vary between
		machines.  You can expect it to be within one order of
		magnitude.
	FG_SET_PAGE
		Sets the current age to "arg".  There are 4 possible pages,
		ranging from 0 to 3.
	FG_GET_PAGE
		Returns the current page, ranging from 0 to 3.
	FG_GET_BASE_PORT
		Returns the current base port.
	FG_GET_ADDRESS
		Returns the address the frame grabber is using.  This will range
		from 0x08 to 0x0D.  You should shift this byte 16 bits to the left
		to get the linear address.
		This also updates the driver's internal address lookup, so it's a
		good idea to call this after setting the address.

These functions should not normally be touched:
	FG_SET_BASE_PORT
		arg = value of port (0x230 is default, to 0x268, in increments of 8 )
		Returns the newly set port.
		If arg is invalid, ioctl() will return -EINVAL.
	FG_SET_ADDRESS
		arg = address segment to use.  Default is 0xA0000.
			Range: 0x80000 to 0xD0000.
			You must specify your addresses from 0x08 to 0x0D.
		Returns the newly set address.
		If arg is invalid, ioctl() will return -EINVAL.
	FG_ACQUIRE
		no argument
		waits for vertical blank.  Puts board into ACQUIRE mode
	FG_ACQUIREF
		no argument
		doesn't wait for VB.  But still puts board into ACQUIRE mode.
	FG_WAITVB
		noargument
		This waits for a vertical blank signal.  This returns 1 if
		successful, 0 if failed.

These functions are in limbo right now, and their functions are
currently undefined:
	FG_GET_RGB_LUT
		???
	FG_SET_INPUT_LUT
		???

Notes:
	FG_SET_BASE_PORT simply takes the value you pass to it, and
		attempts to use that as the frame grabber's base address.  There
		currently is no autodetection, and no way to determine if the
		current port is correct, short of actually using.  Therefore,
		you should not normally touch this setting.
	If you open the device driver in text mode, then go into graphics mode,
		it would be a good idea to call FG_GET_ADDRESS.  This is because
		the frame grabber defaults to address segment 0xA0000 for some
		reason.  And as we all know, VGA address space is in the same
		place.
*/

/*
	The following describes the functionality of the I/O functions on
	the device driver under normal operation:

	read(int cxfd, char *buf, int size)
		Assuming the file position is currently set to zero (see
		lseek()), this will cause a frame grab, and will read in "size"
		bytes into "buf".  If "buf" is a null pointer or if "size" is
		zero, the frame grab will still be done.  If there is no error,
		read() will always return the number of bytes required to store
		the entire image from the current position onward.
	write(int cxfd, char *buf, int size)
		Currently does nothing.
	lseek(int cxfd, int x, int y)
		whence is currently ignored.
		This will shift the current file position so that read() calls
		will start from this pixel onward.  Note: fpos is currently
		calculated by (x + imagewidth * y).  This means, of course, that
		if you wish to do the calculation yourself, you should set y to
		zero.
	open(char *fname, mode)
		This opens the device.  No real initialization is done.  The
		driver does, however, attempt to determine the current memory
		segment the frame grabber wishes to use and the current
		resolution.  These are all internal, however.
	close(int cxfd)
		It's always a good idea to close the device when you're done with it.
	ioctl(int cxfd, int request, int argument)
		This is how many of the functions of the frame grabber is
		accessed.  "request" ranges from FG_NOP to FG_SET_INPUT_LUT, and
		are listed above.  Some of these requests may take an argument.
		And should be placed in "argument".  Also, some requests return a
		value, which would be placed in the return value of the ioctl()
		call.
*/

/* The CX100 driver can be put into several modes of operation (via
	the FG_SET_MODE ioctl() request.  This will affect mainly read()
	and write() calls.  Note that the file position (ref. lseek()) will
	be preserved between mode changes.  In other words, each mode has
	it's own file position value, and each one has it's own
	interpretation fo the file position.

	The default mode is FG_MODE_NORMAL, which lets the user read in
	grabbed data via the read() system call.  The write() call
	currently does nothing.

	The FG_MODE_OVERLAY changes the functionality of the read() and
	write() calls, and gives the user access to the frame grabber's
	overlay RAM.  Although the overlay only looks at the lower 4 bits
	of every byte, each pixel is still 8 bit aligned.  This means that
	for the byte position of one (x,y) coordinate in normal mode will
	corespond to the same byte position in overlay mode.

	FG_MODE_OUTPUTLUT and FG_MODE_INPUTLUT are currently not
	implemented.
*/

#endif /* _CX100_H_ */

