Updates from Robert Schwebel. I also deleted a bunch of obsolete
authorDavid Schleef <ds@schleef.org>
Mon, 20 Aug 2001 00:49:11 +0000 (00:49 +0000)
committerDavid Schleef <ds@schleef.org>
Mon, 20 Aug 2001 00:49:11 +0000 (00:49 +0000)
stuff and rewrote a few bits that were only moderately wrong.

Documentation/comedi/Hardware_Driver.HOWTO

index 544a8dc22b3dc7de302cbfd0117ad356e3dc7c5f..4e7a196639f29f616b98e8c7d89714fb3b95eda5 100644 (file)
-
 Hardware driver interface
-
+=========================
 
 [ this is a little outdated -ds ]
 [ this is a lot outdated -fmh ]
+[ this is a little bit less outdated, hopefully -rs ]
+
+
+Table of Contents
+=================
+
+1. Introduction
+2. The source tree
+3. Adding new drivers
+4. Driver basics
+5. Instructions
+
+
 
 
 1. Introduction
 
-This comedi hardware driver writing HOWTO is written to help you
-write a driver for your particular choice of hardware.  You should
-be familiar with how comedi works from the user's point of view,
-i.e., from a process that is utilizing the comedi driver.
+This comedi hardware driver writing HOWTO is written to help you write a
+driver for your particular choice of hardware.  You should be familiar with
+how comedi works from the user's point of view, i.e., from a process that is
+utilizing the comedi driver.
+
+This guide does not explain the details of things like reading and writing
+I/O ports, Linux kernel internals, or interrupt processing. These issues are
+covered in other documents, e.g.
+
+- The IO-Port Programming Mini HOWTO:
+  http://www.linuxdoc.org/HOWTO/mini/IO-Port-Programming.html
+
+- Linux Kernel Module Programming Guide
+  http://www.linuxdoc.org/LDP/lkmpg/mpg.html
+
+- Kernel Hacker's Guide
+  http://www.linuxdoc.org/LDP/khg/HyperNews/get/khg.html
+
+- The Linux source
+
 
-This guide does not explain the details of things like reading
-and writing I/O ports, Linux kernel internals, or interrupt
-processing.  These issues are covered in other documents,
-specifically, the IO-Port-Programming mini-HOWTO, the Kernel
-Hacker's Guide, and the Linux source.
 
 
 2. The source tree
 
-As of comedi-0.5.0, hardware drivers need to be part of the
-source tree and be compiled with the rest of the comedi driver
-into the module comedi.o.  Later versions will hopefully support
-separate compiling/separate modules, etc.
+Currently hardware drivers need to be part of the source tree and be
+compiled with the rest of the comedi driver into the module comedi.o.  Later
+versions will hopefully support separate compiling/separate modules, etc.
+
+The source for the comedi module is located in the 'comedi/' directory,
+including the device independent part. The source files of the hardware
+drivers for the different boards are located in 'comedi/drivers/', the
+kernel space library (which is used for accessing comedi from realtime
+programs) lives in 'comedi/kcomedilib/'.
+
+In the drivers' directory there is a striped-down example ('skel.c') that
+may be a good starting point for new hardware drivers. 
+
+
+
 
-The source for the comedi module is located in module/, including
-the device independent part and each hardware driver.  A hardware
-driver, such as the "dt282x" driver, is typically located in the
-C source file of the same name.
+3. Adding new drivers
 
-The hardware driver "dummy" is a stripped-down example that may be
-a good starting point for new hardware drivers.
+The best way to write a new driver is to take one of the existing ones (e.g.
+the 'skel' driver) and modify it to your own needs. For integrating new
+drivers in the comedi source tree the following things have to be done:
 
+- Put your new driver into 'comedi/drivers/mydriver.c'. 
+- Edit 'comedi/Config.in' and add a new 'dep_tristate' line (look at the
+  other examples). Invent a senseful name for the driver's variable. 
+- Add a line to 'comedi/drivers/Makefile', using your freshly defined 
+  variable. 
 
