/*
 *
 * cxdrv -- a driver for the cx100 frame grabber
 *
 * Copyright (C) 1995 Alessandro Rubini  --  rubini@ipvvis.unipv.it
 */

Note: this file was last modified on Oct 24th 1995. 

This device driver is conceived as a module, and it should be compiled
under the same kernel which will be used to  run it. The frame grabber
can then be used through the nodes /dev/cxg0 etc.

The major device number is generated  dynamically; thus the /dev nodes
must be recreated after each module loading. This is no problem, since
the module can  only be loaded  by root. A  small script can thus load
the module and create /dev nodes with proper permissions.


	Language interface
	------------------

This package embeds a  C library, to  ease  handling the grabber.  The
documentation  is available in "info" and   postscript format.  Public
symbols and definitions are prefixed in this way:

 Cxg_   for functions, global variables (if any) and data types
 CXG_   for preprocessor defines
 _cxg_  for global variables within the library.


	Multiple devices
	----------------

This module supports multiple boards, but it has only been used with a
single board (I'm not so rich ;-). This is likely to change in the future,
hopefully --- not my richness, only my board supply.


	Compiling and installing
	------------------------

A simple  "make" invocation will compile  the module, the  library and
the test programs. A "make install" will install  things in the proper
places,  i.e.  /usr/local/bin,  /usr/local/include, /usr/local/lib and
/usr/local/info.        The     module       is    installed        in
/lib/modules/VERSION/misc,  where   VERSION is    your   current Linux
version.


	Loading the module
	------------------

To  load the module  issue "cxg_load"; the  script is a simple wrapper
around "insmod"   which creates the   /dev  nodes  after  loading  the
module. To unload  the  module issue  "cxg_unload";  the script   is a
simple wrapper around  "rmmod" which removes the  /dev nodes  as well.
The following variables can be set when loading  the module, but their
use is discouraged   -- I used   them  during early  development,  and
they're unneeded now.

cxg_base   Can be used to select an I/O base address. Disable autodetection.
cxg_major  Select a device major number. Disables dynamic allocation.
cxg_fake   Allows a developer to load the module if the board is not there.
cxg_irq    Specify the irq for the first board. Can be overridden later.
cxg_ram    Specify the ram page for the board. Can be overridden later.


	The interface to the devices
	----------------------------

The following devices are available:

/dev/cxg0
        `Cx100 grabber' 0. This is the raw device. It can always be opened
        when a board exists in the computer. Diagnostics can be performed
        on the board, but any "real work" that requires memory mapping or
        interrupt reporting needs ioctl() invocation to ebable either
        feature. Blocking read is allowed on this device if the board
        generates interrupts.

/dev/cxg0ol
        The overlay device. If your board supports overlays, this device
        can be read-from or written-to just like /dev/cxg0. R/w
        operations will affect overlay memory instead of frame memory.
        Not tested as of 0.85

/dev/cxg0f
        Full-featured device. open() will succeed only if both
        memory-mapping and the interrupt can be detected. The first open()
        invocation may take up to 1 seconds to succeed (or fail), due to
        interrupt probing. Successive open()s will be faster because
        the probed irq number is retained. This device allows blocking
        read and selecting.

/dev/cxg0pgm
        Simple pgm device. Its opening enables memory mapping
        and continuous grabbing. This means that the device can be used as
        a simple live video. A pgm header is added to each frame. Use of
        this node can't coexist with use of other nodes, because there is
        one video memory for each board. Writing to this file changes the
        size and position of the pgm image being returned. Blocking read
        is not allowed here, not select(), due to my lazyness.

	Remarks
	-------

On  oct 8th 1995  I discovered  that  the cx100  is unable to generate
interrupts  when   driven by a   PAL  (european) camera. This  is very
unfortunate when running the board under Linux, though it makes almost
no matter under m$dog. ImageNation found the bug in the board microcode,
and they'll fix the problem in a reasonable time. Check timestamps and
ask ImageNation if in doubt about your board.

My driver should able to keep synchronization anyways. However, I've
had problem with kernel timers, so I disabled the code altogether.  If
I ever do it, the mid-busy loop used will keep the computer slightly
loaded and a one-frame error in timed-grabbing may occur. This is
unavoidable.

I recommend using  Linux 1.2.x or  1.3.x.  The driver is untested with
previous kernels.  I  usually run  one  of the latest kernels,  so the
timestamp of  the release tells  you which kernel   I used last  on my
development platform.

Enjoy, and feel free to call me for any reasonable question.

		Alessandro Rubini (rubini@ipvvis.unipv.it, rubini@systemy.it)

	Acknowledgements
	----------------

Georg v.Zezschwitz, zezschwi@kogs7.informatik.uni-hamburg.de
	Gave me the source of a working module to start with.

Jens Scholz, scholz@faw.uni-ulm.de
	Showed how easy it is to grab under Linux

`grep '^N' /usr/src/linux/CREDITS`
	Wrote the wonderful beast under it all.

ImageNation
	Provided the dos source to learn how the board works.

