]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
Merge branch 'omap-pool'
[linux-2.6-omap-h63xx.git] / drivers / staging / comedi / drivers / addi-data / APCI1710_Inp_cpt.c
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
new file mode 100644 (file)
index 0000000..3ac6a26
--- /dev/null
@@ -0,0 +1,861 @@
+/**
+@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 shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+  +-----------------------------------------------------------------------+
+  | (C) ADDI-DATA GmbH          Dieselstraße 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     : API APCI1710    | Compiler : gcc                        |
+  | Module name : Inp_CPT.C       | Version  : 2.96                       |
+  +-------------------------------+---------------------------------------+
+  | Project manager: Eric Stolz   | Date     :  02/12/2002                |
+  +-----------------------------------------------------------------------+
+  | Description :   APCI-1710 pulse encoder module                        |
+  |                                                                       |
+  |                                                                       |
+  +-----------------------------------------------------------------------+
+  |                             UPDATES                                   |
+  +-----------------------------------------------------------------------+
+  |   Date   |   Author  |          Description of updates                |
+  +----------+-----------+------------------------------------------------+
+  |          |           |                                                |
+  |----------|-----------|------------------------------------------------|
+  | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
+  |          |           |   available                                    |
+  +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+|                               Included files                               |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Inp_cpt.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_InitPulseEncoder                      |
+|                               (BYTE_          b_BoardHandle,               |
+|                                BYTE_          b_ModulNbr,                  |
+|                                BYTE_          b_PulseEncoderNbr,           |
+|                                BYTE_          b_InputLevelSelection,       |
+|                                BYTE_          b_TriggerOutputAction,       |
+|                                ULONG_        ul_StartValue)                |
++----------------------------------------------------------------------------+
+| Task              : Configure the pulse encoder operating mode selected via|
+|                     b_ModulNbr and b_PulseEncoderNbr. The pulse encoder    |
+|                     after each pulse decrement the counter value from 1.   |
+|                                                                            |
+|                     You must calling this function be for you call any     |
+|                     other function witch access of pulse encoders.         |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_ b_BoardHandle         : Handle of board APCI-1710|
+|                     BYTE_ b_ModulNbr            : Module number to         |
+|                                                   configure (0 to 3)       |
+|                     BYTE_ b_PulseEncoderNbr     : Pulse encoder selection  |
+|                                                   (0 to 3)                 |
+|                     BYTE_ b_InputLevelSelection : Input level selection    |
+|                                                   (0 or 1)                 |
+|                                                       0 : Set pulse encoder|
+|                                                           count the the low|
+|                                                           level pulse.     |
+|                                                       1 : Set pulse encoder|
+|                                                           count the the    |
+|                                                           high level pulse.|
+|                     BYTE_ b_TriggerOutputAction : Digital TRIGGER output   |
+|                                                   action                   |
+|                                                       0 : No action        |
+|                                                       1 : Set the trigger  |
+|                                                           output to "1"    |
+|                                                           (high) after the |
+|                                                           passage from 1 to|
+|                                                           0 from pulse     |
+|                                                           encoder.         |
+|                                                       2 : Set the trigger  |
+|                                                           output to "0"    |
+|                                                           (low) after the  |
+|                                                           passage from 1 to|
+|                                                           0 from pulse     |
+|                                                           encoder          |
+|                     ULONG_ ul_StartValue        : Pulse encoder start value|
+|                                                   (1 to 4294967295)
+       b_ModulNbr                              =(BYTE) CR_AREF(insn->chanspec);
+       b_PulseEncoderNbr               =(BYTE) data[0];
+       b_InputLevelSelection   =(BYTE) data[1];
+       b_TriggerOutputAction   =(BYTE) data[2];
+       ul_StartValue                   =(ULONG) data[3];
+       |
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      : 0: No error                                            |
+|                    -1: The handle parameter of the board is wrong          |
+|                    -2: The module is not a pulse encoder module            |
+|                    -3: Pulse encoder selection is wrong                    |
+|                    -4: Input level selection is wrong                      |
+|                    -5: Digital TRIGGER output action selection is wrong    |
+|                    -6: Pulse encoder start value is wrong                  |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device * dev,
+       struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+       INT i_ReturnValue = 0;
+       DWORD dw_IntRegister;
+
+       BYTE b_ModulNbr;
+       BYTE b_PulseEncoderNbr;
+       BYTE b_InputLevelSelection;
+       BYTE b_TriggerOutputAction;
+       ULONG ul_StartValue;
+
+       b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+       b_PulseEncoderNbr = (BYTE) data[0];
+       b_InputLevelSelection = (BYTE) data[1];
+       b_TriggerOutputAction = (BYTE) data[2];
+       ul_StartValue = (ULONG) data[3];
+
+       i_ReturnValue = insn->n;
+
+       /***********************************/
+       /* Test the selected module number */
+       /***********************************/
+
+       if (b_ModulNbr <= 3) {
+          /*************************/
+               /* Test if pulse encoder */
+          /*************************/
+
+               if ((devpriv->s_BoardInfos.
+                               dw_MolduleConfiguration[b_ModulNbr] &
+                               APCI1710_PULSE_ENCODER) ==
+                       APCI1710_PULSE_ENCODER) {
+             /******************************************/
+                       /* Test the selected pulse encoder number */
+             /******************************************/
+
+                       if (b_PulseEncoderNbr <= 3) {
+                /************************/
+                               /* Test the input level */
+                /************************/
+
+                               if ((b_InputLevelSelection == 0)
+                                       || (b_InputLevelSelection == 1)) {
+                   /*******************************************/
+                                       /* Test the ouput TRIGGER action selection */
+                   /*******************************************/
+
+                                       if ((b_TriggerOutputAction <= 2)
+                                               || (b_PulseEncoderNbr > 0)) {
+                                               if (ul_StartValue > 1) {
+
+                                                       dw_IntRegister =
+                                                               inl(devpriv->
+                                                               s_BoardInfos.
+                                                               ui_Address +
+                                                               20 +
+                                                               (64 * b_ModulNbr));
+
+                         /***********************/
+                                                       /* Set the start value */
+                         /***********************/
+
+                                                       outl(ul_StartValue,
+                                                               devpriv->
+                                                               s_BoardInfos.
+                                                               ui_Address +
+                                                               (b_PulseEncoderNbr
+                                                                       * 4) +
+                                                               (64 * b_ModulNbr));
+
+                         /***********************/
+                                                       /* Set the input level */
+                         /***********************/
+                                                       devpriv->
+                                                               s_ModuleInfo
+                                                               [b_ModulNbr].
+                                                               s_PulseEncoderModuleInfo.
+                                                               dw_SetRegister =
+                                                               (devpriv->
+                                                               s_ModuleInfo
+                                                               [b_ModulNbr].
+                                                               s_PulseEncoderModuleInfo.
+                                                               dw_SetRegister &
+                                                               (0xFFFFFFFFUL -
+                                                                       (1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));
+
+                         /*******************************/
+                                                       /* Test if output trigger used */
+                         /*******************************/
+
+                                                       if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) {
+                            /****************************/
+                                                               /* Enable the output action */
+                            /****************************/
+
+                                                               devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       =
+                                                                       devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       | (1UL
+                                                                       << (4 + b_PulseEncoderNbr));
+
+                            /*********************************/
+                                                               /* Set the output TRIGGER action */
+                            /*********************************/
+
+                                                               devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       =
+                                                                       (devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       &
+                                                                       (0xFFFFFFFFUL
+                                                                               -
+                                                                               (1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));
+                                                       } else {
+                            /*****************************/
+                                                               /* Disable the output action */
+                            /*****************************/
+
+                                                               devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       =
+                                                                       devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       &
+                                                                       (0xFFFFFFFFUL
+                                                                       -
+                                                                       (1UL << (4 + b_PulseEncoderNbr)));
+                                                       }
+
+                         /*************************/
+                                                       /* Set the configuration */
+                         /*************************/
+
+                                                       outl(devpriv->
+                                                               s_ModuleInfo
+                                                               [b_ModulNbr].
+                                                               s_PulseEncoderModuleInfo.
+                                                               dw_SetRegister,
+                                                               devpriv->
+                                                               s_BoardInfos.
+                                                               ui_Address +
+                                                               20 +
+                                                               (64 * b_ModulNbr));
+
+                                                       devpriv->
+                                                               s_ModuleInfo
+                                                               [b_ModulNbr].
+                                                               s_PulseEncoderModuleInfo.
+                                                               s_PulseEncoderInfo
+                                                               [b_PulseEncoderNbr].
+                                                               b_PulseEncoderInit
+                                                               = 1;
+                                               } else {
+                         /**************************************/
+                                                       /* Pulse encoder start value is wrong */
+                         /**************************************/
+
+                                                       DPRINTK("Pulse encoder start value is wrong\n");
+                                                       i_ReturnValue = -6;
+                                               }
+                                       } else {
+                      /****************************************************/
+                                               /* Digital TRIGGER output action selection is wrong */
+                      /****************************************************/
+
+                                               DPRINTK("Digital TRIGGER output action selection is wrong\n");
+                                               i_ReturnValue = -5;
+                                       }
+                               } else {
+                   /**********************************/
+                                       /* Input level selection is wrong */
+                   /**********************************/
+
+                                       DPRINTK("Input level selection is wrong\n");
+                                       i_ReturnValue = -4;
+                               }
+                       } else {
+                /************************************/
+                               /* Pulse encoder selection is wrong */
+                /************************************/
+
+                               DPRINTK("Pulse encoder selection is wrong\n");
+                               i_ReturnValue = -3;
+                       }
+               } else {
+             /********************************************/
+                       /* The module is not a pulse encoder module */
+             /********************************************/
+
+                       DPRINTK("The module is not a pulse encoder module\n");
+                       i_ReturnValue = -2;
+               }
+       } else {
+          /********************************************/
+               /* The module is not a pulse encoder module */
+          /********************************************/
+
+               DPRINTK("The module is not a pulse encoder module\n");
+               i_ReturnValue = -2;
+       }
+
+       return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_EnablePulseEncoder                    |
+|                                       (BYTE_  b_BoardHandle,               |
+|                                        BYTE_  b_ModulNbr,                  |
+|                                        BYTE_  b_PulseEncoderNbr,           |
+|                                        BYTE_  b_CycleSelection,            |
+|                                        BYTE_  b_InterruptHandling)         |
++----------------------------------------------------------------------------+
+| Task              : Enableor disable  the selected pulse encoder (b_PulseEncoderNbr)  |
+|                     from selected module (b_ModulNbr). Each input pulse    |
+|                     decrement the pulse encoder counter value from 1.      |
+|                     If you enabled the interrupt (b_InterruptHandling), a  |
+|                     interrupt is generated when the pulse encoder has run  |
+|                     down.                                                  |
++----------------------------------------------------------------------------+
+| Input Parameters  : BYTE_   b_BoardHandle       : Handle of board APCI-1710|
+|                     BYTE_   b_ModulNbr          : Module number to         |
+|                                                   configure (0 to 3)       |
+|                     BYTE_   b_PulseEncoderNbr   : Pulse encoder selection  |
+|                                                   (0 to 3)                 |
+|                     BYTE_   b_CycleSelection    : APCI1710_CONTINUOUS:     |
+|                                                       Each time the        |
+|                                                       counting value is set|
+|                                                       on "0", the pulse    |
+|                                                       encoder load the     |
+|                                                       start value after    |
+|                                                       the next pulse.      |
+|                                                   APCI1710_SINGLE:         |
+|                                                       If the counter is set|
+|                                                       on "0", the pulse    |
+|                                                       encoder is stopped.  |
+|                     BYTE_   b_InterruptHandling : Interrupts can be        |
+|                                                   generated, when the pulse|
+|                                                   encoder has run down.    |
+|                                                   With this parameter the  |
+|                                                   user decides if          |
+|                                                   interrupts are used or   |
+|                                                   not.                     |
+|                                                     APCI1710_ENABLE:       |
+|                                                     Interrupts are enabled |
+|                                                     APCI1710_DISABLE:      |
+|                                                     Interrupts are disabled
+
+       b_ModulNbr                      =(BYTE) CR_AREF(insn->chanspec);
+       b_Action                        =(BYTE) data[0];
+       b_PulseEncoderNbr       =(BYTE) data[1];
+       b_CycleSelection        =(BYTE) data[2];
+       b_InterruptHandling     =(BYTE) data[3];|
++----------------------------------------------------------------------------+
+| Output Parameters : -                                                      |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection is wrong                          |
+|                     -3: Pulse encoder selection is wrong                   |
+|                     -4: Pulse encoder not initialised.                     |
+|                         See function "i_APCI1710_InitPulseEncoder"         |
+|                     -5: Cycle selection mode is wrong                      |
+|                     -6: Interrupt handling mode is wrong                   |
+|                     -7: Interrupt routine not installed.                   |
+|                         See function "i_APCI1710_SetBoardIntRoutineX"      |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device * dev,
+       struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+       INT i_ReturnValue = 0;
+       BYTE b_ModulNbr;
+       BYTE b_PulseEncoderNbr;
+       BYTE b_CycleSelection;
+       BYTE b_InterruptHandling;
+       BYTE b_Action;
+
+       i_ReturnValue = insn->n;
+       b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+       b_Action = (BYTE) data[0];
+       b_PulseEncoderNbr = (BYTE) data[1];
+       b_CycleSelection = (BYTE) data[2];
+       b_InterruptHandling = (BYTE) data[3];
+
+       /***********************************/
+       /* Test the selected module number */
+       /***********************************/
+
+       if (b_ModulNbr <= 3) {
+          /******************************************/
+               /* Test the selected pulse encoder number */
+          /******************************************/
+
+               if (b_PulseEncoderNbr <= 3) {
+             /*************************************/
+                       /* Test if pulse encoder initialised */
+             /*************************************/
+
+                       if (devpriv->s_ModuleInfo[b_ModulNbr].
+                               s_PulseEncoderModuleInfo.
+                               s_PulseEncoderInfo[b_PulseEncoderNbr].
+                               b_PulseEncoderInit == 1) {
+                               switch (b_Action) {
+
+                               case APCI1710_ENABLE:
+                /****************************/
+                                       /* Test the cycle selection */
+                /****************************/
+
+                                       if (b_CycleSelection ==
+                                               APCI1710_CONTINUOUS
+                                               || b_CycleSelection ==
+                                               APCI1710_SINGLE) {
+                   /*******************************/
+                                               /* Test the interrupt handling */
+                   /*******************************/
+
+                                               if (b_InterruptHandling ==
+                                                       APCI1710_ENABLE
+                                                       || b_InterruptHandling
+                                                       == APCI1710_DISABLE) {
+                      /******************************/
+                                                       /* Test if interrupt not used */
+                      /******************************/
+
+                                                       if (b_InterruptHandling
+                                                               ==
+                                                               APCI1710_DISABLE)
+                                                       {
+                         /*************************/
+                                                               /* Disable the interrupt */
+                         /*************************/
+
+                                                               devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       =
+                                                                       devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       &
+                                                                       (0xFFFFFFFFUL
+                                                                       -
+                                                                       (1UL << b_PulseEncoderNbr));
+                                                       } else {
+
+                            /************************/
+                                                               /* Enable the interrupt */
+                            /************************/
+
+                                                               devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       =
+                                                                       devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister
+                                                                       | (1UL
+                                                                       <<
+                                                                       b_PulseEncoderNbr);
+                                                               devpriv->tsk_Current = current; // Save the current process task structure
+
+                                                       }
+
+                                                       if (i_ReturnValue >= 0) {
+                         /***********************************/
+                                                               /* Enable or disable the interrupt */
+                         /***********************************/
+
+                                                               outl(devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_SetRegister,
+                                                                       devpriv->
+                                                                       s_BoardInfos.
+                                                                       ui_Address
+                                                                       + 20 +
+                                                                       (64 * b_ModulNbr));
+
+                         /****************************/
+                                                               /* Enable the pulse encoder */
+                         /****************************/
+                                                               devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_ControlRegister
+                                                                       =
+                                                                       devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_ControlRegister
+                                                                       | (1UL
+                                                                       <<
+                                                                       b_PulseEncoderNbr);
+
+                         /**********************/
+                                                               /* Set the cycle mode */
+                         /**********************/
+
+                                                               devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_ControlRegister
+                                                                       =
+                                                                       (devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_ControlRegister
+                                                                       &
+                                                                       (0xFFFFFFFFUL
+                                                                               -
+                                                                               (1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));
+
+                         /****************************/
+                                                               /* Enable the pulse encoder */
+                         /****************************/
+
+                                                               outl(devpriv->
+                                                                       s_ModuleInfo
+                                                                       [b_ModulNbr].
+                                                                       s_PulseEncoderModuleInfo.
+                                                                       dw_ControlRegister,
+                                                                       devpriv->
+                                                                       s_BoardInfos.
+                                                                       ui_Address
+                                                                       + 16 +
+                                                                       (64 * b_ModulNbr));
+                                                       }
+                                               } else {
+                      /************************************/
+                                                       /* Interrupt handling mode is wrong */
+                      /************************************/
+
+                                                       DPRINTK("Interrupt handling mode is wrong\n");
+                                                       i_ReturnValue = -6;
+                                               }
+                                       } else {
+                   /*********************************/
+                                               /* Cycle selection mode is wrong */
+                   /*********************************/
+
+                                               DPRINTK("Cycle selection mode is wrong\n");
+                                               i_ReturnValue = -5;
+                                       }
+                                       break;
+
+                               case APCI1710_DISABLE:
+                                       devpriv->s_ModuleInfo[b_ModulNbr].
+                                               s_PulseEncoderModuleInfo.
+                                               dw_ControlRegister =
+                                               devpriv->
+                                               s_ModuleInfo[b_ModulNbr].
+                                               s_PulseEncoderModuleInfo.
+                                               dw_ControlRegister &
+                                               (0xFFFFFFFFUL -
+                                               (1UL << b_PulseEncoderNbr));
+
+                /*****************************/
+                                       /* Disable the pulse encoder */
+                /*****************************/
+
+                                       outl(devpriv->s_ModuleInfo[b_ModulNbr].
+                                               s_PulseEncoderModuleInfo.
+                                               dw_ControlRegister,
+                                               devpriv->s_BoardInfos.
+                                               ui_Address + 16 +
+                                               (64 * b_ModulNbr));
+
+                                       break;
+                               }       // switch End
+
+                       } else {
+                /*********************************/
+                               /* Pulse encoder not initialised */
+                /*********************************/
+
+                               DPRINTK("Pulse encoder not initialised\n");
+                               i_ReturnValue = -4;
+                       }
+               } else {
+             /************************************/
+                       /* Pulse encoder selection is wrong */
+             /************************************/
+
+                       DPRINTK("Pulse encoder selection is wrong\n");
+                       i_ReturnValue = -3;
+               }
+       } else {
+          /*****************************/
+               /* Module selection is wrong */
+          /*****************************/
+
+               DPRINTK("Module selection is wrong\n");
+               i_ReturnValue = -2;
+       }
+
+       return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name     : _INT_ i_APCI1710_ReadPulseEncoderStatus                |
+|                                       (BYTE_  b_BoardHandle,               |
+|                                        BYTE_  b_ModulNbr,                  |
+|                                        BYTE_  b_PulseEncoderNbr,           |
+|                                        PBYTE_ pb_Status)                   |
++----------------------------------------------------------------------------+
+| Task    APCI1710_PULSEENCODER_READ          : Reads the pulse encoder status
+                                                                                       and valuefrom selected pulse     |
+|                     encoder (b_PulseEncoderNbr) from selected module       |
+|                     (b_ModulNbr).                                          |
++----------------------------------------------------------------------------+
+       BYTE   b_Type; data[0]
+   APCI1710_PULSEENCODER_WRITE
+ Writes a 32-bit value (ul_WriteValue) into the selected|
+|                     pulse encoder (b_PulseEncoderNbr) from selected module |
+|                     (b_ModulNbr). This operation set the new start pulse   |
+|                     encoder value.
+ APCI1710_PULSEENCODER_READ
+| Input Parameters  : BYTE_   b_BoardHandle       : Handle of board APCI-1710|
+|            CRAREF()         BYTE_   b_ModulNbr          : Module number to         |
+|                                                   configure (0 to 3)       |
+|              data[1]       BYTE_   b_PulseEncoderNbr   : Pulse encoder selection  |
+|                                                   (0 to 3)
+   APCI1710_PULSEENCODER_WRITE
+                               data[2]         ULONG_ ul_WriteValue        : 32-bit value to be       |
+|                                                   written             |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_Status            : Pulse encoder status.    |
+|                                                       0 : No overflow occur|
+|                                                       1 : Overflow occur
+                                               PULONG_ pul_ReadValue       : Pulse encoder value      |  |
++----------------------------------------------------------------------------+
+| Return Value      :  0: No error                                           |
+|                     -1: The handle parameter of the board is wrong         |
+|                     -2: Module selection is wrong                          |
+|                     -3: Pulse encoder selection is wrong                   |
+|                     -4: Pulse encoder not initialised.                     |
+|                         See function "i_APCI1710_InitPulseEncoder"         |
++----------------------------------------------------------------------------+
+*/
+
+/*_INT_   i_APCI1710_ReadPulseEncoderStatus       (BYTE_   b_BoardHandle,
+                                                BYTE_   b_ModulNbr,
+                                                BYTE_   b_PulseEncoderNbr,
+
+                                                PBYTE_ pb_Status)
+                                                */
+INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device * dev,
+       struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+       INT i_ReturnValue = 0;
+       DWORD dw_StatusRegister;
+       BYTE b_ModulNbr;
+       BYTE b_PulseEncoderNbr;
+       PBYTE pb_Status;
+       BYTE b_Type;
+       PULONG pul_ReadValue;
+       ULONG ul_WriteValue;
+
+       i_ReturnValue = insn->n;
+       b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+       b_Type = (BYTE) data[0];
+       b_PulseEncoderNbr = (BYTE) data[1];
+       pb_Status = (PBYTE) & data[0];
+       pul_ReadValue = (PULONG) & data[1];
+
+       /***********************************/
+       /* Test the selected module number */
+       /***********************************/
+
+       if (b_ModulNbr <= 3) {
+          /******************************************/
+               /* Test the selected pulse encoder number */
+          /******************************************/
+
+               if (b_PulseEncoderNbr <= 3) {
+             /*************************************/
+                       /* Test if pulse encoder initialised */
+             /*************************************/
+
+                       if (devpriv->s_ModuleInfo[b_ModulNbr].
+                               s_PulseEncoderModuleInfo.
+                               s_PulseEncoderInfo[b_PulseEncoderNbr].
+                               b_PulseEncoderInit == 1) {
+
+                               switch (b_Type) {
+                               case APCI1710_PULSEENCODER_READ:
+                /****************************/
+                                       /* Read the status register */
+                /****************************/
+
+                                       dw_StatusRegister =
+                                               inl(devpriv->s_BoardInfos.
+                                               ui_Address + 16 +
+                                               (64 * b_ModulNbr));
+
+                                       devpriv->s_ModuleInfo[b_ModulNbr].
+                                               s_PulseEncoderModuleInfo.
+                                               dw_StatusRegister = devpriv->
+                                               s_ModuleInfo[b_ModulNbr].
+                                               s_PulseEncoderModuleInfo.
+                                               dw_StatusRegister |
+                                               dw_StatusRegister;
+
+                                       *pb_Status =
+                                               (BYTE) (devpriv->
+                                               s_ModuleInfo[b_ModulNbr].
+                                               s_PulseEncoderModuleInfo.
+                                               dw_StatusRegister >> (1 +
+                                                       b_PulseEncoderNbr)) & 1;
+
+                                       devpriv->s_ModuleInfo[b_ModulNbr].
+                                               s_PulseEncoderModuleInfo.
+                                               dw_StatusRegister =
+                                               devpriv->
+                                               s_ModuleInfo[b_ModulNbr].
+                                               s_PulseEncoderModuleInfo.
+                                               dw_StatusRegister &
+                                               (0xFFFFFFFFUL - (1 << (1 +
+                                                               b_PulseEncoderNbr)));
+
+                /******************/
+                                       /* Read the value */
+                /******************/
+
+                                       *pul_ReadValue =
+                                               inl(devpriv->s_BoardInfos.
+                                               ui_Address +
+                                               (4 * b_PulseEncoderNbr) +
+                                               (64 * b_ModulNbr));
+                                       break;
+
+                               case APCI1710_PULSEENCODER_WRITE:
+                                       ul_WriteValue = (ULONG) data[2];
+                       /*******************/
+                                       /* Write the value */
+                       /*******************/
+
+                                       outl(ul_WriteValue,
+                                               devpriv->s_BoardInfos.
+                                               ui_Address +
+                                               (4 * b_PulseEncoderNbr) +
+                                               (64 * b_ModulNbr));
+
+                               }       //end of switch
+                       } else {
+                /*********************************/
+                               /* Pulse encoder not initialised */
+                /*********************************/
+
+                               DPRINTK("Pulse encoder not initialised\n");
+                               i_ReturnValue = -4;
+                       }
+               } else {
+             /************************************/
+                       /* Pulse encoder selection is wrong */
+             /************************************/
+
+                       DPRINTK("Pulse encoder selection is wrong\n");
+                       i_ReturnValue = -3;
+               }
+       } else {
+          /*****************************/
+               /* Module selection is wrong */
+          /*****************************/
+
+               DPRINTK("Module selection is wrong\n");
+               i_ReturnValue = -2;
+       }
+
+       return (i_ReturnValue);
+}
+
+INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device * dev,
+       struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+       data[0] = devpriv->s_InterruptParameters.
+               s_FIFOInterruptParameters[devpriv->
+               s_InterruptParameters.ui_Read].b_OldModuleMask;
+       data[1] = devpriv->s_InterruptParameters.
+               s_FIFOInterruptParameters[devpriv->
+               s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+       data[2] = devpriv->s_InterruptParameters.
+               s_FIFOInterruptParameters[devpriv->
+               s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+       /***************************/
+       /* Increment the read FIFO */
+       /***************************/
+
+       devpriv->s_InterruptParameters.
+               ui_Read = (devpriv->
+               s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+       return insn->n;
+
+}