-3. comedi_config and *_init()
+Now 'make distclean', reconfigure comedi with a new 'make', rebuild and be
+happy. If you want to have your driver included in the comedi distribution
+(you _definitely_ want to :) ) send it to David Schleef <ds@schleef.org> for
+review and integration.
 
-The file "module/comeditypes.c" has a list of the initialization
-functions for all the drivers.  You should add your init function
-to this list.  The top level Makefile and scripts/configure
-take care of all the defines.
 
-The purpose of comeditypes.c is to keep a list of available
-hardware drivers by keeping a list of available initialization
-functions.  Thus, when comedi_config is run, it issues the
-COMEDI_CONFIG ioctl() with the name of the driver and
-configuration parameters (I/O port address, irq, dma, etc.).
-The comedi driver then calls the initialization function of
-each hardware driver on the list.
 
-Inside the initialization function, you should perform the
-following tasks:
 
-   o  Check to see if you are the correct hardware driver
-      for the name specified in the comedi_devconfig structure.
-      Your hardware driver may consider several names as
-      "correct", and even behave differently depending on
-      the name given.  The idea here is to support different
-      cards in a series using different names, but using the
-      same hardware driver.  If you are not the correct
-      hardware driver, return a 0.
+4. Driver basics
 
-   o  Announce that the hardware driver has begun initialization
-      by a printk("comedi%d: driver: ",minor);
+Implementation details for the following things can be found in the skel
+driver. Each driver has to register two functions which are called when you
+configure and deconfigure your board:
 
-   o  Check and request the I/O port region, IRQ, DMA, and other
-      hardware resources.  It is convenient here if you verify the
-      existence of the hardware and the correctness of the other
-      information given.  Sometimes, unfortunately, this cannot
-      be done.
+- mydriver_attach()
+- mydriver_detach()
+
+In the 'attach' function all properties of a device and its subdevices are
+defined. As part of this pointers to the low level instructions being
+supported by the subdevice have to be set (see next section) which define
+the basic functionality. 
+
+
+
+5. Instructions
+
+Instructions (insns) are comedi's low level functins for accessing all kinds
+of channels, like analog or digital IOs. 
+
+Drivers for digital IOs should implement the following functions: 
+
+- insn_bits(): 
+  Drivers set this if they have a function that supports reading and writing
+  multiple bits in a digital I/O subdevice at the same time.  Most (if not
+  all) of the drivers use this interface instead of insn_read and insn_write
+  for DIO subdevices.
+
+- insn_config(): 
+  Implements INSN_CONFIG instructions.  Currently used for configuring the
+  direction of digital I/O lines, although will eventually be used for
+  generic configuration of drivers that is outside the scope of the
+  currently defined Comedi interface.
+
+Drivers for analog IOs should implement these function: 
+
+- insn_read(): 
+  Analog inputs have to implement insn_read. 
+
+- insn_write(): 
+  The same with insn_write. 
+
+
+[THIS SEEMS TO BE OBSOLETE??? -rs] -------------------------------------------
+
+Inside the initialization function, you should perform the following tasks:
+
+   o  Announce that the hardware driver has begun initialization by a
+      printk("comedi%d: driver: ",minor);
+
+   o  Check and request the I/O port region, IRQ, DMA, and other hardware
+      resources.  It is convenient here if you verify the existence of the
+      hardware and the correctness of the other information given. 
+      Sometimes, unfortunately, this cannot be done.
 
    o  Fill in the comedi_device structure.
 
