]> Pileus Git - ~andy/linux/blobdiff - drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
staging: comedi: addi_apci_3xxx: clarify 'b_AvailableConvertUnit'
[~andy/linux] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci3xxx.c
index a45a2a26e0da8f11345bb556ef1a1747ccb62aab..edb91849881a5ab502b51d4b543649cb66428d84 100644 (file)
@@ -1,79 +1,7 @@
-/**
-@verbatim
-
-Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
-
-       ADDI-DATA GmbH
-       Dieselstrasse 3
-       D-77833 Ottersweier
-       Tel: +19(0)7223/9493-0
-       Fax: +49(0)7223/9493-92
-       http://www.addi-data.com
-       info@addi-data.com
-
-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; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-You should also find the complete GPL in the COPYING file accompanying this source code.
-
-@endverbatim
-*/
-/*
-  +-----------------------------------------------------------------------+
-  | (C) ADDI-DATA GmbH          Dieselstrasse 3      D-77833 Ottersweier  |
-  +-----------------------------------------------------------------------+
-  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
-  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
-  +-----------------------------------------------------------------------+
-  | Project     : APCI-3XXX       | Compiler   : GCC                      |
-  | Module name : hwdrv_apci3xxx.c| Version    : 2.96                     |
-  +-------------------------------+---------------------------------------+
-  | Project manager: S. Weber     | Date       :  15/09/2005              |
-  +-----------------------------------------------------------------------+
-  | Description :APCI3XXX Module.  Hardware abstraction Layer for APCI3XXX|
-  +-----------------------------------------------------------------------+
-  |                             UPDATE'S                                  |
-  +-----------------------------------------------------------------------+
-  |   Date   |   Author  |          Description of updates                |
-  +----------+-----------+------------------------------------------------+
-  |          |                  |                                                |
-  |          |           |                                               |
-  +----------+-----------+------------------------------------------------+
-*/
-
-#ifndef COMEDI_SUBD_TTLIO
-#define COMEDI_SUBD_TTLIO      11      /* Digital Input Output But TTL */
-#endif
-
 #define APCI3XXX_SINGLE                                0
 #define APCI3XXX_DIFF                          1
 #define APCI3XXX_CONFIGURATION                 0
 
