$Id: README,v 1.5 1998/10/14 20:28:19 sanne Exp $
-------------------------------------------------------------------------------
                 Linux loadable kernel module for Intel 8255
                   'programmable peripheral interface' chip
                             (and compatibles)
				  v 0.2	     

                   by Sanne Graaf <sanne@mmm.xs4all.nl>				 
				 
		   http://www.xs4all.nl/~sgraaf/i8255/				 
				 

0. Index:       ---------------------------------------------------------------

	    1. Overview.
	      1.1 License/warrant.
	      1.2 Installation.
	    2. A bit info about the 8255.
	      2.1 Register D (configuration) layout.
	    3. About the driver.
              3.1 Driver version.
	      3.2 ioctl and structures info.
	      3.3 i8255_struct description.
	      3.4 ioctl functions.
	      3.5 Interrupt support.
	      3.6 Adding a register layout.
	    4. Device files.
	    5. /proc files.
	    6. Command line.
	      6.1 Command line Parameters.
	      6.1 Command line Examples.
	    7. Hardware.
	      7.1 Tested devices.
	      7.2 Tested platforms.
	    8. Todo.

	    
1. Overview:       ------------------------------------------------------------

  This little piece of software is a kernel driver module for controlling
  an Intel 8255 chip (or compatible). The 8255 is a digital I/O chip which
  has 24 TTL level I/O lines (grouped in 3* 8 bit ports). This driver can
  read from, or write to these ports. The 8255 has 3 modes of operation,
  this driver only supports mode 0 in which the 8255 can be used as raw input
  or output device. This driver does the low level communication to the 8255
  chip, the only thing it does by itself is setting all ports in input mode to
  be sure that no short circuits are made. There are no fancy routines for 
  configuring each port to INPUT or OUTPUT, cause at this point I see no reason
  why they should be implemented, so data sheets are RECOMMENDED for using this
  driver. (http://www.intel.com/design/periphrl/datashts/)


 1.1 License/warrant:       ---------------------------------------------------
 
  This program is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the Free
  Software Foundation; either version 2 of the License, or (at your option)
  any later version.
 
  This program is distributed in the hope that it will be useful, but WITHOUT
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  more details.
 
  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING.  If not, write to
  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.

  
 1.2 Installation:       ------------------------------------------------------
  
  First check if the default maximum number of devices (10) is sufficient and
  edit i8255.h (MAX_DEVICES) if necessary. (Don't increase it unnecessary cause
  for every device a static structure is created and memory space for kernel
  modules is limited)
  
  then:
  
  make 
	       which builds three module files (i8255.o, pcl731.o, pcm3724.o).
               become root and run:
  make devices
              which makes 24 device files (/dev/i8255a , b, c, d, ...).
	      
  now you can insmod the i8255 (or one of the other) modules,
  read section 5 about the command line parameters.
  
  copy the modules files to /lib/modules/misc or any other directory where 
  your module loader will find it and add the following two lines (for each
  module, - read Makefile for examples- ) to your modules.conf
  (or conf.modules) file:
  
  alias char-major-64 i8255
  options i8255 <command line parameters>
  
  and demand loading will ease things.  
     
   
2. A bit info about the 8255:       -------------------------------------------

  Again, get the data sheets for all information, but for a little info:

  The 8255 has 4 registers, 3 registers are used for INPUT or OUTPUT and one
  register is used for configuring the chip itself. Selecting whether a port
  is used for input or output is possible for each port (8 bits, port A and 
  port B), port C can be configured on a nibble basis (4 bits). This
  configuration is done by setting a couple of bits in register D. When a
  port is configured as input and a read at that port occurs the 8255 will
  put the current value of that port on the data bus. If a port is configured
  as output and a write occurs it will write the data from the data bus to
  that port. The 8255 itself is TTL compatible so a logical '0' will be about
  0 volt at the output pins and a logical '1' will result in a voltage of
  5 volt at the output pins.  


 2.1 Register D (configuration) layout:       ---------------------------------
  
  bit 0 - Port C (lower): 1-in, 0-out.
      1 - Port B: 	  1-in, 0-out.
      2 - Mode select:	  0-mode 0, 1-mode 1.
      3 - Port C (upper): 1-in, 0-out.
      4 - Port A: 	  1-in, 0-out.
      5 - Mode select:	  00-mode 0, 01-mode 1, 1x-mode 2.
      6 - ^^^
      7 - Mode set flag:  1-active.


3. About the driver:       ----------------------------------------------------

  The driver (currently) only supports mode 0 of the 8255 which means that all
  three ports are manual writable/readable. (In other modes port C will be
  split to half and those 4 bits are used for strobing and other control
  signals). So your computer suddenly has 24 bits which can freely be used for
  controlling and switching any logic circuitry you can think of. 
  
  When this driver loads it will try to get control of the selected 8255('s)
  and will initialize it's device file('s) (major 64). This driver can control
  more 8255's and each 8255 can be used multiple times (for example by more 
  processes), in this case each 8255 will get it's own minor number
  (starting with 0). The maximum number of devices which can be controlled
  is default defined as 10, but can be changed in the header file.

  When the driver is loaded it can be used in two ways:
  
  1. Direct reading and writing to the device files. (not very useful)

     If the device file is read (using 'cat /dev/i8255a' for example) the
     driver will constantly read all registers and output them to the 
     reading process. Output format is register A, B, C, D.

     Writing to the device file will write the first 4 bytes from the 
     input to registers A, B, C, D.
     
     
  2. ioctl function calls. This is the recommended way of using this driver.
     The detailed description of how to do this is described below.
     
    
 3.1 Driver versions:	-------------------------------------------------------

  From version 0.2 this module supports, besides the generic i8255 device
  driver, two other drivers. These drivers are for easy controlling i8255
  compatible cards which have more or special registers. At the moment there
  are two, but adding more is really simple, and descibed below.
  
  pcl731.o  - Advantech card ISA, emulates 2 8255's.
              Regs: A0, B0, C0, D0, A1, B1, C1, D1.
  
  pcm3724.o - Advantech card PC/104, emulates
	      Regs: A0, B0, C0, D0, A1, B1, C1, D1, DIRECTION, GATE.          

  The register layout of these various devices is defined in the i8255.h
  header file. Each drives gets it's own register layout at compile time
  (by using various #define's), so all drivers can be loaded at the same
  time (and each uses a different MAJOR device number).
  
  When compiling applications who include i8255.h you will have to use
  the appropriate compiler defines (gcc -DBLABLA -o etc etc).
  
  
 3.2 ioctl and structures info:       -----------------------------------------

  The most practical way of controlling the driver is by using the ioctl
  call. The ioctl call must have 2 or 3 arguments, first is the file descriptor
  of the device file, second is the driver function number/name and most
  functions need a third parameter (see also: ioctl manual). If a third
  parameter is needed it will be the address of a structure.
  
  example:	struct i8255_struct mystruct;
                ...				// fill mystruct and open device
		... 
                result = ioctl(fd, I8255_WRITE, &mystruct);
		...
		
				
 3.3 i8255_struct description:       ------------------------------------------
  
    struct i8255_struct {
	int regnum;
	u_char value;
	u_char bitno;
    };
    

    regnum:
	    register to perform function on: REG_A, REG_B, REG_C, REG_D.
	    required for all functions that require argument 3 in ioctl call.	    

    value:
	    value to write to selected register.
	    required for write function only.
	    
  bitno:
           this register must contain a bit mask for selecting which bits
	   must be set or cleared: BIT0 ... BIT7, can be AND'ed using bitwise
	   AND (&).
	   required for readbit, setbit and clrbit functions only.



 3.4 ioctl functions:       ---------------------------------------------------

  Here's the list of currently implemented functions:

    I8255_RESET (0):
    
	Set all ports on input and update local copy of 8255's registers.
	Argument 3: none
	Returns   : always 0


    I8255_DEBUG (1):
    
	Set debug level to other value.
	Argument 3: New debug level (0..3)
	Return    : always 0
    
    
    I8255_EXCL (2):
    
	(Re)Set Exclusive device mode.
	Argument 3: 0 - Not Excl, 1 - Exclusive
	Return	  : always 0

			
    I8255_TEST (3):		!! Dropped at version 0.2, use /proc fs !!
    
	Dump local register copies (and some other info) to syslog.
	Argument 3: none
	Returns: always 0

		    
    I8255_READ (4):

        Read selected register.
	Argument 3: address of filled i8255_struct
	Returns   : value read

		
    I8255_WRITE (5):
    
	Write to selected register.
	Argument 3: address of filled i8255_struct
	Returns   : always 0

	
    I8255_SETBIT (6):
    
	Set one or more bits from a selected port and bitno.
	Argument 3: address of filled i8255_struct
	Returns   : always 0

		
    I8255_CLRBIT (7):

	Clears one or more bits from a selected port and bitno.
	Argument 3: address of filled i8255_struct
	Returns   : always 0

	    
    I8255_READBIT (8):

	Read one bit from a selected port and bitno.
	Argument 3: address of filled i8255_struct
	Returns   : 1 if set else 0


 3.5 Interrupt support:       -------------------------------------------------


Comming Soon...


		
 3.6 Adding a register layout:       ------------------------------------------	


Comming Soon...

	
4. Device files:       --------------------------------------------------------	

  For communication to the driver device files are used, one for each 8255.
  The path of these files is default /dev/i8255a for device 1, /dev/i8255b 
  for 2 etc.. and for each driver another set of files is used.
  
  The default major number is 64, but can be changed in i8255.h (I8255_MAJOR).
  Minor numbers are assigned to each device, first 8255 device = 0, second = 1,
  etc..
  
  These files can be created using mknode:

   Generic i8255:
  
      mknode /dev/i8255a c 64 0			(first)
      mknode /dev/i8255b c 64 1			(second)
      mknode /dev/i8255c c 64 2			(third)
      ...
      ...

   pcl731:
  
      mknode /dev/pcl731a c 63 0		(first)
      mknode /dev/pcl731b c 63 1		(second)
      mknode /dev/pcl731c c 63 2		(third)
      ...
      ...

   pcm3724:
  
      mknode /dev/pcm3724a c 62 0		(first)
      mknode /dev/pcm3724b c 62 1		(second)
      mknode /dev/pcm3724c c 62 2		(third)
      ...
      ...


  Any path or filename may be used, only major and minor numbers matter when
  accessing the file.
    	

5. /proc files:       ---------------------------------------------------------


Comming Soon...  

	  
6. Command line:       --------------------------------------------------------

    insmod i8255 ioport=addr irq=irq exclusive=[0/1]

    or

    insmod pcl731 ioport=addr irq=irq exclusive=[0/1]

    or

    insmod pcm3724 ioport=addr irq=irq exclusive=[0/1]


 6.1 Command line parameters:       -------------------------------------------

    ioport=addr,[addr],...

	ioport must be followed by one or more IO addresses.

    irq=irq,[irq],...

	irq isn't a mandatory option but if used must be followed by a list
	of irq numbers, if irq number is 0, nu irq will be used for that device.
	If this option is not used, no device will use IRQ.

    exclusive=[0/1],[0/1],...

	exclusive isn't a mandatory option but if used must be followed by a
	list of 0's or 1's. If set to 1, the device file can only be opened one
	time, if 0 it can be opened more times.
	If this option is not used, all devices will allow multiple open
	device files.
	
    debug=[0/1/2/3]

	This option isn't mandatory either and default 0, but if set to a value
	between 1 and 3 it will generate an increasing number of debug output
	to syslog. If not used no logging will be done.
	Log levels are defined as:
	
	0 - None
	1 - Basic functions and things going on, one message for each command.
	2 - More detailed register messages, more messages for each command.
	3 - ALL written and read registers, total syslog flood...
	
	Debug levels are only useful when stepping thru a program with a 
	debugger, with normal execution messages will flood your syslog.

    slowio=[0/1]
    
	Also not mandatory, but if set to 1 will use inb_p and outb_p instead
	of inb and outb.

    proc=[0/1]
    
	Not mandatory, is 1 by default. This option controls the use of
	/proc directory files. If set to 0 no 'running data' files will be
	available.
		
	
 6.2 Command line Examples:       ----------------------------------------------

    insmod i8255 ioport=0x300
    
	Will configure one 8255 device on ioport 0x300, no irq, no debug, 
	no slowio, device (/dev/i8255a) may be opened multiple times.
	
    insmod i8255 ioport=0x300,0x304 slowio=1 debug=2
    
	Will configure 2 8255 devices on 0x300 and 0x304, will generate log
	messages and will use inb_p and outb_p calls. No IRQ's are used and
	all both devices (/dev/i8255a and /dev/i8255b) can be opened multiple
	times.
	
    insmod i8255 ioport=0x300,0x304,0x308,0x30c irq=5,7,0,10 exclusive=0,0,1,1
    
	Will configure 4 8255 devices:
	
	1. ioport; 0x300 .. 0x303
	   irq: 5
	   open: multiple
	   dev: /dev/i8255a    

	2. ioport; 0x304 .. 0x307
	   irq: 7
	   open: multiple
	   dev: /dev/i8255b

	3. ioport; 0x308 .. 0x30B
	   irq: none
	   open: only once
	   dev: /dev/i8255c    

	4. ioport; 0x30C .. 0x30F
	   irq: 10
	   open: only once
	   dev: /dev/i8255d    


7. Hardware:       ------------------------------------------------------------	   

  Various hardware from various brands are on the market which can be used
  with this driver. Some cards do actually have an i8255, other cards emulate
  the i8255 chip with other IC's.
  
  So when you want to buy a card, make sure it's at least i8255 mode 0 
  compatible. 

  I've tested three cards, one real Intel 8255 card, home brew from a dutch
  electronics magazine. One Taiwan build clone card using a NEC chip. And
  one brand card from Advantech pcl731, which emulates 8255 mode 0.
  
  The electronics on these cards doesn't qualify as high tech, so it's
  pretty easy, for someone who has build printed circuits before, to make
  a 8255 ISA-bus card.


 7.1 Tested devices:	-------------------------------------------------------

    * Generic 8255 card
    * Advantech PCL-731
    * Advantech PCM-3724

    Please inform me about other cards that work too.


 7.2 Tested platforms:		-----------------------------------------------
   
    * Redhat 5.1
    * Redhat 5.0
    * Redhat 4.2

    Please inform me about other distributions of platforms that work too.

  
8. Todo:       ----------------------------------------------------------------  


- Better Interrupt support.

- change init code so it can be a static compiled kernel driver.

- mode 2 support (??)

-------------------------------------------------------------------------------	   