-   o  Allocate your private data structure and space for channel
-      configuration.
-
-   o  Configure each channel.  Each channel has three function
-      pointers:  one for triggering a single conversion (itrig),
-      one for triggering general conversions (trig), and one
-      for setting channel parameters (sp).  Each channel also has
-      a parameter linked list.
-      Parameters are added to this list via addparam().  All the
-      parameter routines are in param.c.  They are currently not
-      very efficient, so if you know of a better algorithm...
-      Look at the header files for parameter types that you may
-      wish to include.
-
-   o  Initialize the read buffer via comedi_initbuf().  The buffering
-      routines are in buffer.c, and support multiple processes
-      reading the same device.  The buffers are also dynamic, so
-      you don't have to worry about the hardware driver collecting
-      1M of data before the controlling process reads it.  I've been
-      using these routines for a while--they appear to be pretty
-      stable.  Most of the error messages you get from the buffer
-      routines indicate memory leaks.
-
-   o  Set mtrig in the comedi_device structure to the function that
-      is called for a channel scan trigger.
-
-   o  Tell the comedi driver the function to call when your driver
-      needs to be removed.
-
-   o  Return a 1.  If there were any errors along the way, you
-      should return the appropriate error number, but don't forget
-      to release any resources that you allocated.  (It will only
-      take one time to realize that if you don't release an I/O region,
-      you have to reboot to get it back.  (Or write a hack, as I did.))
-
-
-4. Set Parameter routines
-
-When the COMEDI_SETPARAM ioctl() is called, the comedi driver
-calls the setparameter routine of the channel involved.  Common
-settable parameters are input gain (input range) and setting bits
-on digital I/O lines as input or output.  The setparameter
-function should check the validity of the parameter type and
-value, and then call changeparam() to update the parameter
-linked lists.  If necessary, calls to update the hardware
-should be made.
-
-
-5. Triggering routines
-
-Like the setparameter routines, each channel has a trigger
-function that is called for a COMEDI_TRIG ioctl().  The trigger
-function is called with the comedi_trig structure, which
-includes the trigger type, number of samples, and one sample value
-(which may be read or written, depending on context).
-
-As of 0.5.0, there are two triggering routines per channel, one
-for TRIGNOW, and one for all the rest.  The reason this was done
-is because the TRIGNOW functions are exported to the rest of the
-kernel (i.e., for RTLinux).
-
-Trigger types are accompanied by the trigger variable, which
-is interpreted based on the trigger type.  The types of triggers
-(currently) available are:
-
-   o  COMEDI_TRIGNOW - causes one sample conversion to be
-      completed immediately.  The trigger variable and number of
-      samples are ignored.
-
-   o  COMEDI_TRIGCLK - causes conversions timed by a clock on
-      the hardware.  The trigger variable determines the clock
-      speed.
-
-   o  COMEDI_TRIGEXT - causes conversions to be triggered by
-      an external trigger provided by the hardware.  The trigger
-      variable determines the particular choice, if there is
-      more than one choice.
-Other trigger sources that may be defined in the future are
-analog triggers and comedi triggers.  Comedi triggers could include
-the 100 Hz interrupt, the rtc interrupt, general timing triggers,
-signals generated by other boards, etc.
-
-Except for COMEDI_TRIGNOW, your triggering routine should return
-after telling the hardware to perform the requested task.  For
-COMEDI_TRIGNOW on input, you should wait for the conversion to
-finish and return it in the ioctl structure, but do *NOT* report
-the sample via report_sample().
-
-Typically, you will poll the hardware or the hardware will
-generate interrupts to tell you when samples are ready.  The
-samples should be reported via report_sample().
-
-
-6. The remove function
-
-A driver is removed from service via a call to dev->rem().  The driver
-is expected to halt all conversions, put the hardware in a sane,
-off-line state, delete all channel parameters, free all allocated memory,
-and release any irq's and port addresses held.  If these things are
-not all done, there will be memory leaks, and more importantly, the
-driver will not configure properly if reused.
+   o  Allocate your private data structure and subdevices.
+
+   o  Set up each subdevice.
+
+   o  Return 0, indicating sucess.  If there were any errors along
+      the way, you should return the appropriate error number.  If
+      an error is returned, the _detach function is called.  The
+      _detach function should check any resources that may have been
+      allocated and release them as necessary.  The comedi core frees
+      dev->subdevices and dev->private, so this does not need to be
+      done in _detach.
 
 
 A. Goals
@@ -204,4 +178,3 @@ A few things to strive for:
 
 
 
-