-#define APCI3XXX_TTL_INIT_DIRECTION_PORT2      0
-
-static const struct comedi_lrange range_apci3XXX_ai = {
-       8, {
-               BIP_RANGE(10),
-               BIP_RANGE(5),
-               BIP_RANGE(2),
-               BIP_RANGE(1),
-               UNI_RANGE(10),
-               UNI_RANGE(5),
-               UNI_RANGE(2),
-               UNI_RANGE(1)
-       }
-};
-
-static const struct comedi_lrange range_apci3XXX_ao = {
-       2, {
-               BIP_RANGE(10),
-               UNI_RANGE(10)
-       }
-};
-
 /*
 +----------------------------------------------------------------------------+
 |                         ANALOG INPUT FUNCTIONS                             |
@@ -97,1280 +25,158 @@ static const struct comedi_lrange range_apci3XXX_ao = {
 */
 static int i_APCI3XXX_TestConversionStarted(struct comedi_device *dev)
 {
-       struct addi_private *devpriv = dev->private;
+       struct apci3xxx_private *devpriv = dev->private;
 
-       if ((readl(devpriv->dw_AiBase + 8) & 0x80000UL) == 0x80000UL)
+       if ((readl(devpriv->mmio + 8) & 0x80000) == 0x80000)
                return 1;
        else
                return 0;
 
 }
 
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_AnalogInputConfigOperatingMode        |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task           Converting mode and convert time selection                  |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_SingleDiff  = (unsigned char)  data[1];                       |
-|                     b_TimeBase    = (unsigned char)  data[2]; (0: ns, 1:micros 2:ms)|
-|                    dw_ReloadValue = (unsigned int) data[3];                       |
-|                     ........                                               |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0 : No error                                           |
-|                    -1 : Single/Diff selection error                        |
-|                    -2 : Convert time base unity selection error            |
-|                    -3 : Convert time value selection error                 |
-|                    -10: Any conversion started                             |
-|                    ....                                                    |
-|                    -100 : Config command error                             |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device *dev,
-                                                    struct comedi_subdevice *s,
-                                                    struct comedi_insn *insn,
-                                                    unsigned int *data)
-{
-       const struct addi_board *this_board = comedi_board(dev);
-       struct addi_private *devpriv = dev->private;
-       int i_ReturnValue = insn->n;
-       unsigned char b_TimeBase = 0;
-       unsigned char b_SingleDiff = 0;
-       unsigned int dw_ReloadValue = 0;
-       unsigned int dw_TestReloadValue = 0;
-
-       /************************/
-       /* Test the buffer size */
-       /************************/
-
-       if (insn->n == 4) {
-          /****************************/
-               /* Get the Singel/Diff flag */
-          /****************************/
-
-               b_SingleDiff = (unsigned char) data[1];
-
-          /****************************/
-               /* Get the time base unitiy */
-          /****************************/
-
-               b_TimeBase = (unsigned char) data[2];
-
-          /*************************************/
-               /* Get the convert time reload value */
-          /*************************************/
-
-               dw_ReloadValue = (unsigned int) data[3];
-
-          /**********************/
-               /* Test the time base */
-          /**********************/
-
-               if ((this_board->b_AvailableConvertUnit & (1 << b_TimeBase)) !=
-                       0) {
-             /*******************************/
-                       /* Test the convert time value */
-             /*******************************/
-
-                       if (dw_ReloadValue <= 65535) {
-                               dw_TestReloadValue = dw_ReloadValue;
-
-                               if (b_TimeBase == 1) {
-                                       dw_TestReloadValue =
-                                               dw_TestReloadValue * 1000UL;
-                               }
-                               if (b_TimeBase == 2) {
-                                       dw_TestReloadValue =
-                                               dw_TestReloadValue * 1000000UL;
-                               }
-
-                /*******************************/
-                               /* Test the convert time value */
-                /*******************************/
-
-                               if (dw_TestReloadValue >=
-                                       devpriv->s_EeParameters.
-                                       ui_MinAcquisitiontimeNs) {
-                                       if ((b_SingleDiff == APCI3XXX_SINGLE)
-                                               || (b_SingleDiff ==
-                                                       APCI3XXX_DIFF)) {
-                                               if (((b_SingleDiff == APCI3XXX_SINGLE)
-                                                       && (devpriv->s_EeParameters.i_NbrAiChannel == 0))
-                                                   || ((b_SingleDiff == APCI3XXX_DIFF)
-                                                       && (this_board->i_NbrAiChannelDiff == 0))
-                                                   ) {
-                          /*******************************/
-                                                       /* Single/Diff selection error */
-                          /*******************************/
-
-                                                       printk("Single/Diff selection error\n");
-                                                       i_ReturnValue = -1;
-                                               } else {
-                          /**********************************/
-                                                       /* Test if conversion not started */
-                          /**********************************/
-
-                                                       if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
-                                                               devpriv->
-                                                                       ui_EocEosConversionTime
-                                                                       =
-                                                                       (unsigned int)
-                                                                       dw_ReloadValue;
-                                                               devpriv->
-                                                                       b_EocEosConversionTimeBase
-                                                                       =
-                                                                       b_TimeBase;
-                                                               devpriv->
-                                                                       b_SingelDiff
-                                                                       =
-                                                                       b_SingleDiff;
-                                                               devpriv->
-                                                                       b_AiInitialisation
-                                                                       = 1;
-
-                             /*******************************/
-                                                               /* Set the convert timing unit */
-                             /*******************************/
-
-                                                               writel((unsigned int)b_TimeBase,
-                                                                       devpriv->dw_AiBase + 36);
-
-                             /**************************/
-                                                               /* Set the convert timing */
-                             /*************************/
-
-                                                               writel(dw_ReloadValue, devpriv->dw_AiBase + 32);
-                                                       } else {
-                             /**************************/
-                                                               /* Any conversion started */
-                             /**************************/
-
-                                                               printk("Any conversion started\n");
-                                                               i_ReturnValue =
-                                                                       -10;
-                                                       }
-                                               }
-                                       } else {
-                      /*******************************/
-                                               /* Single/Diff selection error */
-                      /*******************************/
-
-                                               printk("Single/Diff selection error\n");
-                                               i_ReturnValue = -1;
-                                       }
-                               } else {
-                   /************************/
-                                       /* Time selection error */
-                   /************************/
-
-                                       printk("Convert time value selection error\n");
-                                       i_ReturnValue = -3;
-                               }
-                       } else {
-                /************************/
-                               /* Time selection error */
-                /************************/
-
-                               printk("Convert time value selection error\n");
-                               i_ReturnValue = -3;
-                       }
-               } else {
-             /*****************************/
-                       /* Time base selection error */
-             /*****************************/
-
-                       printk("Convert time base unity selection error\n");
-                       i_ReturnValue = -2;
-               }
-       } else {
-          /*******************/
-               /* Data size error */
-          /*******************/
-
-               printk("Buffer size error\n");
-               i_ReturnValue = -101;
-       }
-
-       return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_InsnConfigAnalogInput                 |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task           Converting mode and convert time selection                  |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_ConvertMode = (unsigned char)  data[0];                       |
-|                     b_TimeBase    = (unsigned char)  data[1]; (0: ns, 1:micros 2:ms)|
-|                    dw_ReloadValue = (unsigned int) data[2];                       |
-|                     ........                                               |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0: No error                                            |
-|                    ....                                                    |
-|                    -100 : Config command error                             |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device *dev,
-                                           struct comedi_subdevice *s,
-                                           struct comedi_insn *insn,
-                                           unsigned int *data)
-{
-       int i_ReturnValue = insn->n;
-
-       /************************/
-       /* Test the buffer size */
-       /************************/
-
-       if (insn->n >= 1) {
-               switch ((unsigned char) data[0]) {
-               case APCI3XXX_CONFIGURATION:
-                       i_ReturnValue =
-                               i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
-                               s, insn, data);
-                       break;
-
-               default:
-                       i_ReturnValue = -100;
-                       printk("Config command error %d\n", data[0]);
-                       break;
-               }
-       } else {
-          /*******************/
-               /* Data size error */
-          /*******************/
-
-               printk("Buffer size error\n");
-               i_ReturnValue = -101;
-       }
-
-       return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_InsnReadAnalogInput                   |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task                Read 1 analog input                                    |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Range             = CR_RANGE(insn->chanspec);        |
-|                     b_Channel           = CR_CHAN(insn->chanspec);         |
-|                     dw_NbrOfAcquisition = insn->n;                         |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0: No error                                            |
-|                    -3 : Channel selection error                            |
-|                    -4 : Configuration selelection error                    |
-|                    -10: Any conversion started                             |
-|                    ....                                                    |
-|                    -100 : Config command error                             |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device *dev,
-                                         struct comedi_subdevice *s,
-                                         struct comedi_insn *insn,
-                                         unsigned int *data)
-{
-       const struct addi_board *this_board = comedi_board(dev);
-       struct addi_private *devpriv = dev->private;
-       int i_ReturnValue = insn->n;
-       unsigned char b_Configuration = (unsigned char) CR_RANGE(insn->chanspec);
-       unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
-       unsigned int dw_Temp = 0;
-       unsigned int dw_Configuration = 0;
-       unsigned int dw_AcquisitionCpt = 0;
-       unsigned char b_Interrupt = 0;
-
-       /*************************************/
-       /* Test if operating mode configured */
-       /*************************************/
-
-       if (devpriv->b_AiInitialisation) {
-          /***************************/
-               /* Test the channel number */
-          /***************************/
-
-               if (((b_Channel < devpriv->s_EeParameters.i_NbrAiChannel)
-                               && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
-                       || ((b_Channel < this_board->i_NbrAiChannelDiff)
-                               && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
-             /**********************************/
-                       /* Test the channel configuration */
-             /**********************************/
-
-                       if (b_Configuration > 7) {
-                /***************************/
-                               /* Channel not initialised */
-                /***************************/
-
-                               i_ReturnValue = -4;
-                               printk("Channel %d range %d selection error\n",
-                                       b_Channel, b_Configuration);
-                       }
-               } else {
-             /***************************/
-                       /* Channel selection error */
-             /***************************/
-
-                       i_ReturnValue = -3;
-                       printk("Channel %d selection error\n", b_Channel);
-               }
-
-          /**************************/
-               /* Test if no error occur */
-          /**************************/
-
-               if (i_ReturnValue >= 0) {
-             /************************/
-                       /* Test the buffer size */
-             /************************/
-
-                       if ((b_Interrupt != 0) || ((b_Interrupt == 0)
-                                       && (insn->n >= 1))) {
-                /**********************************/
-                               /* Test if conversion not started */
-                /**********************************/
-
-                               if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
-                   /******************/
-                                       /* Clear the FIFO */
-                   /******************/
-
-                                       writel(0x10000UL, devpriv->dw_AiBase + 12);
-
-                   /*******************************/
-                                       /* Get and save the delay mode */
-                   /*******************************/
-
-                                       dw_Temp = readl(devpriv->dw_AiBase + 4);
-                                       dw_Temp = dw_Temp & 0xFFFFFEF0UL;
-
-                   /***********************************/
-                                       /* Channel configuration selection */
-                   /***********************************/
-
-                                       writel(dw_Temp, devpriv->dw_AiBase + 4);
-
-                   /**************************/
-                                       /* Make the configuration */
-                   /**************************/
-
-                                       dw_Configuration =
-                                               (b_Configuration & 3) |
-                                               ((unsigned int) (b_Configuration >> 2)
-                                               << 6) | ((unsigned int) devpriv->
-                                               b_SingelDiff << 7);
-
-                   /***************************/
-                                       /* Write the configuration */
-                   /***************************/
-
-                                       writel(dw_Configuration,
-                                              devpriv->dw_AiBase + 0);
-
-                   /*********************/
-                                       /* Channel selection */
-                   /*********************/
-
-                                       writel(dw_Temp | 0x100UL,
-                                              devpriv->dw_AiBase + 4);
-                                       writel((unsigned int) b_Channel,
-                                              devpriv->dw_AiBase + 0);
-
-                   /***********************/
-                                       /* Restaure delay mode */
-                   /***********************/
-
-                                       writel(dw_Temp, devpriv->dw_AiBase + 4);
-
-                   /***********************************/
-                                       /* Set the number of sequence to 1 */
-                   /***********************************/
-
-                                       writel(1, devpriv->dw_AiBase + 48);
-
-                   /***************************/
-                                       /* Save the interrupt flag */
-                   /***************************/
-
-                                       devpriv->b_EocEosInterrupt =
-                                               b_Interrupt;
-
-                   /*******************************/
-                                       /* Save the number of channels */
-                   /*******************************/
-
-                                       devpriv->ui_AiNbrofChannels = 1;
-
-                   /******************************/
-                                       /* Test if interrupt not used */
-                   /******************************/
-
-                                       if (b_Interrupt == 0) {
-                                               for (dw_AcquisitionCpt = 0;
-                                                       dw_AcquisitionCpt <
-                                                       insn->n;
-                                                       dw_AcquisitionCpt++) {
-                         /************************/
-                                                       /* Start the conversion */
-                         /************************/
-
-                                                       writel(0x80000UL, devpriv->dw_AiBase + 8);
-
-                         /****************/
-                                                       /* Wait the EOS */
-                         /****************/
-
-                                                       do {
-                                                               dw_Temp = readl(devpriv->dw_AiBase + 20);
-                                                               dw_Temp = dw_Temp & 1;
-                                                       } while (dw_Temp != 1);
-
-                         /*************************/
-                                                       /* Read the analog value */
-                         /*************************/
-
-                                                       data[dw_AcquisitionCpt] = (unsigned int)readl(devpriv->dw_AiBase + 28);
-                                               }
-                                       } else {
-                      /************************/
-                                               /* Start the conversion */
-                      /************************/
-
-                                               writel(0x180000UL, devpriv->dw_AiBase + 8);
-                                       }
-                               } else {
-                   /**************************/
-                                       /* Any conversion started */
-                   /**************************/
-
-                                       printk("Any conversion started\n");
-                                       i_ReturnValue = -10;
-                               }
-                       } else {
-                /*******************/
-                               /* Data size error */
-                /*******************/
-
-                               printk("Buffer size error\n");
-                               i_ReturnValue = -101;
-                       }
-               }
-       } else {
-          /***************************/
-               /* Channel selection error */
-          /***************************/
-
-               printk("Operating mode not configured\n");
-               i_ReturnValue = -1;
-       }
-       return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function name     : void v_APCI3XXX_Interrupt (int            irq,         |
-|                                                void           *d)       |
-+----------------------------------------------------------------------------+
-| Task              :Interrupt handler for APCI3XXX                          |
-|                    When interrupt occurs this gets called.                 |
-|                    First it finds which interrupt has been generated and   |
-|                    handles  corresponding interrupt                        |
-+----------------------------------------------------------------------------+
-| Input Parameters  : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      : -                                                      |
-+----------------------------------------------------------------------------+
-*/
-
-static void v_APCI3XXX_Interrupt(int irq, void *d)
-{
-       struct comedi_device *dev = d;
-       struct addi_private *devpriv = dev->private;
-       unsigned char b_CopyCpt = 0;
-       unsigned int dw_Status = 0;
-
-       /***************************/
-       /* Test if interrupt occur */
-       /***************************/
-
-       dw_Status = readl(devpriv->dw_AiBase + 16);
-       if ( (dw_Status & 0x2UL) == 0x2UL) {
-          /***********************/
-               /* Reset the interrupt */
-          /***********************/
-
-               writel(dw_Status, devpriv->dw_AiBase + 16);
-
-          /*****************************/
-               /* Test if interrupt enabled */
-          /*****************************/
-
-               if (devpriv->b_EocEosInterrupt == 1) {
-             /********************************/
-                       /* Read all analog inputs value */
-             /********************************/
-
-                       for (b_CopyCpt = 0;
-                               b_CopyCpt < devpriv->ui_AiNbrofChannels;
-                               b_CopyCpt++) {
-                               devpriv->ui_AiReadData[b_CopyCpt] =
-                                       (unsigned int)readl(devpriv->dw_AiBase + 28);
-                       }
-
-             /**************************/
-                       /* Set the interrupt flag */
-             /**************************/
-
-                       devpriv->b_EocEosInterrupt = 2;
-
-             /**********************************************/
-                       /* Send a signal to from kernel to user space */
-             /**********************************************/
-
-                       send_sig(SIGIO, devpriv->tsk_Current, 0);
-               }
-       }
-}
-
-/*
-+----------------------------------------------------------------------------+
-|                            ANALOG OUTPUT SUBDEVICE                         |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_InsnWriteAnalogOutput                 |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task                Read 1 analog input                                    |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Range    = CR_RANGE(insn->chanspec);                 |
-|                     b_Channel  = CR_CHAN(insn->chanspec);                  |
-|                     data[0]    = analog value;                             |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0: No error                                            |
-|                    -3 : Channel selection error                            |
-|                    -4 : Configuration selelection error                    |
-|                    ....                                                    |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device *dev,
-                                           struct comedi_subdevice *s,
-                                           struct comedi_insn *insn,
-                                           unsigned int *data)
-{
-       struct addi_private *devpriv = dev->private;
-       unsigned char b_Range = (unsigned char) CR_RANGE(insn->chanspec);
-       unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
-       unsigned int dw_Status = 0;
-       int i_ReturnValue = insn->n;
-
-       /************************/
-       /* Test the buffer size */
-       /************************/
-
-       if (insn->n >= 1) {
-          /***************************/
-               /* Test the channel number */
-          /***************************/
-
-               if (b_Channel < devpriv->s_EeParameters.i_NbrAoChannel) {
-             /**********************************/
-                       /* Test the channel configuration */
-             /**********************************/
-
-                       if (b_Range < 2) {
-                /***************************/
-                               /* Set the range selection */
-                /***************************/
-
-                               writel(b_Range, devpriv->dw_AiBase + 96);
-
-                /**************************************************/
-                               /* Write the analog value to the selected channel */
-                /**************************************************/
-
-                               writel((data[0] << 8) | b_Channel,
-                                       devpriv->dw_AiBase + 100);
-
-                /****************************/
-                               /* Wait the end of transfer */
-                /****************************/
-
-                               do {
-                                       dw_Status = readl(devpriv->dw_AiBase + 96);
-                               } while ((dw_Status & 0x100) != 0x100);
-                       } else {
-                /***************************/
-                               /* Channel not initialised */
-                /***************************/
-
-                               i_ReturnValue = -4;
-                               printk("Channel %d range %d selection error\n",
-                                       b_Channel, b_Range);
-                       }
-               } else {
-             /***************************/
-                       /* Channel selection error */
-             /***************************/
-
-                       i_ReturnValue = -3;
-                       printk("Channel %d selection error\n", b_Channel);
-               }
-       } else {
-          /*******************/
-               /* Data size error */
-          /*******************/
-
-               printk("Buffer size error\n");
-               i_ReturnValue = -101;
-       }
-
-       return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-|                              TTL FUNCTIONS                                 |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int   i_APCI3XXX_InsnConfigInitTTLIO                   |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task           You must calling this function be                           |
-|                for you call any other function witch access of TTL.        |
-|                APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_InitType    = (unsigned char) data[0];                        |
-|                     b_Port2Mode   = (unsigned char) data[1];                        |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      :>0: No error                                            |
-|                    -1: Port 2 mode selection is wrong                      |
-|                    ....                                                    |
-|                    -100 : Config command error                             |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device *dev,
-                                         struct comedi_subdevice *s,
-                                         struct comedi_insn *insn,
-                                         unsigned int *data)
-{
-       struct addi_private *devpriv = dev->private;
-       int i_ReturnValue = insn->n;
-       unsigned char b_Command = 0;
-
-       /************************/
-       /* Test the buffer size */
-       /************************/
-
-       if (insn->n >= 1) {
-          /*******************/
-               /* Get the command */
-               /* **************** */
-
-               b_Command = (unsigned char) data[0];
-
-          /********************/
-               /* Test the command */
-          /********************/
-
-               if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
-             /***************************************/
-                       /* Test the initialisation buffer size */
-             /***************************************/
-
-                       if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
-                               && (insn->n != 2)) {
-                /*******************/
-                               /* Data size error */
-                /*******************/
-
-                               printk("Buffer size error\n");
-                               i_ReturnValue = -101;
-                       }
-               } else {
-             /************************/
-                       /* Config command error */
-             /************************/
-
-                       printk("Command selection error\n");
-                       i_ReturnValue = -100;
-               }
-       } else {
-          /*******************/
-               /* Data size error */
-          /*******************/
-
-               printk("Buffer size error\n");
-               i_ReturnValue = -101;
-       }
-
-       /*********************************************************************************/
-       /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
-       /*********************************************************************************/
-
-       if ((i_ReturnValue >= 0)
-               && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
-          /**********************/
-               /* Test the direction */
-          /**********************/
-
-               if ((data[1] == 0) || (data[1] == 0xFF)) {
-             /**************************/
-                       /* Save the configuration */
-             /**************************/
-
-                       devpriv->ul_TTLPortConfiguration[0] =
-                               devpriv->ul_TTLPortConfiguration[0] | data[1];
-               } else {
-             /************************/
-                       /* Port direction error */
-             /************************/
-
-                       printk("Port 2 direction selection error\n");
-                       i_ReturnValue = -1;
-               }
-       }
-
-       /**************************/
-       /* Test if no error occur */
-       /**************************/
-
-       if (i_ReturnValue >= 0) {
-          /***********************************/
-               /* Test if TTL port initilaisation */
-          /***********************************/
-
-               if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
-             /*************************/
-                       /* Set the configuration */
-             /*************************/
-
-                       outl(data[1], devpriv->iobase + 224);
-               }
-       }
-
-       return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-|                        TTL INPUT FUNCTIONS                                 |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int     i_APCI3XXX_InsnBitsTTLIO                       |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task              : Write the selected output mask and read the status from|
-|                     all TTL channles                                       |
-+----------------------------------------------------------------------------+
-| Input Parameters  : dw_ChannelMask = data [0];                             |
-|                     dw_BitMask     = data [1];                             |
-+----------------------------------------------------------------------------+
-| Output Parameters : data[1] : All TTL channles states                      |
-+----------------------------------------------------------------------------+
-| Return Value      : >0  : No error                                         |
-|                    -4   : Channel mask error                               |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device *dev,
-                                   struct comedi_subdevice *s,
-                                   struct comedi_insn *insn,
-                                   unsigned int *data)
+static int apci3xxx_ai_configure(struct comedi_device *dev,
+                                struct comedi_subdevice *s,
+                                struct comedi_insn *insn,
+                                unsigned int *data)
 {
-       struct addi_private *devpriv = dev->private;
-       int i_ReturnValue = insn->n;
-       unsigned char b_ChannelCpt = 0;
-       unsigned int dw_ChannelMask = 0;
-       unsigned int dw_BitMask = 0;
-       unsigned int dw_Status = 0;
-
-       /************************/
-       /* Test the buffer size */
-       /************************/
-
-       if (insn->n >= 2) {
-          /*******************************/
-               /* Get the channe and bit mask */
-          /*******************************/
-
-               dw_ChannelMask = data[0];
-               dw_BitMask = data[1];
-
-          /*************************/
-               /* Test the channel mask */
-          /*************************/
-
-               if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
-                       (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
-                               || (((devpriv->ul_TTLPortConfiguration[0] &
-                                                       0xFF) == 0)
-                                       && ((dw_ChannelMask & 0XFF0000) ==
-                                               0)))) {
-             /*********************************/
-                       /* Test if set/reset any channel */
-             /*********************************/
-
-                       if (dw_ChannelMask) {
-                /****************************************/
-                               /* Test if set/rest any port 0 channels */
-                /****************************************/
-
-                               if (dw_ChannelMask & 0xFF) {
-                   /*******************************************/
-                                       /* Read port 0 (first digital output port) */
-                   /*******************************************/
-
-                                       dw_Status = inl(devpriv->iobase + 80);
-
-                                       for (b_ChannelCpt = 0; b_ChannelCpt < 8;
-                                               b_ChannelCpt++) {
-                                               if ((dw_ChannelMask >>
-                                                               b_ChannelCpt) &
-                                                       1) {
-                                                       dw_Status =
-                                                               (dw_Status &
-                                                               (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
-                                               }
-                                       }
-
-                                       outl(dw_Status, devpriv->iobase + 80);
-                               }
-
-                /****************************************/
-                               /* Test if set/rest any port 2 channels */
-                /****************************************/
-
-                               if (dw_ChannelMask & 0xFF0000) {
-                                       dw_BitMask = dw_BitMask >> 16;
-                                       dw_ChannelMask = dw_ChannelMask >> 16;
-
-                   /********************************************/
-                                       /* Read port 2 (second digital output port) */
-                   /********************************************/
-
-                                       dw_Status = inl(devpriv->iobase + 112);
-
-                                       for (b_ChannelCpt = 0; b_ChannelCpt < 8;
-                                               b_ChannelCpt++) {
-                                               if ((dw_ChannelMask >>
-                                                               b_ChannelCpt) &
-                                                       1) {
-                                                       dw_Status =
-                                                               (dw_Status &
-                                                               (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
-                                               }
-                                       }
-
-                                       outl(dw_Status, devpriv->iobase + 112);
-                               }
-                       }
-
-             /*******************************************/
-                       /* Read port 0 (first digital output port) */
-             /*******************************************/
-
-                       data[1] = inl(devpriv->iobase + 80);
-
-             /******************************************/
-                       /* Read port 1 (first digital input port) */
-             /******************************************/
-
-                       data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
-
-             /************************/
-                       /* Test if port 2 input */
-             /************************/
-
-                       if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
-                               data[1] =
-                                       data[1] | (inl(devpriv->iobase +
-                                               96) << 16);
-                       } else {
-                               data[1] =
-                                       data[1] | (inl(devpriv->iobase +
-                                               112) << 16);
-                       }
-               } else {
-             /************************/
-                       /* Config command error */
-             /************************/
-
-                       printk("Channel mask error\n");
-                       i_ReturnValue = -4;
-               }
-       } else {
-          /*******************/
-               /* Data size error */
-          /*******************/
-
-               printk("Buffer size error\n");
-               i_ReturnValue = -101;
+       const struct apci3xxx_boardinfo *board = comedi_board(dev);
+       struct apci3xxx_private *devpriv = dev->private;
+       unsigned int aref_mode = data[1];
+       unsigned int time_base = data[2];
+       unsigned int reload_time = data[3];
+       unsigned int acq_ns;
+
+       if (aref_mode != 0 && aref_mode != 1)
+               return -EINVAL;
+
+       if (time_base > 2)
+               return -EINVAL;
+
+       if (reload_time > 0xffff)
+               return -EINVAL;
+
+       time_base = 1 << time_base;
+       if (!(board->ai_conv_units & time_base))
+               return -EINVAL;
+
+       switch (time_base) {
+       case CONV_UNIT_NS:
+               acq_ns = reload_time;
+       case CONV_UNIT_US:
+               acq_ns = reload_time * 1000;
+       case CONV_UNIT_MS:
+               acq_ns = reload_time * 1000000;
+       default:
+               return -EINVAL;
        }
 
-       return i_ReturnValue;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int i_APCI3XXX_InsnReadTTLIO                           |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task              : Read the status from selected channel                  |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
-+----------------------------------------------------------------------------+
-| Output Parameters : data[0] : Selected TTL channel state                   |
-+----------------------------------------------------------------------------+
-| Return Value      : 0   : No error                                         |
-|                    -3   : Channel selection error                          |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnReadTTLIO(struct comedi_device *dev,
-                                   struct comedi_subdevice *s,
-                                   struct comedi_insn *insn,
-                                   unsigned int *data)
-{
-       struct addi_private *devpriv = dev->private;
-       unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
-       int i_ReturnValue = insn->n;
-       unsigned int *pls_ReadData = data;
-
-       /************************/
-       /* Test the buffer size */
-       /************************/
-
-       if (insn->n >= 1) {
-          /***********************/
-               /* Test if read port 0 */
-          /***********************/
-
-               if (b_Channel < 8) {
-             /*******************************************/
-                       /* Read port 0 (first digital output port) */
-             /*******************************************/
-
-                       pls_ReadData[0] = inl(devpriv->iobase + 80);
-                       pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
-               } else {
-             /***********************/
-                       /* Test if read port 1 */
-             /***********************/
+       /* Test the convert time value */
+       if (acq_ns < board->ui_MinAcquisitiontimeNs)
+               return -EINVAL;
 
-                       if ((b_Channel > 7) && (b_Channel < 16)) {
-                /******************************************/
-                               /* Read port 1 (first digital input port) */
-                /******************************************/
+       /* Test if conversion not started */
+       if (i_APCI3XXX_TestConversionStarted(dev))
+               return -EBUSY;
 
-                               pls_ReadData[0] = inl(devpriv->iobase + 64);
-                               pls_ReadData[0] =
-                                       (pls_ReadData[0] >> (b_Channel -
-                                               8)) & 1;
-                       } else {
-                /***********************/
-                               /* Test if read port 2 */
-                /***********************/
+       devpriv->ui_EocEosConversionTime = reload_time;
+       devpriv->b_EocEosConversionTimeBase = time_base;
+       devpriv->b_SingelDiff = aref_mode;
 
-                               if ((b_Channel > 15) && (b_Channel < 24)) {
-                   /************************/
-                                       /* Test if port 2 input */
-                   /************************/
+       /* Set the convert timing unit */
+       writel(time_base, devpriv->mmio + 36);
 
-                                       if ((devpriv->ul_TTLPortConfiguration[0]
-                                                       & 0xFF) == 0) {
-                                               pls_ReadData[0] =
-                                                       inl(devpriv->iobase +
-                                                       96);
-                                               pls_ReadData[0] =
-                                                       (pls_ReadData[0] >>
-                                                       (b_Channel - 16)) & 1;
-                                       } else {
-                                               pls_ReadData[0] =
-                                                       inl(devpriv->iobase +
-                                                       112);
-                                               pls_ReadData[0] =
-                                                       (pls_ReadData[0] >>
-                                                       (b_Channel - 16)) & 1;
-                                       }
-                               } else {
-                   /***************************/
-                                       /* Channel selection error */
-                   /***************************/
+       /* Set the convert timing */
+       writel(reload_time, devpriv->mmio + 32);
 
-                                       i_ReturnValue = -3;
-                                       printk("Channel %d selection error\n",
-                                               b_Channel);
-                               }
-                       }
-               }
-       } else {
-          /*******************/
-               /* Data size error */
-          /*******************/
-
-               printk("Buffer size error\n");
-               i_ReturnValue = -101;
-       }
-
-       return i_ReturnValue;
+       return insn->n;
 }
 
-/*
-+----------------------------------------------------------------------------+
-|                        TTL OUTPUT FUNCTIONS                                |
-+----------------------------------------------------------------------------+
-*/
-
-/*
-+----------------------------------------------------------------------------+
-| Function Name     : int     i_APCI3XXX_InsnWriteTTLIO                      |
-|                          (struct comedi_device    *dev,                           |
-|                           struct comedi_subdevice *s,                             |
-|                           struct comedi_insn      *insn,                          |
-|                           unsigned int         *data)                          |
-+----------------------------------------------------------------------------+
-| Task              : Set the state from TTL output channel                  |
-+----------------------------------------------------------------------------+
-| Input Parameters  : b_Channel = CR_CHAN(insn->chanspec)                    |
-|                     b_State   = data [0]                                   |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      : 0   : No error                                         |
-|                    -3   : Channel selection error                          |
-|                    -101 : Data size error                                  |
-+----------------------------------------------------------------------------+
-*/
-static int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device *dev,
-                                    struct comedi_subdevice *s,
-                                    struct comedi_insn *insn,
-                                    unsigned int *data)
+static int apci3xxx_ai_insn_config(struct comedi_device *dev,
+                                  struct comedi_subdevice *s,
+                                  struct comedi_insn *insn,
+                                  unsigned int *data)
 {
-       struct addi_private *devpriv = dev->private;
-       int i_ReturnValue = insn->n;
-       unsigned char b_Channel = (unsigned char) CR_CHAN(insn->chanspec);
-       unsigned char b_State = 0;
-       unsigned int dw_Status = 0;
-
-       /************************/
-       /* Test the buffer size */
-       /************************/
-
-       if (insn->n >= 1) {
-               b_State = (unsigned char) data[0];
-
-          /***********************/
-               /* Test if read port 0 */
-          /***********************/
-
-               if (b_Channel < 8) {
-             /*****************************************************************************/
-                       /* Read port 0 (first digital output port) and set/reset the selected channel */
-             /*****************************************************************************/
-
-                       dw_Status = inl(devpriv->iobase + 80);
-                       dw_Status =
-                               (dw_Status & (0xFF -
-                                       (1 << b_Channel))) | ((b_State & 1) <<
-                               b_Channel);
-                       outl(dw_Status, devpriv->iobase + 80);
-               } else {
-             /***********************/
-                       /* Test if read port 2 */
-             /***********************/
-
-                       if ((b_Channel > 15) && (b_Channel < 24)) {
-                /*************************/
-                               /* Test if port 2 output */
-                /*************************/
-
-                               if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
-                                       == 0xFF) {
-                   /*****************************************************************************/
-                                       /* Read port 2 (first digital output port) and set/reset the selected channel */
-                   /*****************************************************************************/
-
-                                       dw_Status = inl(devpriv->iobase + 112);
-                                       dw_Status =
-                                               (dw_Status & (0xFF -
-                                                       (1 << (b_Channel -
-                                                                       16)))) |
-                                               ((b_State & 1) << (b_Channel -
-                                                       16));
-                                       outl(dw_Status, devpriv->iobase + 112);
-                               } else {
-                   /***************************/
-                                       /* Channel selection error */
-                   /***************************/
-
-                                       i_ReturnValue = -3;
-                                       printk("Channel %d selection error\n",
-                                               b_Channel);
-                               }
-                       } else {
-                /***************************/
-                               /* Channel selection error */
-                /***************************/
-
-                               i_ReturnValue = -3;
-                               printk("Channel %d selection error\n",
-                                       b_Channel);
-                       }
-               }
-       } else {
-          /*******************/
-               /* Data size error */
-          /*******************/
-
-               printk("Buffer size error\n");
-               i_ReturnValue = -101;
+       switch (data[0]) {
+       case APCI3XXX_CONFIGURATION:
+               if (insn->n == 4)
+                       return apci3xxx_ai_configure(dev, s, insn, data);
+               else
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
        }
-
-       return i_ReturnValue;
 }
 
-static int apci3xxx_di_insn_bits(struct comedi_device *dev,
+static int apci3xxx_ai_insn_read(struct comedi_device *dev,
                                 struct comedi_subdevice *s,
                                 struct comedi_insn *insn,
                                 unsigned int *data)
 {
-       struct addi_private *devpriv = dev->private;
-
-       data[1] = inl(devpriv->iobase + 32) & 0xf;
-
-       return insn->n;
-}
-
-static int apci3xxx_do_insn_bits(struct comedi_device *dev,
-                                struct comedi_subdevice *s,
-                                struct comedi_insn *insn,
-                                unsigned int *data)
-{
-       struct addi_private *devpriv = dev->private;
-       unsigned int mask = data[0];
-       unsigned int bits = data[1];
-
-       s->state = inl(devpriv->iobase + 48) & 0xf;
-       if (mask) {
-               s->state &= ~mask;
-               s->state |= (bits & mask);
+       struct apci3xxx_private *devpriv = dev->private;
+       unsigned int chan = CR_CHAN(insn->chanspec);
+       unsigned int range = CR_RANGE(insn->chanspec);
+       unsigned char use_interrupt = 0;        /* FIXME: use interrupts */
+       unsigned int delay_mode;
+       unsigned int val;
+       int i;
 
-               outl(s->state, devpriv->iobase + 48);
-       }
-
-       data[1] = s->state;
-
-       return insn->n;
-}
-
-/*
-+----------------------------------------------------------------------------+
-| Function   Name   : int i_APCI3XXX_Reset(struct comedi_device *dev)               |                                                         +----------------------------------------------------------------------------+
-| Task              :resets all the registers                                |
-+----------------------------------------------------------------------------+
-| Input Parameters  : struct comedi_device *dev                                     |
-+----------------------------------------------------------------------------+
-| Output Parameters : -                                                      |
-+----------------------------------------------------------------------------+
-| Return Value      : -                                                      |
-+----------------------------------------------------------------------------+
-*/
+       if (!use_interrupt && insn->n == 0)
+               return insn->n;
 
-static int i_APCI3XXX_Reset(struct comedi_device *dev)
-{
-       struct addi_private *devpriv = dev->private;
-       unsigned char b_Cpt = 0;
+       if (i_APCI3XXX_TestConversionStarted(dev))
+               return -EBUSY;
 
-       /*************************/
-       /* Disable the interrupt */
-       /*************************/
+       /* Clear the FIFO */
+       writel(0x10000, devpriv->mmio + 12);
 
-       disable_irq(dev->irq);
+       /* Get and save the delay mode */
+       delay_mode = readl(devpriv->mmio + 4);
+       delay_mode &= 0xfffffef0;
 
-       /****************************/
-       /* Reset the interrupt flag */
-       /****************************/
+       /* Channel configuration selection */
+       writel(delay_mode, devpriv->mmio + 4);
 
-       devpriv->b_EocEosInterrupt = 0;
+       /* Make the configuration */
+       val = (range & 3) | ((range >> 2) << 6) |
+             (devpriv->b_SingelDiff << 7);
+       writel(val, devpriv->mmio + 0);
 
-       /***************************/
-       /* Clear the start command */
-       /***************************/
+       /* Channel selection */
+       writel(delay_mode | 0x100, devpriv->mmio + 4);
+       writel(chan, devpriv->mmio + 0);
 
-       writel(0, devpriv->dw_AiBase + 8);
+       /* Restore delay mode */
+       writel(delay_mode, devpriv->mmio + 4);
 
-       /*****************************/
-       /* Reset the interrupt flags */
-       /*****************************/
+       /* Set the number of sequence to 1 */
+       writel(1, devpriv->mmio + 48);
 
-       writel(readl(devpriv->dw_AiBase + 16), devpriv->dw_AiBase + 16);
+       /* Save the interrupt flag */
+       devpriv->b_EocEosInterrupt = use_interrupt;
 
-       /*****************/
-       /* clear the EOS */
-       /*****************/
+       /* Save the number of channels */
+       devpriv->ui_AiNbrofChannels = 1;
 
-       readl(devpriv->dw_AiBase + 20);
+       /* Test if interrupt not used */
+       if (!use_interrupt) {
+               for (i = 0; i < insn->n; i++) {
+                       /* Start the conversion */
+                       writel(0x80000, devpriv->mmio + 8);
 
-       /******************/
-       /* Clear the FIFO */
-       /******************/
+                       /* Wait the EOS */
+                       do {
+                               val = readl(devpriv->mmio + 20);
+                               val &= 0x1;
+                       } while (!val);
 
-       for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
-               readl(devpriv->dw_AiBase + 28);
+                       /* Read the analog value */
+                       data[i] = readl(devpriv->mmio + 28);
+               }
+       } else {
+               /* Start the conversion */
+               writel(0x180000, devpriv->mmio + 8);
        }
 
-       /************************/
-       /* Enable the interrupt */
-       /************************/
-
-       enable_irq(dev->irq);
-
-       return 0;
+       return insn->n;
 }