]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
staging: comedi: hwdrv_apci3200: remove forward declarations
[karo-tx-linux.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci3200.c
1 /**
2 @verbatim
3
4 Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
5
6         ADDI-DATA GmbH
7         Dieselstrasse 3
8         D-77833 Ottersweier
9         Tel: +19(0)7223/9493-0
10         Fax: +49(0)7223/9493-92
11         http://www.addi-data.com
12         info@addi-data.com
13
14 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.
15
16 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.
17
18 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
19
20 You should also find the complete GPL in the COPYING file accompanying this source code.
21
22 @endverbatim
23 */
24 /*
25
26   +-----------------------------------------------------------------------+
27   | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
28   +-----------------------------------------------------------------------+
29   | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
30   | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
31   +-------------------------------+---------------------------------------+
32   | Project     : APCI-3200       | Compiler   : GCC                      |
33   | Module name : hwdrv_apci3200.c| Version    : 2.96                     |
34   +-------------------------------+---------------------------------------+
35   | Project manager: Eric Stolz   | Date       :  02/12/2002              |
36   +-------------------------------+---------------------------------------+
37   | Description :   Hardware Layer Access For APCI-3200                   |
38   +-----------------------------------------------------------------------+
39   |                             UPDATES                                   |
40   +----------+-----------+------------------------------------------------+
41   |   Date   |   Author  |          Description of updates                |
42   +----------+-----------+------------------------------------------------+
43   | 02.07.04 | J. Krauth | Modification from the driver in order to       |
44   |          |           | correct some errors when using several boards. |
45   |          |           |                                                |
46   |          |           |                                                |
47   +----------+-----------+------------------------------------------------+
48   | 26.10.04 | J. Krauth | - Update for COMEDI 0.7.68                     |
49   |          |           | - Read eeprom value                            |
50   |          |           | - Append APCI-3300                             |
51   +----------+-----------+------------------------------------------------+
52 */
53
54 /*
55   +----------------------------------------------------------------------------+
56   |                               Included files                               |
57   +----------------------------------------------------------------------------+
58 */
59 #include "hwdrv_apci3200.h"
60
61 /* #define PRINT_INFO */
62
63 /* BEGIN JK 06.07.04: Management of sevrals boards */
64 /*
65   int i_CJCAvailable=1;
66   int i_CJCPolarity=0;
67   int i_CJCGain=2;/* changed from 0 to 2 */
68   int i_InterruptFlag=0;
69   int i_ADDIDATAPolarity;
70   int i_ADDIDATAGain;
71   int i_AutoCalibration=0;   /* : auto calibration */
72   int i_ADDIDATAConversionTime;
73   int i_ADDIDATAConversionTimeUnit;
74   int i_ADDIDATAType;
75   int i_ChannelNo;
76   int i_ChannelCount=0;
77   int i_ScanType;
78   int i_FirstChannel;
79   int i_LastChannel;
80   int i_Sum=0;
81   int i_Offset;
82   unsigned int ui_Channel_num=0;
83   static int i_Count=0;
84   int i_Initialised=0;
85   unsigned int ui_InterruptChannelValue[96]; /* Buffer */
86 */
87 struct str_BoardInfos s_BoardInfos[100];        /*  100 will be the max number of boards to be used */
88 /* END JK 06.07.04: Management of sevrals boards */
89
90 #define AMCC_OP_REG_MCSR        0x3c
91 #define EEPROM_BUSY             0x80000000
92 #define NVCMD_LOAD_LOW          (0x4 << 5)      /* nvRam load low command */
93 #define NVCMD_LOAD_HIGH         (0x5 << 5)      /* nvRam load high command */
94 #define NVCMD_BEGIN_READ        (0x7 << 5)      /* nvRam begin read command */
95 #define NVCMD_BEGIN_WRITE       (0x6 << 5)      /* EEPROM begin write command */
96
97 static int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
98                                      unsigned int dw_PCIBoardEepromAddress,
99                                      unsigned short w_EepromStartAddress,
100                                      unsigned short *pw_DataRead)
101 {
102         unsigned int dw_eeprom_busy = 0;
103         int i_Counter = 0;
104         int i_WordCounter;
105         int i;
106         unsigned char pb_ReadByte[1];
107         unsigned char b_ReadLowByte = 0;
108         unsigned char b_ReadHighByte = 0;
109         unsigned char b_SelectedAddressLow = 0;
110         unsigned char b_SelectedAddressHigh = 0;
111         unsigned short w_ReadWord = 0;
112
113         for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
114                 i_WordCounter++) {
115                 do {
116                         dw_eeprom_busy =
117                                 inl(dw_PCIBoardEepromAddress +
118                                 AMCC_OP_REG_MCSR);
119                         dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
120                 } while (dw_eeprom_busy == EEPROM_BUSY);
121
122                 for (i_Counter = 0; i_Counter < 2; i_Counter++) {
123                         b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256;        /* Read the low 8 bit part */
124                         b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256;       /* Read the high 8 bit part */
125
126                         /* Select the load low address mode */
127                         outb(NVCMD_LOAD_LOW,
128                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
129                                 3);
130
131                         /* Wait on busy */
132                         do {
133                                 dw_eeprom_busy =
134                                         inl(dw_PCIBoardEepromAddress +
135                                         AMCC_OP_REG_MCSR);
136                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
137                         } while (dw_eeprom_busy == EEPROM_BUSY);
138
139                         /* Load the low address */
140                         outb(b_SelectedAddressLow,
141                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
142                                 2);
143
144                         /* Wait on busy */
145                         do {
146                                 dw_eeprom_busy =
147                                         inl(dw_PCIBoardEepromAddress +
148                                         AMCC_OP_REG_MCSR);
149                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
150                         } while (dw_eeprom_busy == EEPROM_BUSY);
151
152                         /* Select the load high address mode */
153                         outb(NVCMD_LOAD_HIGH,
154                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
155                                 3);
156
157                         /* Wait on busy */
158                         do {
159                                 dw_eeprom_busy =
160                                         inl(dw_PCIBoardEepromAddress +
161                                         AMCC_OP_REG_MCSR);
162                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
163                         } while (dw_eeprom_busy == EEPROM_BUSY);
164
165                         /* Load the high address */
166                         outb(b_SelectedAddressHigh,
167                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
168                                 2);
169
170                         /* Wait on busy */
171                         do {
172                                 dw_eeprom_busy =
173                                         inl(dw_PCIBoardEepromAddress +
174                                         AMCC_OP_REG_MCSR);
175                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
176                         } while (dw_eeprom_busy == EEPROM_BUSY);
177
178                         /* Select the READ mode */
179                         outb(NVCMD_BEGIN_READ,
180                                 dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
181                                 3);
182
183                         /* Wait on busy */
184                         do {
185                                 dw_eeprom_busy =
186                                         inl(dw_PCIBoardEepromAddress +
187                                         AMCC_OP_REG_MCSR);
188                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
189                         } while (dw_eeprom_busy == EEPROM_BUSY);
190
191                         /* Read data into the EEPROM */
192                         *pb_ReadByte =
193                                 inb(dw_PCIBoardEepromAddress +
194                                 AMCC_OP_REG_MCSR + 2);
195
196                         /* Wait on busy */
197                         do {
198                                 dw_eeprom_busy =
199                                         inl(dw_PCIBoardEepromAddress +
200                                         AMCC_OP_REG_MCSR);
201                                 dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
202                         } while (dw_eeprom_busy == EEPROM_BUSY);
203
204                         /* Select the upper address part */
205                         if (i_Counter == 0)
206                                 b_ReadLowByte = pb_ReadByte[0];
207                         else
208                                 b_ReadHighByte = pb_ReadByte[0];
209
210
211                         /* Sleep */
212                         msleep(1);
213
214                 }
215                 w_ReadWord =
216                         (b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
217                                 256));
218
219                 pw_DataRead[i_WordCounter] = w_ReadWord;
220
221                 w_EepromStartAddress += 2;      /*  to read the next word */
222
223         }                       /*  for (...) i_NbOfWordsToRead */
224         return 0;
225 }
226
227 static void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress,
228                                                 struct str_BoardInfos *BoardInformations)
229 {
230         unsigned short w_AnalogInputMainHeaderAddress;
231         unsigned short w_AnalogInputComponentAddress;
232         unsigned short w_NumberOfModuls = 0;
233         unsigned short w_CurrentSources[2];
234         unsigned short w_ModulCounter = 0;
235         unsigned short w_FirstHeaderSize = 0;
236         unsigned short w_NumberOfInputs = 0;
237         unsigned short w_CJCFlag = 0;
238         unsigned short w_NumberOfGainValue = 0;
239         unsigned short w_SingleHeaderAddress = 0;
240         unsigned short w_SingleHeaderSize = 0;
241         unsigned short w_Input = 0;
242         unsigned short w_GainFactorAddress = 0;
243         unsigned short w_GainFactorValue[2];
244         unsigned short w_GainIndex = 0;
245         unsigned short w_GainValue = 0;
246
247   /*****************************************/
248   /** Get the Analog input header address **/
249   /*****************************************/
250         i_AddiHeaderRW_ReadEeprom(1,    /* i_NbOfWordsToRead */
251                 dw_PCIBoardEepromAddress, 0x116,        /* w_EepromStartAddress: Analog input header address */
252                 &w_AnalogInputMainHeaderAddress);
253
254   /*******************************************/
255   /** Compute the real analog input address **/
256   /*******************************************/
257         w_AnalogInputMainHeaderAddress = w_AnalogInputMainHeaderAddress + 0x100;
258
259   /******************************/
260   /** Get the number of moduls **/
261   /******************************/
262         i_AddiHeaderRW_ReadEeprom(1,    /* i_NbOfWordsToRead */
263                 dw_PCIBoardEepromAddress, w_AnalogInputMainHeaderAddress + 0x02,        /* w_EepromStartAddress: Number of conponment */
264                 &w_NumberOfModuls);
265
266         for (w_ModulCounter = 0; w_ModulCounter < w_NumberOfModuls;
267                 w_ModulCounter++) {
268       /***********************************/
269       /** Compute the component address **/
270       /***********************************/
271                 w_AnalogInputComponentAddress =
272                         w_AnalogInputMainHeaderAddress +
273                         (w_FirstHeaderSize * w_ModulCounter) + 0x04;
274
275       /****************************/
276       /** Read first header size **/
277       /****************************/
278                 i_AddiHeaderRW_ReadEeprom(1,    /* i_NbOfWordsToRead */
279                         dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress,        /*  Address of the first header */
280                         &w_FirstHeaderSize);
281
282                 w_FirstHeaderSize = w_FirstHeaderSize >> 4;
283
284       /***************************/
285       /** Read number of inputs **/
286       /***************************/
287                 i_AddiHeaderRW_ReadEeprom(1,    /* i_NbOfWordsToRead */
288                         dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x06, /*  Number of inputs for the first modul */
289                         &w_NumberOfInputs);
290
291                 w_NumberOfInputs = w_NumberOfInputs >> 4;
292
293       /***********************/
294       /** Read the CJC flag **/
295       /***********************/
296                 i_AddiHeaderRW_ReadEeprom(1,    /* i_NbOfWordsToRead */
297                         dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x08, /*  CJC flag */
298                         &w_CJCFlag);
299
300                 w_CJCFlag = (w_CJCFlag >> 3) & 0x1;     /*  Get only the CJC flag */
301
302       /*******************************/
303       /** Read number of gain value **/
304       /*******************************/
305                 i_AddiHeaderRW_ReadEeprom(1,    /* i_NbOfWordsToRead */
306                         dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x44, /*  Number of gain value */
307                         &w_NumberOfGainValue);
308
309                 w_NumberOfGainValue = w_NumberOfGainValue & 0xFF;
310
311       /***********************************/
312       /** Compute single header address **/
313       /***********************************/
314                 w_SingleHeaderAddress =
315                         w_AnalogInputComponentAddress + 0x46 +
316                         (((w_NumberOfGainValue / 16) + 1) * 2) +
317                         (6 * w_NumberOfGainValue) +
318                         (4 * (((w_NumberOfGainValue / 16) + 1) * 2));
319
320       /********************************************/
321       /** Read current sources value for input 1 **/
322       /********************************************/
323                 i_AddiHeaderRW_ReadEeprom(1,    /* i_NbOfWordsToRead */
324                         dw_PCIBoardEepromAddress, w_SingleHeaderAddress,        /* w_EepromStartAddress: Single header address */
325                         &w_SingleHeaderSize);
326
327                 w_SingleHeaderSize = w_SingleHeaderSize >> 4;
328
329       /*************************************/
330       /** Read gain factor for the module **/
331       /*************************************/
332                 w_GainFactorAddress = w_AnalogInputComponentAddress;
333
334                 for (w_GainIndex = 0; w_GainIndex < w_NumberOfGainValue;
335                         w_GainIndex++) {
336           /************************************/
337           /** Read gain value for the module **/
338           /************************************/
339                         i_AddiHeaderRW_ReadEeprom(1,    /* i_NbOfWordsToRead */
340                                 dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + (2 * (1 + (w_NumberOfGainValue / 16))) + (0x02 * w_GainIndex),   /*  Gain value */
341                                 &w_GainValue);
342
343                         BoardInformations->s_Module[w_ModulCounter].
344                                 w_GainValue[w_GainIndex] = w_GainValue;
345
346 #             ifdef PRINT_INFO
347                         printk("\n Gain value = %d",
348                                 BoardInformations->s_Module[w_ModulCounter].
349                                 w_GainValue[w_GainIndex]);
350 #             endif
351
352           /*************************************/
353           /** Read gain factor for the module **/
354           /*************************************/
355                         i_AddiHeaderRW_ReadEeprom(2,    /* i_NbOfWordsToRead */
356                                 dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + ((2 * w_NumberOfGainValue) + (2 * (1 + (w_NumberOfGainValue / 16)))) + (0x04 * w_GainIndex),     /*  Gain factor */
357                                 w_GainFactorValue);
358
359                         BoardInformations->s_Module[w_ModulCounter].
360                                 ul_GainFactor[w_GainIndex] =
361                                 (w_GainFactorValue[1] << 16) +
362                                 w_GainFactorValue[0];
363
364 #             ifdef PRINT_INFO
365                         printk("\n w_GainFactorValue [%d] = %lu", w_GainIndex,
366                                 BoardInformations->s_Module[w_ModulCounter].
367                                 ul_GainFactor[w_GainIndex]);
368 #             endif
369                 }
370
371       /***************************************************************/
372       /** Read current source value for each channels of the module **/
373       /***************************************************************/
374                 for (w_Input = 0; w_Input < w_NumberOfInputs; w_Input++) {
375           /********************************************/
376           /** Read current sources value for input 1 **/
377           /********************************************/
378                         i_AddiHeaderRW_ReadEeprom(2,    /* i_NbOfWordsToRead */
379                                 dw_PCIBoardEepromAddress,
380                                 (w_Input * w_SingleHeaderSize) +
381                                 w_SingleHeaderAddress + 0x0C, w_CurrentSources);
382
383           /************************************/
384           /** Save the current sources value **/
385           /************************************/
386                         BoardInformations->s_Module[w_ModulCounter].
387                                 ul_CurrentSource[w_Input] =
388                                 (w_CurrentSources[0] +
389                                 ((w_CurrentSources[1] & 0xFFF) << 16));
390
391 #             ifdef PRINT_INFO
392                         printk("\n Current sources [%d] = %lu", w_Input,
393                                 BoardInformations->s_Module[w_ModulCounter].
394                                 ul_CurrentSource[w_Input]);
395 #             endif
396                 }
397
398       /***************************************/
399       /** Read the CJC current source value **/
400       /***************************************/
401                 i_AddiHeaderRW_ReadEeprom(2,    /* i_NbOfWordsToRead */
402                         dw_PCIBoardEepromAddress,
403                         (w_Input * w_SingleHeaderSize) + w_SingleHeaderAddress +
404                         0x0C, w_CurrentSources);
405
406       /************************************/
407       /** Save the current sources value **/
408       /************************************/
409                 BoardInformations->s_Module[w_ModulCounter].
410                         ul_CurrentSourceCJC =
411                         (w_CurrentSources[0] +
412                         ((w_CurrentSources[1] & 0xFFF) << 16));
413
414 #          ifdef PRINT_INFO
415                 printk("\n Current sources CJC = %lu",
416                         BoardInformations->s_Module[w_ModulCounter].
417                         ul_CurrentSourceCJC);
418 #          endif
419         }
420 }
421
422 static int i_APCI3200_GetChannelCalibrationValue(struct comedi_device *dev,
423                                                  unsigned int ui_Channel_num,
424                                                  unsigned int *CJCCurrentSource,
425                                                  unsigned int *ChannelCurrentSource,
426                                                  unsigned int *ChannelGainFactor)
427 {
428         int i_DiffChannel = 0;
429         int i_Module = 0;
430
431 #ifdef PRINT_INFO
432         printk("\n Channel = %u", ui_Channel_num);
433 #endif
434
435         /* Test if single or differential mode */
436         if (s_BoardInfos[dev->minor].i_ConnectionType == 1) {
437                 /* if diff */
438
439                 if (ui_Channel_num <= 1)
440                         i_DiffChannel = ui_Channel_num, i_Module = 0;
441                 else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3))
442                         i_DiffChannel = ui_Channel_num - 2, i_Module = 1;
443                 else if ((ui_Channel_num >= 4) && (ui_Channel_num <= 5))
444                         i_DiffChannel = ui_Channel_num - 4, i_Module = 2;
445                 else if ((ui_Channel_num >= 6) && (ui_Channel_num <= 7))
446                         i_DiffChannel = ui_Channel_num - 6, i_Module = 3;
447
448         } else {
449                 /*  if single */
450                 if ((ui_Channel_num == 0) || (ui_Channel_num == 1))
451                         i_DiffChannel = 0, i_Module = 0;
452                 else if ((ui_Channel_num == 2) || (ui_Channel_num == 3))
453                         i_DiffChannel = 1, i_Module = 0;
454                 else if ((ui_Channel_num == 4) || (ui_Channel_num == 5))
455                         i_DiffChannel = 0, i_Module = 1;
456                 else if ((ui_Channel_num == 6) || (ui_Channel_num == 7))
457                         i_DiffChannel = 1, i_Module = 1;
458                 else if ((ui_Channel_num == 8) || (ui_Channel_num == 9))
459                         i_DiffChannel = 0, i_Module = 2;
460                 else if ((ui_Channel_num == 10) || (ui_Channel_num == 11))
461                         i_DiffChannel = 1, i_Module = 2;
462                 else if ((ui_Channel_num == 12) || (ui_Channel_num == 13))
463                         i_DiffChannel = 0, i_Module = 3;
464                 else if ((ui_Channel_num == 14) || (ui_Channel_num == 15))
465                         i_DiffChannel = 1, i_Module = 3;
466         }
467
468         /* Test if thermocouple or RTD mode */
469         *CJCCurrentSource =
470                 s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC;
471 #ifdef PRINT_INFO
472         printk("\n CJCCurrentSource = %lu", *CJCCurrentSource);
473 #endif
474
475         *ChannelCurrentSource =
476                 s_BoardInfos[dev->minor].s_Module[i_Module].
477                 ul_CurrentSource[i_DiffChannel];
478 #ifdef PRINT_INFO
479         printk("\n ChannelCurrentSource = %lu", *ChannelCurrentSource);
480 #endif
481         /*       } */
482         /*    } */
483
484         /* Channle gain factor */
485         *ChannelGainFactor =
486                 s_BoardInfos[dev->minor].s_Module[i_Module].
487                 ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain];
488 #ifdef PRINT_INFO
489         printk("\n ChannelGainFactor = %lu", *ChannelGainFactor);
490 #endif
491         /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
492
493         return 0;
494 }
495
496 /*
497  * Read  value  of the selected channel or port
498  *
499  * data[0] = 0: Read single channel
500  *         = 1 Read port value
501  * data[1] = Port number
502  *
503  * data[0] : Read status value
504  */
505 static int i_APCI3200_ReadDigitalInput(struct comedi_device *dev,
506                                        struct comedi_subdevice *s,
507                                        struct comedi_insn *insn,
508                                        unsigned int *data)
509 {
510         struct addi_private *devpriv = dev->private;
511         unsigned int ui_Temp = 0;
512         unsigned int ui_NoOfChannel = 0;
513
514         ui_NoOfChannel = CR_CHAN(insn->chanspec);
515         ui_Temp = data[0];
516         *data = inl(devpriv->i_IobaseReserved);
517
518         if (ui_Temp == 0) {
519                 *data = (*data >> ui_NoOfChannel) & 0x1;
520         }                       /* if  (ui_Temp==0) */
521         else {
522                 if (ui_Temp == 1) {
523                         if (data[1] < 0 || data[1] > 1) {
524                                 printk("\nThe port number is in error\n");
525                                 return -EINVAL;
526                         }       /* if(data[1] < 0 || data[1] >1) */
527                         switch (ui_NoOfChannel) {
528
529                         case 2:
530                                 *data = (*data >> (2 * data[1])) & 0x3;
531                                 break;
532                         case 3:
533                                 *data = (*data & 15);
534                                 break;
535                         default:
536                                 comedi_error(dev, " chan spec wrong");
537                                 return -EINVAL; /*  "sorry channel spec wrong " */
538
539                         }       /* switch(ui_NoOfChannels) */
540                 }               /* if  (ui_Temp==1) */
541                 else {
542                         printk("\nSpecified channel not supported \n");
543                 }               /* elseif  (ui_Temp==1) */
544         }
545         return insn->n;
546 }
547
548 /*
549  * Configures The Digital Output Subdevice.
550  *
551  * data[0] = 1  Memory enable
552  *         = 0  Memory Disable
553  */
554 static int i_APCI3200_ConfigDigitalOutput(struct comedi_device *dev,
555                                           struct comedi_subdevice *s,
556                                           struct comedi_insn *insn,
557                                           unsigned int *data)
558 {
559         struct addi_private *devpriv = dev->private;
560
561         if ((data[0] != 0) && (data[0] != 1)) {
562                 comedi_error(dev,
563                         "Not a valid Data !!! ,Data should be 1 or 0\n");
564                 return -EINVAL;
565         }                       /* if  ( (data[0]!=0) && (data[0]!=1) ) */
566         if (data[0]) {
567                 devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
568         }                       /*  if  (data[0]) */
569         else {
570                 devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
571         }                       /* else if  (data[0]) */
572         return insn->n;
573 }
574
575 /*
576  * Writes To the digital Output Subdevice
577  *
578  * data[0] = Value to output
579  * data[1] = 0  o/p single channel
580  *         = 1  o/p port
581  * data[2] = port no
582  * data[3] = 0  set the digital o/p on
583  *         = 1  set the digital o/p off
584  */
585 static int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev,
586                                          struct comedi_subdevice *s,
587                                          struct comedi_insn *insn,
588                                          unsigned int *data)
589 {
590         struct addi_private *devpriv = dev->private;
591         unsigned int ui_Temp = 0, ui_Temp1 = 0;
592         unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec);  /*  get the channel */
593
594         if (devpriv->b_OutputMemoryStatus) {
595                 ui_Temp = inl(devpriv->i_IobaseAddon);
596
597         }                       /* if(devpriv->b_OutputMemoryStatus ) */
598         else {
599                 ui_Temp = 0;
600         }                       /* if(devpriv->b_OutputMemoryStatus ) */
601         if (data[3] == 0) {
602                 if (data[1] == 0) {
603                         data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
604                         outl(data[0], devpriv->i_IobaseAddon);
605                 }               /* if(data[1]==0) */
606                 else {
607                         if (data[1] == 1) {
608                                 switch (ui_NoOfChannel) {
609
610                                 case 2:
611                                         data[0] =
612                                                 (data[0] << (2 *
613                                                         data[2])) | ui_Temp;
614                                         break;
615                                 case 3:
616                                         data[0] = (data[0] | ui_Temp);
617                                         break;
618                                 }       /* switch(ui_NoOfChannels) */
619
620                                 outl(data[0], devpriv->i_IobaseAddon);
621                         }       /*  if(data[1]==1) */
622                         else {
623                                 printk("\nSpecified channel not supported\n");
624                         }       /* else if(data[1]==1) */
625                 }               /* elseif(data[1]==0) */
626         }                       /* if(data[3]==0) */
627         else {
628                 if (data[3] == 1) {
629                         if (data[1] == 0) {
630                                 data[0] = ~data[0] & 0x1;
631                                 ui_Temp1 = 1;
632                                 ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
633                                 ui_Temp = ui_Temp | ui_Temp1;
634                                 data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
635                                 data[0] = data[0] & ui_Temp;
636                                 outl(data[0], devpriv->i_IobaseAddon);
637                         }       /* if(data[1]==0) */
638                         else {
639                                 if (data[1] == 1) {
640                                         switch (ui_NoOfChannel) {
641
642                                         case 2:
643                                                 data[0] = ~data[0] & 0x3;
644                                                 ui_Temp1 = 3;
645                                                 ui_Temp1 =
646                                                         ui_Temp1 << 2 * data[2];
647                                                 ui_Temp = ui_Temp | ui_Temp1;
648                                                 data[0] =
649                                                         ((data[0] << (2 *
650                                                                         data
651                                                                         [2])) ^
652                                                         0xf) & ui_Temp;
653
654                                                 break;
655                                         case 3:
656                                                 break;
657
658                                         default:
659                                                 comedi_error(dev,
660                                                         " chan spec wrong");
661                                                 return -EINVAL; /*  "sorry channel spec wrong " */
662                                         }       /* switch(ui_NoOfChannels) */
663
664                                         outl(data[0], devpriv->i_IobaseAddon);
665                                 }       /*  if(data[1]==1) */
666                                 else {
667                                         printk("\nSpecified channel not supported\n");
668                                 }       /* else if(data[1]==1) */
669                         }       /* elseif(data[1]==0) */
670                 }               /* if(data[3]==1); */
671                 else {
672                         printk("\nSpecified functionality does not exist\n");
673                         return -EINVAL;
674                 }               /* if else data[3]==1) */
675         }                       /* if else data[3]==0) */
676         return insn->n;
677 }
678
679 /*
680  * Read  value  of the selected channel or port
681  *
682  * data[0] = 0  read single channel
683  *         = 1  read port value
684  * data[1] = port no
685  */
686 static int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev,
687                                         struct comedi_subdevice *s,
688                                         struct comedi_insn *insn,
689                                         unsigned int *data)
690 {
691         struct addi_private *devpriv = dev->private;
692         unsigned int ui_Temp;
693         unsigned int ui_NoOfChannel;
694
695         ui_NoOfChannel = CR_CHAN(insn->chanspec);
696         ui_Temp = data[0];
697         *data = inl(devpriv->i_IobaseAddon);
698         if (ui_Temp == 0) {
699                 *data = (*data >> ui_NoOfChannel) & 0x1;
700         }                       /*  if  (ui_Temp==0) */
701         else {
702                 if (ui_Temp == 1) {
703                         if (data[1] < 0 || data[1] > 1) {
704                                 printk("\nThe port selection is in error\n");
705                                 return -EINVAL;
706                         }       /* if(data[1] <0 ||data[1] >1) */
707                         switch (ui_NoOfChannel) {
708                         case 2:
709                                 *data = (*data >> (2 * data[1])) & 3;
710                                 break;
711
712                         case 3:
713                                 break;
714
715                         default:
716                                 comedi_error(dev, " chan spec wrong");
717                                 return -EINVAL; /*  "sorry channel spec wrong " */
718                                 break;
719                         }       /*  switch(ui_NoOfChannels) */
720                 }               /*  if  (ui_Temp==1) */
721                 else {
722                         printk("\nSpecified channel not supported \n");
723                 }               /*  else if (ui_Temp==1) */
724         }                       /*  else if  (ui_Temp==0) */
725         return insn->n;
726 }
727
728 static int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
729                                               struct comedi_subdevice *s,
730                                               struct comedi_insn *insn,
731                                               unsigned int *data)
732 {
733         struct addi_private *devpriv = dev->private;
734         unsigned int ui_EOC = 0;
735         unsigned int ui_ChannelNo = 0;
736         unsigned int ui_CommandRegister = 0;
737
738         /* BEGIN JK 06.07.04: Management of sevrals boards */
739         /* ui_ChannelNo=i_ChannelNo; */
740         ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo;
741
742         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
743         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
744                                         12) >> 19) & 1) != 1) ;
745   /*********************************/
746         /* Write the channel to configure */
747   /*********************************/
748         /* Begin JK 20.10.2004: Bad channel value is used when using differential mode */
749         /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */
750         /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */
751         outl(0 | s_BoardInfos[dev->minor].i_ChannelNo,
752                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
753         /* End JK 20.10.2004: Bad channel value is used when using differential mode */
754
755   /*******************************/
756         /* Set the convert timing unit */
757   /*******************************/
758         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
759         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
760                                         12) >> 19) & 1) != 1) ;
761
762         /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
763         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
764                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
765
766   /**************************/
767         /* Set the convert timing */
768   /**************************/
769         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
770         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
771                                         12) >> 19) & 1) != 1) ;
772
773         /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
774         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
775                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
776
777   /**************************************************************************/
778         /* Set the start end stop index to the selected channel and set the start */
779   /**************************************************************************/
780
781         ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000;
782
783   /*********************************/
784         /*Test if the interrupt is enable */
785   /*********************************/
786
787         /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
788         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
789       /************************/
790                 /* Enable the interrupt */
791       /************************/
792                 ui_CommandRegister = ui_CommandRegister | 0x00100000;
793         }                       /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
794
795   /******************************/
796         /* Write the command register */
797   /******************************/
798         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
799         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
800                                         12) >> 19) & 1) != 1) ;
801
802         /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */
803         outl(ui_CommandRegister,
804                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
805
806   /*****************************/
807         /*Test if interrupt is enable */
808   /*****************************/
809         /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
810         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
811                 do {
812           /*************************/
813                         /*Read the EOC Status bit */
814           /*************************/
815
816                         /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
817                         ui_EOC = inl(devpriv->iobase +
818                                 s_BoardInfos[dev->minor].i_Offset + 20) & 1;
819
820                 } while (ui_EOC != 1);
821
822       /***************************************/
823                 /* Read the digital value of the input */
824       /***************************************/
825
826                 /* data[0] = inl (devpriv->iobase+i_Offset + 28); */
827                 data[0] =
828                         inl(devpriv->iobase +
829                         s_BoardInfos[dev->minor].i_Offset + 28);
830                 /* END JK 06.07.04: Management of sevrals boards */
831
832         }                       /*  if (i_InterruptFlag == ADDIDATA_DISABLE) */
833         return 0;
834 }
835
836 static int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev,
837                                                  unsigned int *data)
838 {
839         struct addi_private *devpriv = dev->private;
840         unsigned int ui_Temp = 0, ui_EOC = 0;
841         unsigned int ui_CommandRegister = 0;
842
843         /* BEGIN JK 06.07.04: Management of sevrals boards */
844         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
845         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
846                                         12) >> 19) & 1) != 1) ;
847   /*********************************/
848         /* Write the channel to configure */
849   /*********************************/
850         /* Begin JK 20.10.2004: This seems not necessary ! */
851         /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */
852         /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */
853         /* End JK 20.10.2004: This seems not necessary ! */
854
855   /*******************************/
856         /* Set the convert timing unit */
857   /*******************************/
858         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
859         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
860                                         12) >> 19) & 1) != 1) ;
861         /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
862         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
863                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
864   /**************************/
865         /* Set the convert timing */
866   /**************************/
867         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
868         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
869                                         12) >> 19) & 1) != 1) ;
870         /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
871         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
872                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
873   /*****************************/
874         /*Read the calibration offset */
875   /*****************************/
876         /* ui_Temp = inl(devpriv->iobase+i_Offset + 12); */
877         ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
878
879   /*********************************/
880         /*Configure the Offset Conversion */
881   /*********************************/
882         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
883         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
884                                         12) >> 19) & 1) != 1) ;
885         /* outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12); */
886         outl((ui_Temp | 0x00020000),
887                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
888   /*******************************/
889         /*Initialise ui_CommandRegister */
890   /*******************************/
891
892         ui_CommandRegister = 0;
893
894   /*********************************/
895         /*Test if the interrupt is enable */
896   /*********************************/
897
898         /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
899         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
900
901       /**********************/
902                 /*Enable the interrupt */
903       /**********************/
904
905                 ui_CommandRegister = ui_CommandRegister | 0x00100000;
906
907         }                       /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
908
909   /**********************/
910         /*Start the conversion */
911   /**********************/
912         ui_CommandRegister = ui_CommandRegister | 0x00080000;
913
914   /***************************/
915         /*Write the command regiter */
916   /***************************/
917         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
918         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
919                                         12) >> 19) & 1) != 1) ;
920         /* outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8); */
921         outl(ui_CommandRegister,
922                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
923
924   /*****************************/
925         /*Test if interrupt is enable */
926   /*****************************/
927
928         /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
929         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
930
931                 do {
932           /*******************/
933                         /*Read the EOC flag */
934           /*******************/
935
936                         /* ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1; */
937                         ui_EOC = inl(devpriv->iobase +
938                                 s_BoardInfos[dev->minor].i_Offset + 20) & 1;
939
940                 } while (ui_EOC != 1);
941
942       /**************************************************/
943                 /*Read the digital value of the calibration Offset */
944       /**************************************************/
945
946                 /* data[0] = inl(devpriv->iobase+i_Offset+ 28); */
947                 data[0] =
948                         inl(devpriv->iobase +
949                         s_BoardInfos[dev->minor].i_Offset + 28);
950         }                       /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
951         return 0;
952 }
953
954 static int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev,
955                                                unsigned int *data)
956 {
957         struct addi_private *devpriv = dev->private;
958         unsigned int ui_EOC = 0;
959         int ui_CommandRegister = 0;
960
961         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
962         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
963                                         12) >> 19) & 1) != 1) ;
964   /*********************************/
965         /* Write the channel to configure */
966   /*********************************/
967         /* Begin JK 20.10.2004: This seems not necessary ! */
968         /* outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4); */
969         /* outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4); */
970         /* End JK 20.10.2004: This seems not necessary ! */
971
972   /***************************/
973         /*Read the calibration gain */
974   /***************************/
975   /*******************************/
976         /* Set the convert timing unit */
977   /*******************************/
978         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
979         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
980                                         12) >> 19) & 1) != 1) ;
981         /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
982         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
983                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
984   /**************************/
985         /* Set the convert timing */
986   /**************************/
987         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
988         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
989                                         12) >> 19) & 1) != 1) ;
990         /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
991         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
992                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
993   /*******************************/
994         /*Configure the Gain Conversion */
995   /*******************************/
996         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
997         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
998                                         12) >> 19) & 1) != 1) ;
999         /* outl(0x00040000 , devpriv->iobase+i_Offset + 12); */
1000         outl(0x00040000,
1001                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
1002
1003   /*******************************/
1004         /*Initialise ui_CommandRegister */
1005   /*******************************/
1006
1007         ui_CommandRegister = 0;
1008
1009   /*********************************/
1010         /*Test if the interrupt is enable */
1011   /*********************************/
1012
1013         /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1014         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
1015
1016       /**********************/
1017                 /*Enable the interrupt */
1018       /**********************/
1019
1020                 ui_CommandRegister = ui_CommandRegister | 0x00100000;
1021
1022         }                       /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1023
1024   /**********************/
1025         /*Start the conversion */
1026   /**********************/
1027
1028         ui_CommandRegister = ui_CommandRegister | 0x00080000;
1029   /***************************/
1030         /*Write the command regiter */
1031   /***************************/
1032         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1033         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1034                                         12) >> 19) & 1) != 1) ;
1035         /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */
1036         outl(ui_CommandRegister,
1037                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
1038
1039   /*****************************/
1040         /*Test if interrupt is enable */
1041   /*****************************/
1042
1043         /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1044         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
1045
1046                 do {
1047
1048           /*******************/
1049                         /*Read the EOC flag */
1050           /*******************/
1051
1052                         /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
1053                         ui_EOC = inl(devpriv->iobase +
1054                                 s_BoardInfos[dev->minor].i_Offset + 20) & 1;
1055
1056                 } while (ui_EOC != 1);
1057
1058       /************************************************/
1059                 /*Read the digital value of the calibration Gain */
1060       /************************************************/
1061
1062                 /* data[0] = inl(devpriv->iobase+i_Offset + 28); */
1063                 data[0] =
1064                         inl(devpriv->iobase +
1065                         s_BoardInfos[dev->minor].i_Offset + 28);
1066
1067         }                       /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1068         return 0;
1069 }
1070
1071 static int i_APCI3200_ReadCJCValue(struct comedi_device *dev,
1072                                    unsigned int *data)
1073 {
1074         struct addi_private *devpriv = dev->private;
1075         unsigned int ui_EOC = 0;
1076         int ui_CommandRegister = 0;
1077
1078   /******************************/
1079         /*Set the converting time unit */
1080   /******************************/
1081
1082         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1083         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1084                                         12) >> 19) & 1) != 1) ;
1085
1086         /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
1087         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
1088                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
1089   /**************************/
1090         /* Set the convert timing */
1091   /**************************/
1092         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1093         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1094                                         12) >> 19) & 1) != 1) ;
1095
1096         /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
1097         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
1098                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
1099
1100   /******************************/
1101         /*Configure the CJC Conversion */
1102   /******************************/
1103         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1104         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1105                                         12) >> 19) & 1) != 1) ;
1106
1107         /* outl( 0x00000400 , devpriv->iobase+i_Offset + 4); */
1108         outl(0x00000400,
1109                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
1110   /*******************************/
1111         /*Initialise dw_CommandRegister */
1112   /*******************************/
1113         ui_CommandRegister = 0;
1114   /*********************************/
1115         /*Test if the interrupt is enable */
1116   /*********************************/
1117         /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1118         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
1119       /**********************/
1120                 /*Enable the interrupt */
1121       /**********************/
1122                 ui_CommandRegister = ui_CommandRegister | 0x00100000;
1123         }
1124
1125   /**********************/
1126         /*Start the conversion */
1127   /**********************/
1128
1129         ui_CommandRegister = ui_CommandRegister | 0x00080000;
1130
1131   /***************************/
1132         /*Write the command regiter */
1133   /***************************/
1134         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1135         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1136                                         12) >> 19) & 1) != 1) ;
1137         /* outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8); */
1138         outl(ui_CommandRegister,
1139                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
1140
1141   /*****************************/
1142         /*Test if interrupt is enable */
1143   /*****************************/
1144
1145         /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1146         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
1147                 do {
1148
1149           /*******************/
1150                         /*Read the EOC flag */
1151           /*******************/
1152
1153                         /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
1154                         ui_EOC = inl(devpriv->iobase +
1155                                 s_BoardInfos[dev->minor].i_Offset + 20) & 1;
1156
1157                 } while (ui_EOC != 1);
1158
1159       /***********************************/
1160                 /*Read the digital value of the CJC */
1161       /***********************************/
1162
1163                 /* data[0] = inl(devpriv->iobase+i_Offset + 28); */
1164                 data[0] =
1165                         inl(devpriv->iobase +
1166                         s_BoardInfos[dev->minor].i_Offset + 28);
1167
1168         }                       /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1169         return 0;
1170 }
1171
1172 static int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev,
1173                                        unsigned int *data)
1174 {
1175         struct addi_private *devpriv = dev->private;
1176         unsigned int ui_EOC = 0;
1177         int ui_CommandRegister = 0;
1178
1179   /*******************************************/
1180         /*Read calibration offset value for the CJC */
1181   /*******************************************/
1182   /*******************************/
1183         /* Set the convert timing unit */
1184   /*******************************/
1185         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1186         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1187                                         12) >> 19) & 1) != 1) ;
1188         /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
1189         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
1190                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
1191   /**************************/
1192         /* Set the convert timing */
1193   /**************************/
1194         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1195         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1196                                         12) >> 19) & 1) != 1) ;
1197         /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
1198         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
1199                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
1200   /******************************/
1201         /*Configure the CJC Conversion */
1202   /******************************/
1203         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1204         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1205                                         12) >> 19) & 1) != 1) ;
1206         /* outl(0x00000400 , devpriv->iobase+i_Offset + 4); */
1207         outl(0x00000400,
1208                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
1209   /*********************************/
1210         /*Configure the Offset Conversion */
1211   /*********************************/
1212         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1213         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1214                                         12) >> 19) & 1) != 1) ;
1215         /* outl(0x00020000, devpriv->iobase+i_Offset + 12); */
1216         outl(0x00020000,
1217                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
1218   /*******************************/
1219         /*Initialise ui_CommandRegister */
1220   /*******************************/
1221         ui_CommandRegister = 0;
1222   /*********************************/
1223         /*Test if the interrupt is enable */
1224   /*********************************/
1225
1226         /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1227         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
1228       /**********************/
1229                 /*Enable the interrupt */
1230       /**********************/
1231                 ui_CommandRegister = ui_CommandRegister | 0x00100000;
1232
1233         }
1234
1235   /**********************/
1236         /*Start the conversion */
1237   /**********************/
1238         ui_CommandRegister = ui_CommandRegister | 0x00080000;
1239   /***************************/
1240         /*Write the command regiter */
1241   /***************************/
1242         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1243         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1244                                         12) >> 19) & 1) != 1) ;
1245         /* outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8); */
1246         outl(ui_CommandRegister,
1247                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
1248         /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1249         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
1250                 do {
1251           /*******************/
1252                         /*Read the EOC flag */
1253           /*******************/
1254                         /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
1255                         ui_EOC = inl(devpriv->iobase +
1256                                 s_BoardInfos[dev->minor].i_Offset + 20) & 1;
1257                 } while (ui_EOC != 1);
1258
1259       /**************************************************/
1260                 /*Read the digital value of the calibration Offset */
1261       /**************************************************/
1262                 /* data[0] = inl(devpriv->iobase+i_Offset + 28); */
1263                 data[0] =
1264                         inl(devpriv->iobase +
1265                         s_BoardInfos[dev->minor].i_Offset + 28);
1266         }                       /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1267         return 0;
1268 }
1269
1270 static int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev,
1271                                      unsigned int *data)
1272 {
1273         struct addi_private *devpriv = dev->private;
1274         unsigned int ui_EOC = 0;
1275         int ui_CommandRegister = 0;
1276
1277   /*******************************/
1278         /* Set the convert timing unit */
1279   /*******************************/
1280         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1281         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1282                                         12) >> 19) & 1) != 1) ;
1283         /* outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36); */
1284         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
1285                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
1286   /**************************/
1287         /* Set the convert timing */
1288   /**************************/
1289         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1290         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1291                                         12) >> 19) & 1) != 1) ;
1292         /* outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32); */
1293         outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
1294                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
1295   /******************************/
1296         /*Configure the CJC Conversion */
1297   /******************************/
1298         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1299         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1300                                         12) >> 19) & 1) != 1) ;
1301         /* outl(0x00000400,devpriv->iobase+i_Offset + 4); */
1302         outl(0x00000400,
1303                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
1304   /*******************************/
1305         /*Configure the Gain Conversion */
1306   /*******************************/
1307         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1308         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1309                                         12) >> 19) & 1) != 1) ;
1310         /* outl(0x00040000,devpriv->iobase+i_Offset + 12); */
1311         outl(0x00040000,
1312                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
1313
1314   /*******************************/
1315         /*Initialise dw_CommandRegister */
1316   /*******************************/
1317         ui_CommandRegister = 0;
1318   /*********************************/
1319         /*Test if the interrupt is enable */
1320   /*********************************/
1321         /* if (i_InterruptFlag == ADDIDATA_ENABLE) */
1322         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
1323       /**********************/
1324                 /*Enable the interrupt */
1325       /**********************/
1326                 ui_CommandRegister = ui_CommandRegister | 0x00100000;
1327         }
1328   /**********************/
1329         /*Start the conversion */
1330   /**********************/
1331         ui_CommandRegister = ui_CommandRegister | 0x00080000;
1332   /***************************/
1333         /*Write the command regiter */
1334   /***************************/
1335         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
1336         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
1337                                         12) >> 19) & 1) != 1) ;
1338         /* outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8); */
1339         outl(ui_CommandRegister,
1340                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
1341         /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1342         if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
1343                 do {
1344           /*******************/
1345                         /*Read the EOC flag */
1346           /*******************/
1347                         /* ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1; */
1348                         ui_EOC = inl(devpriv->iobase +
1349                                 s_BoardInfos[dev->minor].i_Offset + 20) & 1;
1350                 } while (ui_EOC != 1);
1351       /************************************************/
1352                 /*Read the digital value of the calibration Gain */
1353       /************************************************/
1354                 /* data[0] = inl (devpriv->iobase+i_Offset + 28); */
1355                 data[0] =
1356                         inl(devpriv->iobase +
1357                         s_BoardInfos[dev->minor].i_Offset + 28);
1358         }                       /* if (i_InterruptFlag == ADDIDATA_DISABLE) */
1359         return 0;
1360 }
1361
1362 static int i_APCI3200_Reset(struct comedi_device *dev)
1363 {
1364         struct addi_private *devpriv = dev->private;
1365         int i_Temp;
1366         unsigned int dw_Dummy;
1367
1368         /* i_InterruptFlag=0; */
1369         /* i_Initialised==0; */
1370         /* i_Count=0; */
1371         /* i_Sum=0; */
1372
1373         s_BoardInfos[dev->minor].i_InterruptFlag = 0;
1374         s_BoardInfos[dev->minor].i_Initialised = 0;
1375         s_BoardInfos[dev->minor].i_Count = 0;
1376         s_BoardInfos[dev->minor].i_Sum = 0;
1377         s_BoardInfos[dev->minor].b_StructInitialized = 0;
1378
1379         outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
1380
1381         /*  Enable the interrupt for the controller */
1382         dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
1383         outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
1384         outl(0, devpriv->i_IobaseAddon);        /* Resets the output */
1385   /***************/
1386         /*Empty the buffer */
1387   /**************/
1388         for (i_Temp = 0; i_Temp <= 95; i_Temp++) {
1389                 /* ui_InterruptChannelValue[i_Temp]=0; */
1390                 s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0;
1391         }                       /* for(i_Temp=0;i_Temp<=95;i_Temp++) */
1392   /*****************************/
1393         /*Reset the START and IRQ bit */
1394   /*****************************/
1395         for (i_Temp = 0; i_Temp <= 192;) {
1396                 while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ;
1397                 outl(0, devpriv->iobase + i_Temp + 8);
1398                 i_Temp = i_Temp + 64;
1399         }                       /* for(i_Temp=0;i_Temp<=192;i_Temp+64) */
1400         return 0;
1401 }
1402
1403 /*
1404  * Read value of the selected channel
1405  *
1406  * data[0]  : Digital Value Of Input
1407  * data[1]  : Calibration Offset Value
1408  * data[2]  : Calibration Gain Value
1409  * data[3]  : CJC value
1410  * data[4]  : CJC offset value
1411  * data[5]  : CJC gain value
1412  * data[6] : CJC current source from eeprom
1413  * data[7] : Channel current source from eeprom
1414  * data[8] : Channle gain factor from eeprom
1415  */
1416 static int i_APCI3200_ReadAnalogInput(struct comedi_device *dev,
1417                                       struct comedi_subdevice *s,
1418                                       struct comedi_insn *insn,
1419                                       unsigned int *data)
1420 {
1421         unsigned int ui_DummyValue = 0;
1422         int i_ConvertCJCCalibration;
1423         int i = 0;
1424
1425         /* BEGIN JK 06.07.04: Management of sevrals boards */
1426         /* if(i_Initialised==0) */
1427         if (s_BoardInfos[dev->minor].i_Initialised == 0)
1428                 /* END JK 06.07.04: Management of sevrals boards */
1429         {
1430                 i_APCI3200_Reset(dev);
1431                 return -EINVAL;
1432         }                       /* if(i_Initialised==0); */
1433
1434 #ifdef PRINT_INFO
1435         printk("\n insn->unused[0] = %i", insn->unused[0]);
1436 #endif
1437
1438         switch (insn->unused[0]) {
1439         case 0:
1440
1441                 i_APCI3200_Read1AnalogInputChannel(dev, s, insn,
1442                         &ui_DummyValue);
1443                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1444                 /* ui_InterruptChannelValue[i_Count+0]=ui_DummyValue; */
1445                 s_BoardInfos[dev->minor].
1446                         ui_InterruptChannelValue[s_BoardInfos[dev->minor].
1447                         i_Count + 0] = ui_DummyValue;
1448                 /* END JK 06.07.04: Management of sevrals boards */
1449
1450                 /* Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1451                 i_APCI3200_GetChannelCalibrationValue(dev,
1452                         s_BoardInfos[dev->minor].ui_Channel_num,
1453                         &s_BoardInfos[dev->minor].
1454                         ui_InterruptChannelValue[s_BoardInfos[dev->minor].
1455                                 i_Count + 6],
1456                         &s_BoardInfos[dev->minor].
1457                         ui_InterruptChannelValue[s_BoardInfos[dev->minor].
1458                                 i_Count + 7],
1459                         &s_BoardInfos[dev->minor].
1460                         ui_InterruptChannelValue[s_BoardInfos[dev->minor].
1461                                 i_Count + 8]);
1462
1463 #ifdef PRINT_INFO
1464                 printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
1465
1466                 printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
1467
1468                 printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
1469 #endif
1470
1471                 /* End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1472
1473                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1474                 /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */
1475                 if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
1476                         && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
1477                         && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
1478                         /* END JK 06.07.04: Management of sevrals boards */
1479                 {
1480                         i_APCI3200_ReadCJCValue(dev, &ui_DummyValue);
1481                         /* BEGIN JK 06.07.04: Management of sevrals boards */
1482                         /* ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue; */
1483                         s_BoardInfos[dev->minor].
1484                                 ui_InterruptChannelValue[s_BoardInfos[dev->
1485                                         minor].i_Count + 3] = ui_DummyValue;
1486                         /* END JK 06.07.04: Management of sevrals boards */
1487                 }               /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */
1488                 else {
1489                         /* BEGIN JK 06.07.04: Management of sevrals boards */
1490                         /* ui_InterruptChannelValue[i_Count + 3]=0; */
1491                         s_BoardInfos[dev->minor].
1492                                 ui_InterruptChannelValue[s_BoardInfos[dev->
1493                                         minor].i_Count + 3] = 0;
1494                         /* END JK 06.07.04: Management of sevrals boards */
1495                 }               /* elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1)) */
1496
1497                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1498                 /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */
1499                 if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE)
1500                         && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE))
1501                         /* END JK 06.07.04: Management of sevrals boards */
1502                 {
1503                         i_APCI3200_ReadCalibrationOffsetValue(dev,
1504                                 &ui_DummyValue);
1505                         /* BEGIN JK 06.07.04: Management of sevrals boards */
1506                         /* ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue; */
1507                         s_BoardInfos[dev->minor].
1508                                 ui_InterruptChannelValue[s_BoardInfos[dev->
1509                                         minor].i_Count + 1] = ui_DummyValue;
1510                         /* END JK 06.07.04: Management of sevrals boards */
1511                         i_APCI3200_ReadCalibrationGainValue(dev,
1512                                 &ui_DummyValue);
1513                         /* BEGIN JK 06.07.04: Management of sevrals boards */
1514                         /* ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue; */
1515                         s_BoardInfos[dev->minor].
1516                                 ui_InterruptChannelValue[s_BoardInfos[dev->
1517                                         minor].i_Count + 2] = ui_DummyValue;
1518                         /* END JK 06.07.04: Management of sevrals boards */
1519                 }               /* if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE)) */
1520
1521                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1522                 /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1)) */
1523                 if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
1524                         && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
1525                         && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
1526                         /* END JK 06.07.04: Management of sevrals boards */
1527                 {
1528           /**********************************************************/
1529                         /*Test if the Calibration channel must be read for the CJC */
1530           /**********************************************************/
1531           /**********************************/
1532                         /*Test if the polarity is the same */
1533           /**********************************/
1534                         /* BEGIN JK 06.07.04: Management of sevrals boards */
1535                         /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
1536                         if (s_BoardInfos[dev->minor].i_CJCPolarity !=
1537                                 s_BoardInfos[dev->minor].i_ADDIDATAPolarity)
1538                                 /* END JK 06.07.04: Management of sevrals boards */
1539                         {
1540                                 i_ConvertCJCCalibration = 1;
1541                         }       /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
1542                         else {
1543                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1544                                 /* if(i_CJCGain==i_ADDIDATAGain) */
1545                                 if (s_BoardInfos[dev->minor].i_CJCGain ==
1546                                         s_BoardInfos[dev->minor].i_ADDIDATAGain)
1547                                         /* END JK 06.07.04: Management of sevrals boards */
1548                                 {
1549                                         i_ConvertCJCCalibration = 0;
1550                                 }       /* if(i_CJCGain==i_ADDIDATAGain) */
1551                                 else {
1552                                         i_ConvertCJCCalibration = 1;
1553                                 }       /* elseif(i_CJCGain==i_ADDIDATAGain) */
1554                         }       /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */
1555                         if (i_ConvertCJCCalibration == 1) {
1556                                 i_APCI3200_ReadCJCCalOffset(dev,
1557                                         &ui_DummyValue);
1558                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1559                                 /* ui_InterruptChannelValue[i_Count+4]=ui_DummyValue; */
1560                                 s_BoardInfos[dev->minor].
1561                                         ui_InterruptChannelValue[s_BoardInfos
1562                                         [dev->minor].i_Count + 4] =
1563                                         ui_DummyValue;
1564                                 /* END JK 06.07.04: Management of sevrals boards */
1565
1566                                 i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue);
1567
1568                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1569                                 /* ui_InterruptChannelValue[i_Count+5]=ui_DummyValue; */
1570                                 s_BoardInfos[dev->minor].
1571                                         ui_InterruptChannelValue[s_BoardInfos
1572                                         [dev->minor].i_Count + 5] =
1573                                         ui_DummyValue;
1574                                 /* END JK 06.07.04: Management of sevrals boards */
1575                         }       /* if(i_ConvertCJCCalibration==1) */
1576                         else {
1577                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1578                                 /* ui_InterruptChannelValue[i_Count+4]=0; */
1579                                 /* ui_InterruptChannelValue[i_Count+5]=0; */
1580
1581                                 s_BoardInfos[dev->minor].
1582                                         ui_InterruptChannelValue[s_BoardInfos
1583                                         [dev->minor].i_Count + 4] = 0;
1584                                 s_BoardInfos[dev->minor].
1585                                         ui_InterruptChannelValue[s_BoardInfos
1586                                         [dev->minor].i_Count + 5] = 0;
1587                                 /* END JK 06.07.04: Management of sevrals boards */
1588                         }       /* elseif(i_ConvertCJCCalibration==1) */
1589                 }               /* if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)) */
1590
1591                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1592                 /* if(i_ScanType!=1) */
1593                 if (s_BoardInfos[dev->minor].i_ScanType != 1) {
1594                         /* i_Count=0; */
1595                         s_BoardInfos[dev->minor].i_Count = 0;
1596                 }               /* if(i_ScanType!=1) */
1597                 else {
1598                         /* i_Count=i_Count +6; */
1599                         /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1600                         /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6; */
1601                         s_BoardInfos[dev->minor].i_Count =
1602                                 s_BoardInfos[dev->minor].i_Count + 9;
1603                         /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1604                 }               /* else if(i_ScanType!=1) */
1605
1606                 /* if((i_ScanType==1) &&(i_InterruptFlag==1)) */
1607                 if ((s_BoardInfos[dev->minor].i_ScanType == 1)
1608                         && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) {
1609                         /* i_Count=i_Count-6; */
1610                         /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1611                         /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6; */
1612                         s_BoardInfos[dev->minor].i_Count =
1613                                 s_BoardInfos[dev->minor].i_Count - 9;
1614                         /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1615                 }
1616                 /* if(i_ScanType==0) */
1617                 if (s_BoardInfos[dev->minor].i_ScanType == 0) {
1618                         /*
1619                            data[0]= ui_InterruptChannelValue[0];
1620                            data[1]= ui_InterruptChannelValue[1];
1621                            data[2]= ui_InterruptChannelValue[2];
1622                            data[3]= ui_InterruptChannelValue[3];
1623                            data[4]= ui_InterruptChannelValue[4];
1624                            data[5]= ui_InterruptChannelValue[5];
1625                          */
1626 #ifdef PRINT_INFO
1627                         printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
1628 #endif
1629                         data[0] =
1630                                 s_BoardInfos[dev->minor].
1631                                 ui_InterruptChannelValue[0];
1632                         data[1] =
1633                                 s_BoardInfos[dev->minor].
1634                                 ui_InterruptChannelValue[1];
1635                         data[2] =
1636                                 s_BoardInfos[dev->minor].
1637                                 ui_InterruptChannelValue[2];
1638                         data[3] =
1639                                 s_BoardInfos[dev->minor].
1640                                 ui_InterruptChannelValue[3];
1641                         data[4] =
1642                                 s_BoardInfos[dev->minor].
1643                                 ui_InterruptChannelValue[4];
1644                         data[5] =
1645                                 s_BoardInfos[dev->minor].
1646                                 ui_InterruptChannelValue[5];
1647
1648                         /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1649                         /* printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]); */
1650                         i_APCI3200_GetChannelCalibrationValue(dev,
1651                                 s_BoardInfos[dev->minor].ui_Channel_num,
1652                                 &data[6], &data[7], &data[8]);
1653                         /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1654                 }
1655                 break;
1656         case 1:
1657
1658                 for (i = 0; i < insn->n; i++) {
1659                         /* data[i]=ui_InterruptChannelValue[i]; */
1660                         data[i] =
1661                                 s_BoardInfos[dev->minor].
1662                                 ui_InterruptChannelValue[i];
1663                 }
1664
1665                 /* i_Count=0; */
1666                 /* i_Sum=0; */
1667                 /* if(i_ScanType==1) */
1668                 s_BoardInfos[dev->minor].i_Count = 0;
1669                 s_BoardInfos[dev->minor].i_Sum = 0;
1670                 if (s_BoardInfos[dev->minor].i_ScanType == 1) {
1671                         /* i_Initialised=0; */
1672                         /* i_InterruptFlag=0; */
1673                         s_BoardInfos[dev->minor].i_Initialised = 0;
1674                         s_BoardInfos[dev->minor].i_InterruptFlag = 0;
1675                         /* END JK 06.07.04: Management of sevrals boards */
1676                 }
1677                 break;
1678         default:
1679                 printk("\nThe parameters passed are in error\n");
1680                 i_APCI3200_Reset(dev);
1681                 return -EINVAL;
1682         }                       /* switch(insn->unused[0]) */
1683
1684         return insn->n;
1685 }
1686
1687 /*
1688  * Configures The Analog Input Subdevice
1689  *
1690  * data[0]  = 0  Normal AI
1691  *          = 1  RTD
1692  *          = 2  THERMOCOUPLE
1693  * data[1]  = Gain To Use
1694  * data[2]  = 0  Bipolar
1695  *          = 1  Unipolar
1696  * data[3]  = Offset Range
1697  * data[4]  = 0  DC Coupling
1698  *          = 1  AC Coupling
1699  * data[5]  = 0  Single
1700  *          = 1  Differential
1701  * data[6]  = TimerReloadValue
1702  * data[7]  = ConvertingTimeUnit
1703  * data[8]  = 0  Analog voltage measurement
1704  *          = 1  Resistance measurement
1705  *          = 2  Temperature measurement
1706  * data[9]  = 0  Interrupt Disable
1707  *          = 1  INterrupt Enable
1708  * data[10] = Type of Thermocouple
1709  * data[11] = single channel Module Number
1710  * data[12] = 0  Single Read
1711  *          = 1  Read more channel
1712  *          = 2  Single scan
1713  *          = 3  Continuous Scan
1714  * data[13] = Number of channels to read
1715  * data[14] = 0  RTD not used
1716  *          = 1  RTD 2 wire connection
1717  *          = 2  RTD 3 wire connection
1718  *          = 3  RTD 4 wire connection
1719  */
1720 static int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev,
1721                                         struct comedi_subdevice *s,
1722                                         struct comedi_insn *insn,
1723                                         unsigned int *data)
1724 {
1725         struct addi_private *devpriv = dev->private;
1726         unsigned int ul_Config = 0, ul_Temp = 0;
1727         unsigned int ui_ChannelNo = 0;
1728         unsigned int ui_Dummy = 0;
1729         int i_err = 0;
1730
1731         /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1732
1733 #ifdef PRINT_INFO
1734         int i = 0, i2 = 0;
1735 #endif
1736         /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1737
1738         /* BEGIN JK 06.07.04: Management of sevrals boards */
1739         /*  Initialize the structure */
1740         if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
1741                 s_BoardInfos[dev->minor].i_CJCAvailable = 1;
1742                 s_BoardInfos[dev->minor].i_CJCPolarity = 0;
1743                 s_BoardInfos[dev->minor].i_CJCGain = 2; /* changed from 0 to 2 */
1744                 s_BoardInfos[dev->minor].i_InterruptFlag = 0;
1745                 s_BoardInfos[dev->minor].i_AutoCalibration = 0; /* : auto calibration */
1746                 s_BoardInfos[dev->minor].i_ChannelCount = 0;
1747                 s_BoardInfos[dev->minor].i_Sum = 0;
1748                 s_BoardInfos[dev->minor].ui_Channel_num = 0;
1749                 s_BoardInfos[dev->minor].i_Count = 0;
1750                 s_BoardInfos[dev->minor].i_Initialised = 0;
1751                 s_BoardInfos[dev->minor].b_StructInitialized = 1;
1752
1753                 /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1754                 s_BoardInfos[dev->minor].i_ConnectionType = 0;
1755                 /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1756
1757                 /* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1758                 memset(s_BoardInfos[dev->minor].s_Module, 0,
1759                         sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE]));
1760
1761                 v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc,
1762                         &s_BoardInfos[dev->minor]);
1763
1764 #ifdef PRINT_INFO
1765                 for (i = 0; i < MAX_MODULE; i++) {
1766                         printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
1767                                 s_BoardInfos[dev->minor].s_Module[i].
1768                                 ul_CurrentSourceCJC);
1769
1770                         for (i2 = 0; i2 < 5; i2++) {
1771                                 printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
1772                         }
1773
1774                         for (i2 = 0; i2 < 8; i2++) {
1775                                 printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
1776                         }
1777
1778                         for (i2 = 0; i2 < 8; i2++) {
1779                                 printk("\n s_Module[%i].w_GainValue [%i] = %u",
1780                                         i, i2,
1781                                         s_BoardInfos[dev->minor].s_Module[i].
1782                                         w_GainValue[i2]);
1783                         }
1784                 }
1785 #endif
1786                 /* End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
1787         }
1788
1789         if (data[0] != 0 && data[0] != 1 && data[0] != 2) {
1790                 printk("\nThe selection of acquisition type is in error\n");
1791                 i_err++;
1792         }                       /* if(data[0]!=0 && data[0]!=1 && data[0]!=2) */
1793         if (data[0] == 1) {
1794                 if (data[14] != 0 && data[14] != 1 && data[14] != 2
1795                         && data[14] != 4) {
1796                         printk("\n Error in selection of RTD connection type\n");
1797                         i_err++;
1798                 }               /* if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4) */
1799         }                       /* if(data[0]==1 ) */
1800         if (data[1] < 0 || data[1] > 7) {
1801                 printk("\nThe selection of gain is in error\n");
1802                 i_err++;
1803         }                       /*  if(data[1]<0 || data[1]>7) */
1804         if (data[2] != 0 && data[2] != 1) {
1805                 printk("\nThe selection of polarity is in error\n");
1806                 i_err++;
1807         }                       /* if(data[2]!=0 &&  data[2]!=1) */
1808         if (data[3] != 0) {
1809                 printk("\nThe selection of offset range  is in error\n");
1810                 i_err++;
1811         }                       /*  if(data[3]!=0) */
1812         if (data[4] != 0 && data[4] != 1) {
1813                 printk("\nThe selection of coupling is in error\n");
1814                 i_err++;
1815         }                       /* if(data[4]!=0 &&  data[4]!=1) */
1816         if (data[5] != 0 && data[5] != 1) {
1817                 printk("\nThe selection of single/differential mode is in error\n");
1818                 i_err++;
1819         }                       /* if(data[5]!=0 &&  data[5]!=1) */
1820         if (data[8] != 0 && data[8] != 1 && data[2] != 2) {
1821                 printk("\nError in selection of functionality\n");
1822         }                       /* if(data[8]!=0 && data[8]!=1 && data[2]!=2) */
1823         if (data[12] == 0 || data[12] == 1) {
1824                 if (data[6] != 20 && data[6] != 40 && data[6] != 80
1825                         && data[6] != 160) {
1826                         printk("\nThe selection of conversion time reload value is in error\n");
1827                         i_err++;
1828                 }               /*  if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 ) */
1829                 if (data[7] != 2) {
1830                         printk("\nThe selection of conversion time unit  is in error\n");
1831                         i_err++;
1832                 }               /*  if(data[7]!=2) */
1833         }
1834         if (data[9] != 0 && data[9] != 1) {
1835                 printk("\nThe selection of interrupt enable is in error\n");
1836                 i_err++;
1837         }                       /* if(data[9]!=0 &&  data[9]!=1) */
1838         if (data[11] < 0 || data[11] > 4) {
1839                 printk("\nThe selection of module is in error\n");
1840                 i_err++;
1841         }                       /* if(data[11] <0 ||  data[11]>1) */
1842         if (data[12] < 0 || data[12] > 3) {
1843                 printk("\nThe selection of singlechannel/scan selection is in error\n");
1844                 i_err++;
1845         }                       /* if(data[12] < 0 ||  data[12]> 3) */
1846         if (data[13] < 0 || data[13] > 16) {
1847                 printk("\nThe selection of number of channels is in error\n");
1848                 i_err++;
1849         }                       /*  if(data[13] <0 ||data[13] >15) */
1850
1851         /* BEGIN JK 06.07.04: Management of sevrals boards */
1852         /*
1853            i_ChannelCount=data[13];
1854            i_ScanType=data[12];
1855            i_ADDIDATAPolarity = data[2];
1856            i_ADDIDATAGain=data[1];
1857            i_ADDIDATAConversionTime=data[6];
1858            i_ADDIDATAConversionTimeUnit=data[7];
1859            i_ADDIDATAType=data[0];
1860          */
1861
1862         /*  Save acquisition configuration for the actual board */
1863         s_BoardInfos[dev->minor].i_ChannelCount = data[13];
1864         s_BoardInfos[dev->minor].i_ScanType = data[12];
1865         s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2];
1866         s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1];
1867         s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6];
1868         s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7];
1869         s_BoardInfos[dev->minor].i_ADDIDATAType = data[0];
1870         /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
1871         s_BoardInfos[dev->minor].i_ConnectionType = data[5];
1872         /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
1873         /* END JK 06.07.04: Management of sevrals boards */
1874
1875         /* Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
1876         memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); /*  7 is the maximal number of channels */
1877         /* End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
1878
1879         /* BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards */
1880         /* while(i_InterruptFlag==1) */
1881         while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
1882 #ifndef MSXBOX
1883                 udelay(1);
1884 #else
1885                 /*  In the case where the driver is compiled for the MSX-Box */
1886                 /*  we used a printk to have a little delay because udelay */
1887                 /*  seems to be broken under the MSX-Box. */
1888                 /*  This solution hat to be studied. */
1889                 printk("");
1890 #endif
1891         }
1892         /* END JK 02.07.04 : This while can't be do, it block the process when using severals boards */
1893
1894         ui_ChannelNo = CR_CHAN(insn->chanspec); /*  get the channel */
1895         /* BEGIN JK 06.07.04: Management of sevrals boards */
1896         /* i_ChannelNo=ui_ChannelNo; */
1897         /* ui_Channel_num =ui_ChannelNo; */
1898
1899         s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo;
1900         s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo;
1901
1902         /* END JK 06.07.04: Management of sevrals boards */
1903
1904         if (data[5] == 0) {
1905                 if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
1906                         printk("\nThe Selection of the channel is in error\n");
1907                         i_err++;
1908                 }               /*  if(ui_ChannelNo<0 || ui_ChannelNo>15) */
1909         }                       /* if(data[5]==0) */
1910         else {
1911                 if (data[14] == 2) {
1912                         if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
1913                                 printk("\nThe Selection of the channel is in error\n");
1914                                 i_err++;
1915                         }       /*  if(ui_ChannelNo<0 || ui_ChannelNo>3) */
1916                 }               /* if(data[14]==2) */
1917                 else {
1918                         if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
1919                                 printk("\nThe Selection of the channel is in error\n");
1920                                 i_err++;
1921                         }       /*  if(ui_ChannelNo<0 || ui_ChannelNo>7) */
1922                 }               /* elseif(data[14]==2) */
1923         }                       /* elseif(data[5]==0) */
1924         if (data[12] == 0 || data[12] == 1) {
1925                 switch (data[5]) {
1926                 case 0:
1927                         if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
1928                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1929                                 /* i_Offset=0; */
1930                                 s_BoardInfos[dev->minor].i_Offset = 0;
1931                                 /* END JK 06.07.04: Management of sevrals boards */
1932                         }       /* if(ui_ChannelNo >=0 && ui_ChannelNo <=3) */
1933                         if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
1934                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1935                                 /* i_Offset=64; */
1936                                 s_BoardInfos[dev->minor].i_Offset = 64;
1937                                 /* END JK 06.07.04: Management of sevrals boards */
1938                         }       /* if(ui_ChannelNo >=4 && ui_ChannelNo <=7) */
1939                         if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) {
1940                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1941                                 /* i_Offset=128; */
1942                                 s_BoardInfos[dev->minor].i_Offset = 128;
1943                                 /* END JK 06.07.04: Management of sevrals boards */
1944                         }       /* if(ui_ChannelNo >=8 && ui_ChannelNo <=11) */
1945                         if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) {
1946                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1947                                 /* i_Offset=192; */
1948                                 s_BoardInfos[dev->minor].i_Offset = 192;
1949                                 /* END JK 06.07.04: Management of sevrals boards */
1950                         }       /* if(ui_ChannelNo >=12 && ui_ChannelNo <=15) */
1951                         break;
1952                 case 1:
1953                         if (data[14] == 2) {
1954                                 if (ui_ChannelNo == 0) {
1955                                         /* BEGIN JK 06.07.04: Management of sevrals boards */
1956                                         /* i_Offset=0; */
1957                                         s_BoardInfos[dev->minor].i_Offset = 0;
1958                                         /* END JK 06.07.04: Management of sevrals boards */
1959                                 }       /* if(ui_ChannelNo ==0 ) */
1960                                 if (ui_ChannelNo == 1) {
1961                                         /* BEGIN JK 06.07.04: Management of sevrals boards */
1962                                         /* i_Offset=0; */
1963                                         s_BoardInfos[dev->minor].i_Offset = 64;
1964                                         /* END JK 06.07.04: Management of sevrals boards */
1965                                 }       /*  if(ui_ChannelNo ==1) */
1966                                 if (ui_ChannelNo == 2) {
1967                                         /* BEGIN JK 06.07.04: Management of sevrals boards */
1968                                         /* i_Offset=128; */
1969                                         s_BoardInfos[dev->minor].i_Offset = 128;
1970                                         /* END JK 06.07.04: Management of sevrals boards */
1971                                 }       /* if(ui_ChannelNo ==2 ) */
1972                                 if (ui_ChannelNo == 3) {
1973                                         /* BEGIN JK 06.07.04: Management of sevrals boards */
1974                                         /* i_Offset=192; */
1975                                         s_BoardInfos[dev->minor].i_Offset = 192;
1976                                         /* END JK 06.07.04: Management of sevrals boards */
1977                                 }       /* if(ui_ChannelNo ==3) */
1978
1979                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1980                                 /* i_ChannelNo=0; */
1981                                 s_BoardInfos[dev->minor].i_ChannelNo = 0;
1982                                 /* END JK 06.07.04: Management of sevrals boards */
1983                                 ui_ChannelNo = 0;
1984                                 break;
1985                         }       /* if(data[14]==2) */
1986                         if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
1987                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1988                                 /* i_Offset=0; */
1989                                 s_BoardInfos[dev->minor].i_Offset = 0;
1990                                 /* END JK 06.07.04: Management of sevrals boards */
1991                         }       /* if(ui_ChannelNo >=0 && ui_ChannelNo <=1) */
1992                         if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
1993                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
1994                                 /* i_ChannelNo=i_ChannelNo-2; */
1995                                 /* i_Offset=64; */
1996                                 s_BoardInfos[dev->minor].i_ChannelNo =
1997                                         s_BoardInfos[dev->minor].i_ChannelNo -
1998                                         2;
1999                                 s_BoardInfos[dev->minor].i_Offset = 64;
2000                                 /* END JK 06.07.04: Management of sevrals boards */
2001                                 ui_ChannelNo = ui_ChannelNo - 2;
2002                         }       /* if(ui_ChannelNo >=2 && ui_ChannelNo <=3) */
2003                         if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) {
2004                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
2005                                 /* i_ChannelNo=i_ChannelNo-4; */
2006                                 /* i_Offset=128; */
2007                                 s_BoardInfos[dev->minor].i_ChannelNo =
2008                                         s_BoardInfos[dev->minor].i_ChannelNo -
2009                                         4;
2010                                 s_BoardInfos[dev->minor].i_Offset = 128;
2011                                 /* END JK 06.07.04: Management of sevrals boards */
2012                                 ui_ChannelNo = ui_ChannelNo - 4;
2013                         }       /* if(ui_ChannelNo >=4 && ui_ChannelNo <=5) */
2014                         if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) {
2015                                 /* BEGIN JK 06.07.04: Management of sevrals boards */
2016                                 /* i_ChannelNo=i_ChannelNo-6; */
2017                                 /* i_Offset=192; */
2018                                 s_BoardInfos[dev->minor].i_ChannelNo =
2019                                         s_BoardInfos[dev->minor].i_ChannelNo -
2020                                         6;
2021                                 s_BoardInfos[dev->minor].i_Offset = 192;
2022                                 /* END JK 06.07.04: Management of sevrals boards */
2023                                 ui_ChannelNo = ui_ChannelNo - 6;
2024                         }       /* if(ui_ChannelNo >=6 && ui_ChannelNo <=7) */
2025                         break;
2026
2027                 default:
2028                         printk("\n This selection of polarity does not exist\n");
2029                         i_err++;
2030                 }               /* switch(data[2]) */
2031         }                       /* if(data[12]==0 || data[12]==1) */
2032         else {
2033                 switch (data[11]) {
2034                 case 1:
2035                         /* BEGIN JK 06.07.04: Management of sevrals boards */
2036                         /* i_Offset=0; */
2037                         s_BoardInfos[dev->minor].i_Offset = 0;
2038                         /* END JK 06.07.04: Management of sevrals boards */
2039                         break;
2040                 case 2:
2041                         /* BEGIN JK 06.07.04: Management of sevrals boards */
2042                         /* i_Offset=64; */
2043                         s_BoardInfos[dev->minor].i_Offset = 64;
2044                         /* END JK 06.07.04: Management of sevrals boards */
2045                         break;
2046                 case 3:
2047                         /* BEGIN JK 06.07.04: Management of sevrals boards */
2048                         /* i_Offset=128; */
2049                         s_BoardInfos[dev->minor].i_Offset = 128;
2050                         /* END JK 06.07.04: Management of sevrals boards */
2051                         break;
2052                 case 4:
2053                         /* BEGIN JK 06.07.04: Management of sevrals boards */
2054                         /* i_Offset=192; */
2055                         s_BoardInfos[dev->minor].i_Offset = 192;
2056                         /* END JK 06.07.04: Management of sevrals boards */
2057                         break;
2058                 default:
2059                         printk("\nError in module selection\n");
2060                         i_err++;
2061                 }               /*  switch(data[11]) */
2062         }                       /*  elseif(data[12]==0 || data[12]==1) */
2063         if (i_err) {
2064                 i_APCI3200_Reset(dev);
2065                 return -EINVAL;
2066         }
2067         /* if(i_ScanType!=1) */
2068         if (s_BoardInfos[dev->minor].i_ScanType != 1) {
2069                 /* BEGIN JK 06.07.04: Management of sevrals boards */
2070                 /* i_Count=0; */
2071                 /* i_Sum=0; */
2072                 s_BoardInfos[dev->minor].i_Count = 0;
2073                 s_BoardInfos[dev->minor].i_Sum = 0;
2074                 /* END JK 06.07.04: Management of sevrals boards */
2075         }                       /* if(i_ScanType!=1) */
2076
2077         ul_Config =
2078                 data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) |
2079                 (data[4] << 9);
2080         /* BEGIN JK 06.07.04: Management of sevrals boards */
2081         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2082         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2083                                         12) >> 19) & 1) != 1) ;
2084         /* END JK 06.07.04: Management of sevrals boards */
2085   /*********************************/
2086         /* Write the channel to configure */
2087   /*********************************/
2088         /* BEGIN JK 06.07.04: Management of sevrals boards */
2089         /* outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4); */
2090         outl(0 | ui_ChannelNo,
2091                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
2092         /* END JK 06.07.04: Management of sevrals boards */
2093
2094         /* BEGIN JK 06.07.04: Management of sevrals boards */
2095         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2096         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2097                                         12) >> 19) & 1) != 1) ;
2098         /* END JK 06.07.04: Management of sevrals boards */
2099   /**************************/
2100         /* Reset the configuration */
2101   /**************************/
2102         /* BEGIN JK 06.07.04: Management of sevrals boards */
2103         /* outl(0 , devpriv->iobase+i_Offset + 0x0); */
2104         outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
2105         /* END JK 06.07.04: Management of sevrals boards */
2106
2107         /* BEGIN JK 06.07.04: Management of sevrals boards */
2108         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2109         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2110                                         12) >> 19) & 1) != 1) ;
2111         /* END JK 06.07.04: Management of sevrals boards */
2112
2113   /***************************/
2114         /* Write the configuration */
2115   /***************************/
2116         /* BEGIN JK 06.07.04: Management of sevrals boards */
2117         /* outl(ul_Config , devpriv->iobase+i_Offset + 0x0); */
2118         outl(ul_Config,
2119                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
2120         /* END JK 06.07.04: Management of sevrals boards */
2121
2122   /***************************/
2123         /*Reset the calibration bit */
2124   /***************************/
2125         /* BEGIN JK 06.07.04: Management of sevrals boards */
2126         /* ul_Temp = inl(devpriv->iobase+i_Offset + 12); */
2127         ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
2128         /* END JK 06.07.04: Management of sevrals boards */
2129
2130         /* BEGIN JK 06.07.04: Management of sevrals boards */
2131         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2132         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2133                                         12) >> 19) & 1) != 1) ;
2134         /* END JK 06.07.04: Management of sevrals boards */
2135
2136         /* BEGIN JK 06.07.04: Management of sevrals boards */
2137         /* outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12); */
2138         outl((ul_Temp & 0xFFF9FFFF),
2139                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
2140         /* END JK 06.07.04: Management of sevrals boards */
2141
2142         if (data[9] == 1) {
2143                 devpriv->tsk_Current = current;
2144                 /* BEGIN JK 06.07.04: Management of sevrals boards */
2145                 /* i_InterruptFlag=1; */
2146                 s_BoardInfos[dev->minor].i_InterruptFlag = 1;
2147                 /* END JK 06.07.04: Management of sevrals boards */
2148         }                       /*  if(data[9]==1) */
2149         else {
2150                 /* BEGIN JK 06.07.04: Management of sevrals boards */
2151                 /* i_InterruptFlag=0; */
2152                 s_BoardInfos[dev->minor].i_InterruptFlag = 0;
2153                 /* END JK 06.07.04: Management of sevrals boards */
2154         }                       /* else  if(data[9]==1) */
2155
2156         /* BEGIN JK 06.07.04: Management of sevrals boards */
2157         /* i_Initialised=1; */
2158         s_BoardInfos[dev->minor].i_Initialised = 1;
2159         /* END JK 06.07.04: Management of sevrals boards */
2160
2161         /* BEGIN JK 06.07.04: Management of sevrals boards */
2162         /* if(i_ScanType==1) */
2163         if (s_BoardInfos[dev->minor].i_ScanType == 1)
2164                 /* END JK 06.07.04: Management of sevrals boards */
2165         {
2166                 /* BEGIN JK 06.07.04: Management of sevrals boards */
2167                 /* i_Sum=i_Sum+1; */
2168                 s_BoardInfos[dev->minor].i_Sum =
2169                         s_BoardInfos[dev->minor].i_Sum + 1;
2170                 /* END JK 06.07.04: Management of sevrals boards */
2171
2172                 insn->unused[0] = 0;
2173                 i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy);
2174         }
2175
2176         return insn->n;
2177 }
2178
2179 /*
2180  * Tests the Selected Anlog Input Channel
2181  *
2182  * data[0] = 0  TestAnalogInputShortCircuit
2183  *         = 1  TestAnalogInputConnection
2184  *
2185  * data[0] : Digital value obtained
2186  * data[1] : calibration offset
2187  * data[2] : calibration gain
2188  */
2189 static int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
2190                                                 struct comedi_subdevice *s,
2191                                                 struct comedi_insn *insn,
2192                                                 unsigned int *data)
2193 {
2194         struct addi_private *devpriv = dev->private;
2195         unsigned int ui_Configuration = 0;
2196         int i_Temp;             /* ,i_TimeUnit; */
2197
2198         /* if(i_Initialised==0) */
2199
2200         if (s_BoardInfos[dev->minor].i_Initialised == 0) {
2201                 i_APCI3200_Reset(dev);
2202                 return -EINVAL;
2203         }                       /* if(i_Initialised==0); */
2204         if (data[0] != 0 && data[0] != 1) {
2205                 printk("\nError in selection of functionality\n");
2206                 i_APCI3200_Reset(dev);
2207                 return -EINVAL;
2208         }                       /* if(data[0]!=0 && data[0]!=1) */
2209
2210         if (data[0] == 1)       /* Perform Short Circuit TEST */
2211         {
2212       /**************************/
2213                 /*Set the short-cicuit bit */
2214       /**************************/
2215                 /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2216                 while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
2217                                                 i_Offset + 12) >> 19) & 1) !=
2218                         1) ;
2219                 /* outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4); */
2220                 outl((0x00001000 | s_BoardInfos[dev->minor].i_ChannelNo),
2221                         devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2222                         4);
2223       /*************************/
2224                 /*Set the time unit to ns */
2225       /*************************/
2226                 /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
2227                    i_ADDIDATAConversionTimeUnit= 1; */
2228                 /* i_Temp= i_InterruptFlag ; */
2229                 i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
2230                 /* i_InterruptFlag = ADDIDATA_DISABLE; */
2231                 s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
2232                 i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
2233                 /* if(i_AutoCalibration == FALSE) */
2234                 if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
2235                         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2236                         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
2237                                                         i_Offset +
2238                                                         12) >> 19) & 1) != 1) ;
2239
2240                         /* outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4); */
2241                         outl((0x00001000 | s_BoardInfos[dev->minor].
2242                                         i_ChannelNo),
2243                                 devpriv->iobase +
2244                                 s_BoardInfos[dev->minor].i_Offset + 4);
2245                         data++;
2246                         i_APCI3200_ReadCalibrationOffsetValue(dev, data);
2247                         data++;
2248                         i_APCI3200_ReadCalibrationGainValue(dev, data);
2249                 }
2250         } else {
2251                 /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2252                 while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
2253                                                 i_Offset + 12) >> 19) & 1) !=
2254                         1) ;
2255                 /* outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4); */
2256                 outl((0x00000800 | s_BoardInfos[dev->minor].i_ChannelNo),
2257                         devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2258                         4);
2259                 /* ui_Configuration = inl(devpriv->iobase+i_Offset + 0); */
2260                 ui_Configuration =
2261                         inl(devpriv->iobase +
2262                         s_BoardInfos[dev->minor].i_Offset + 0);
2263       /*************************/
2264                 /*Set the time unit to ns */
2265       /*************************/
2266                 /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
2267                    i_ADDIDATAConversionTimeUnit= 1; */
2268                 /* i_Temp= i_InterruptFlag ; */
2269                 i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
2270                 /* i_InterruptFlag = ADDIDATA_DISABLE; */
2271                 s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
2272                 i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
2273                 /* if(i_AutoCalibration == FALSE) */
2274                 if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
2275                         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2276                         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
2277                                                         i_Offset +
2278                                                         12) >> 19) & 1) != 1) ;
2279                         /* outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4); */
2280                         outl((0x00000800 | s_BoardInfos[dev->minor].
2281                                         i_ChannelNo),
2282                                 devpriv->iobase +
2283                                 s_BoardInfos[dev->minor].i_Offset + 4);
2284                         data++;
2285                         i_APCI3200_ReadCalibrationOffsetValue(dev, data);
2286                         data++;
2287                         i_APCI3200_ReadCalibrationGainValue(dev, data);
2288                 }
2289         }
2290         /* i_InterruptFlag=i_Temp ; */
2291         s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp;
2292         /* printk("\ni_InterruptFlag=%d\n",i_InterruptFlag); */
2293         return insn->n;
2294 }
2295
2296 static int i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev,
2297                                                   struct comedi_subdevice *s,
2298                                                   struct comedi_insn *insn,
2299                                                   unsigned int *data)
2300 {
2301         i_APCI3200_Reset(dev);
2302         return insn->n;
2303 }
2304
2305 static int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev,
2306                                              struct comedi_subdevice *s,
2307                                              struct comedi_cmd *cmd)
2308 {
2309
2310         int err = 0;
2311         unsigned int ui_ConvertTime = 0;
2312         unsigned int ui_ConvertTimeBase = 0;
2313         unsigned int ui_DelayTime = 0;
2314         unsigned int ui_DelayTimeBase = 0;
2315         int i_Triggermode = 0;
2316         int i_TriggerEdge = 0;
2317         int i_NbrOfChannel = 0;
2318         int i_Cpt = 0;
2319         double d_ConversionTimeForAllChannels = 0.0;
2320         double d_SCANTimeNewUnit = 0.0;
2321
2322         /* Step 1 : check if triggers are trivially valid */
2323
2324         err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
2325         err |= cfc_check_trigger_src(&cmd->scan_begin_src,
2326                                         TRIG_TIMER | TRIG_FOLLOW);
2327         err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
2328         err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
2329         err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
2330
2331         if (s_BoardInfos[dev->minor].i_InterruptFlag == 0)
2332                 err |= -EINVAL;
2333
2334         if (err) {
2335                 i_APCI3200_Reset(dev);
2336                 return 1;
2337         }
2338
2339         /* Step 2a : make sure trigger sources are unique */
2340
2341         err |= cfc_check_trigger_is_unique(&cmd->start_src);
2342         err |= cfc_check_trigger_is_unique(&cmd->scan_begin_src);
2343         err |= cfc_check_trigger_is_unique(&cmd->stop_src);
2344
2345         /* Step 2b : and mutually compatible */
2346
2347         if (cmd->start_src == TRIG_EXT) {
2348                 i_TriggerEdge = cmd->start_arg & 0xFFFF;
2349                 i_Triggermode = cmd->start_arg >> 16;
2350                 if (i_TriggerEdge < 1 || i_TriggerEdge > 3) {
2351                         err++;
2352                         printk("\nThe trigger edge selection is in error\n");
2353                 }
2354                 if (i_Triggermode != 2) {
2355                         err++;
2356                         printk("\nThe trigger mode selection is in error\n");
2357                 }
2358         }
2359
2360         if (err) {
2361                 i_APCI3200_Reset(dev);
2362                 return 2;
2363         }
2364         /* i_FirstChannel=cmd->chanlist[0]; */
2365         s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
2366         /* i_LastChannel=cmd->chanlist[1]; */
2367         s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
2368
2369         if (cmd->convert_src == TRIG_TIMER) {
2370                 ui_ConvertTime = cmd->convert_arg & 0xFFFF;
2371                 ui_ConvertTimeBase = cmd->convert_arg >> 16;
2372                 if (ui_ConvertTime != 20 && ui_ConvertTime != 40
2373                         && ui_ConvertTime != 80 && ui_ConvertTime != 160)
2374                 {
2375                         printk("\nThe selection of conversion time reload value is in error\n");
2376                         err++;
2377                 }               /*  if (ui_ConvertTime!=20 && ui_ConvertTime!=40 && ui_ConvertTime!=80 && ui_ConvertTime!=160 ) */
2378                 if (ui_ConvertTimeBase != 2) {
2379                         printk("\nThe selection of conversion time unit  is in error\n");
2380                         err++;
2381                 }               /* if(ui_ConvertTimeBase!=2) */
2382         } else {
2383                 ui_ConvertTime = 0;
2384                 ui_ConvertTimeBase = 0;
2385         }
2386         if (cmd->scan_begin_src == TRIG_FOLLOW) {
2387                 ui_DelayTime = 0;
2388                 ui_DelayTimeBase = 0;
2389         }                       /* if(cmd->scan_begin_src==TRIG_FOLLOW) */
2390         else {
2391                 ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
2392                 ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
2393                 if (ui_DelayTimeBase != 2 && ui_DelayTimeBase != 3) {
2394                         err++;
2395                         printk("\nThe Delay time base selection is in error\n");
2396                 }
2397                 if (ui_DelayTime < 1 || ui_DelayTime > 1023) {
2398                         err++;
2399                         printk("\nThe Delay time value is in error\n");
2400                 }
2401                 if (err) {
2402                         i_APCI3200_Reset(dev);
2403                         return 3;
2404                 }
2405                 fpu_begin();
2406                 d_SCANTimeNewUnit = (double)ui_DelayTime;
2407                 /* i_NbrOfChannel= i_LastChannel-i_FirstChannel + 4; */
2408                 i_NbrOfChannel =
2409                         s_BoardInfos[dev->minor].i_LastChannel -
2410                         s_BoardInfos[dev->minor].i_FirstChannel + 4;
2411       /**********************************************************/
2412                 /*calculate the total conversion time for all the channels */
2413       /**********************************************************/
2414                 d_ConversionTimeForAllChannels =
2415                         (double)((double)ui_ConvertTime /
2416                         (double)i_NbrOfChannel);
2417
2418       /*******************************/
2419                 /*Convert the frequence in time */
2420       /*******************************/
2421                 d_ConversionTimeForAllChannels =
2422                         (double)1.0 / d_ConversionTimeForAllChannels;
2423                 ui_ConvertTimeBase = 3;
2424       /***********************************/
2425                 /*Test if the time unit is the same */
2426       /***********************************/
2427
2428                 if (ui_DelayTimeBase <= ui_ConvertTimeBase) {
2429
2430                         for (i_Cpt = 0;
2431                                 i_Cpt < (ui_ConvertTimeBase - ui_DelayTimeBase);
2432                                 i_Cpt++) {
2433
2434                                 d_ConversionTimeForAllChannels =
2435                                         d_ConversionTimeForAllChannels * 1000;
2436                                 d_ConversionTimeForAllChannels =
2437                                         d_ConversionTimeForAllChannels + 1;
2438                         }
2439                 } else {
2440                         for (i_Cpt = 0;
2441                                 i_Cpt < (ui_DelayTimeBase - ui_ConvertTimeBase);
2442                                 i_Cpt++) {
2443                                 d_SCANTimeNewUnit = d_SCANTimeNewUnit * 1000;
2444
2445                         }
2446                 }
2447
2448                 if (d_ConversionTimeForAllChannels >= d_SCANTimeNewUnit) {
2449
2450                         printk("\nSCAN Delay value cannot be used\n");
2451           /*********************************/
2452                         /*SCAN Delay value cannot be used */
2453           /*********************************/
2454                         err++;
2455                 }
2456                 fpu_end();
2457         }                       /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */
2458
2459         if (err) {
2460                 i_APCI3200_Reset(dev);
2461                 return 4;
2462         }
2463
2464         return 0;
2465 }
2466
2467 static int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,
2468                                             struct comedi_subdevice *s)
2469 {
2470         struct addi_private *devpriv = dev->private;
2471         unsigned int ui_Configuration = 0;
2472
2473         /* i_InterruptFlag=0; */
2474         /* i_Initialised=0; */
2475         /* i_Count=0; */
2476         /* i_Sum=0; */
2477         s_BoardInfos[dev->minor].i_InterruptFlag = 0;
2478         s_BoardInfos[dev->minor].i_Initialised = 0;
2479         s_BoardInfos[dev->minor].i_Count = 0;
2480         s_BoardInfos[dev->minor].i_Sum = 0;
2481
2482   /*******************/
2483         /*Read the register */
2484   /*******************/
2485         /* ui_Configuration = inl(devpriv->iobase+i_Offset + 8); */
2486         ui_Configuration =
2487                 inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2488   /*****************************/
2489         /*Reset the START and IRQ bit */
2490   /*****************************/
2491         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2492         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2493                                         12) >> 19) & 1) != 1) ;
2494         /* outl((ui_Configuration & 0xFFE7FFFF),devpriv->iobase+i_Offset + 8); */
2495         outl((ui_Configuration & 0xFFE7FFFF),
2496                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2497         return 0;
2498 }
2499
2500 /*
2501  * Does asynchronous acquisition
2502  * Determines the mode 1 or 2.
2503  */
2504 static int i_APCI3200_CommandAnalogInput(struct comedi_device *dev,
2505                                          struct comedi_subdevice *s)
2506 {
2507         struct addi_private *devpriv = dev->private;
2508         struct comedi_cmd *cmd = &s->async->cmd;
2509         unsigned int ui_Configuration = 0;
2510         /* INT  i_CurrentSource = 0; */
2511         unsigned int ui_Trigger = 0;
2512         unsigned int ui_TriggerEdge = 0;
2513         unsigned int ui_Triggermode = 0;
2514         unsigned int ui_ScanMode = 0;
2515         unsigned int ui_ConvertTime = 0;
2516         unsigned int ui_ConvertTimeBase = 0;
2517         unsigned int ui_DelayTime = 0;
2518         unsigned int ui_DelayTimeBase = 0;
2519         unsigned int ui_DelayMode = 0;
2520
2521         /* i_FirstChannel=cmd->chanlist[0]; */
2522         /* i_LastChannel=cmd->chanlist[1]; */
2523         s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
2524         s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
2525         if (cmd->start_src == TRIG_EXT) {
2526                 ui_Trigger = 1;
2527                 ui_TriggerEdge = cmd->start_arg & 0xFFFF;
2528                 ui_Triggermode = cmd->start_arg >> 16;
2529         }                       /* if(cmd->start_src==TRIG_EXT) */
2530         else {
2531                 ui_Trigger = 0;
2532         }                       /* elseif(cmd->start_src==TRIG_EXT) */
2533
2534         if (cmd->stop_src == TRIG_COUNT) {
2535                 ui_ScanMode = 0;
2536         }                       /*  if (cmd->stop_src==TRIG_COUNT) */
2537         else {
2538                 ui_ScanMode = 2;
2539         }                       /* else if (cmd->stop_src==TRIG_COUNT) */
2540
2541         if (cmd->scan_begin_src == TRIG_FOLLOW) {
2542                 ui_DelayTime = 0;
2543                 ui_DelayTimeBase = 0;
2544                 ui_DelayMode = 0;
2545         }                       /* if(cmd->scan_begin_src==TRIG_FOLLOW) */
2546         else {
2547                 ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
2548                 ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
2549                 ui_DelayMode = 1;
2550         }                       /* else if(cmd->scan_begin_src==TRIG_FOLLOW) */
2551         /*         printk("\nui_DelayTime=%u\n",ui_DelayTime); */
2552         /*         printk("\nui_DelayTimeBase=%u\n",ui_DelayTimeBase); */
2553         if (cmd->convert_src == TRIG_TIMER) {
2554                 ui_ConvertTime = cmd->convert_arg & 0xFFFF;
2555                 ui_ConvertTimeBase = cmd->convert_arg >> 16;
2556         } else {
2557                 ui_ConvertTime = 0;
2558                 ui_ConvertTimeBase = 0;
2559         }
2560
2561         /*  if(i_ADDIDATAType ==1 || ((i_ADDIDATAType==2))) */
2562         /*    { */
2563   /**************************************************/
2564         /*Read the old configuration of the current source */
2565   /**************************************************/
2566         /* ui_Configuration = inl(devpriv->iobase+i_Offset + 12); */
2567         ui_Configuration =
2568                 inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
2569   /***********************************************/
2570         /*Write the configuration of the current source */
2571   /***********************************************/
2572         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2573         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2574                                         12) >> 19) & 1) != 1) ;
2575         /* outl((ui_Configuration & 0xFFC00000 ), devpriv->iobase+i_Offset +12); */
2576         outl((ui_Configuration & 0xFFC00000),
2577                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
2578         /*  } */
2579         ui_Configuration = 0;
2580         /*      printk("\nfirstchannel=%u\n",i_FirstChannel); */
2581         /*      printk("\nlastchannel=%u\n",i_LastChannel); */
2582         /*      printk("\nui_Trigger=%u\n",ui_Trigger); */
2583         /*      printk("\nui_TriggerEdge=%u\n",ui_TriggerEdge); */
2584         /*      printk("\nui_Triggermode=%u\n",ui_Triggermode); */
2585         /*       printk("\nui_DelayMode=%u\n",ui_DelayMode); */
2586         /*      printk("\nui_ScanMode=%u\n",ui_ScanMode); */
2587
2588         /* ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 | */
2589         ui_Configuration =
2590                 s_BoardInfos[dev->minor].i_FirstChannel | (s_BoardInfos[dev->
2591                         minor].
2592                 i_LastChannel << 8) | 0x00100000 | (ui_Trigger << 24) |
2593                 (ui_TriggerEdge << 25) | (ui_Triggermode << 27) | (ui_DelayMode
2594                 << 18) | (ui_ScanMode << 16);
2595
2596   /*************************/
2597         /*Write the Configuration */
2598   /*************************/
2599         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2600         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2601                                         12) >> 19) & 1) != 1) ;
2602         /* outl( ui_Configuration, devpriv->iobase+i_Offset + 0x8); */
2603         outl(ui_Configuration,
2604                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x8);
2605   /***********************/
2606         /*Write the Delay Value */
2607   /***********************/
2608         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2609         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2610                                         12) >> 19) & 1) != 1) ;
2611         /* outl(ui_DelayTime,devpriv->iobase+i_Offset + 40); */
2612         outl(ui_DelayTime,
2613                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 40);
2614   /***************************/
2615         /*Write the Delay time base */
2616   /***************************/
2617         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2618         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2619                                         12) >> 19) & 1) != 1) ;
2620         /* outl(ui_DelayTimeBase,devpriv->iobase+i_Offset + 44); */
2621         outl(ui_DelayTimeBase,
2622                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 44);
2623   /*********************************/
2624         /*Write the conversion time value */
2625   /*********************************/
2626         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2627         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2628                                         12) >> 19) & 1) != 1) ;
2629         /* outl(ui_ConvertTime,devpriv->iobase+i_Offset + 32); */
2630         outl(ui_ConvertTime,
2631                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
2632
2633   /********************************/
2634         /*Write the conversion time base */
2635   /********************************/
2636         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2637         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2638                                         12) >> 19) & 1) != 1) ;
2639         /* outl(ui_ConvertTimeBase,devpriv->iobase+i_Offset + 36); */
2640         outl(ui_ConvertTimeBase,
2641                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
2642   /*******************/
2643         /*Read the register */
2644   /*******************/
2645         /* ui_Configuration = inl(devpriv->iobase+i_Offset + 4); */
2646         ui_Configuration =
2647                 inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
2648   /******************/
2649         /*Set the SCAN bit */
2650   /******************/
2651         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2652         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2653                                         12) >> 19) & 1) != 1) ;
2654
2655         /* outl(((ui_Configuration & 0x1E0FF) | 0x00002000),devpriv->iobase+i_Offset + 4); */
2656         outl(((ui_Configuration & 0x1E0FF) | 0x00002000),
2657                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
2658   /*******************/
2659         /*Read the register */
2660   /*******************/
2661         ui_Configuration = 0;
2662         /* ui_Configuration = inl(devpriv->iobase+i_Offset + 8); */
2663         ui_Configuration =
2664                 inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2665
2666   /*******************/
2667         /*Set the START bit */
2668   /*******************/
2669         /* while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1); */
2670         while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
2671                                         12) >> 19) & 1) != 1) ;
2672         /* outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8); */
2673         outl((ui_Configuration | 0x00080000),
2674                 devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
2675         return 0;
2676 }
2677
2678 /*
2679  * This function copies the acquired data(from FIFO) to Comedi buffer.
2680  */
2681 static int i_APCI3200_InterruptHandleEos(struct comedi_device *dev)
2682 {
2683         struct addi_private *devpriv = dev->private;
2684         unsigned int ui_StatusRegister = 0;
2685         struct comedi_subdevice *s = &dev->subdevices[0];
2686
2687         /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2688         /* comedi_async *async = s->async; */
2689         /* UINT *data; */
2690         /* data=async->data+async->buf_int_ptr;//new samples added from here onwards */
2691         int n = 0, i = 0;
2692         /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2693
2694   /************************************/
2695         /*Read the interrupt status register */
2696   /************************************/
2697         /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */
2698         ui_StatusRegister =
2699                 inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16);
2700
2701   /*************************/
2702         /*Test if interrupt occur */
2703   /*************************/
2704
2705         if ((ui_StatusRegister & 0x2) == 0x2) {
2706       /*************************/
2707                 /*Read the channel number */
2708       /*************************/
2709                 /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */
2710                 /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2711                 /* This value is not used */
2712                 /* ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24); */
2713                 s->async->events = 0;
2714                 /* END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2715
2716       /*************************************/
2717                 /*Read the digital Analog Input value */
2718       /*************************************/
2719
2720                 /* data[i_Count] = inl(devpriv->iobase+i_Offset + 28); */
2721                 /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2722                 /* data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28); */
2723                 s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev->
2724                                 minor].i_Count] =
2725                         inl(devpriv->iobase +
2726                         s_BoardInfos[dev->minor].i_Offset + 28);
2727                 /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2728
2729                 /* if((i_Count == (i_LastChannel-i_FirstChannel+3))) */
2730                 if ((s_BoardInfos[dev->minor].i_Count ==
2731                                 (s_BoardInfos[dev->minor].i_LastChannel -
2732                                         s_BoardInfos[dev->minor].
2733                                         i_FirstChannel + 3))) {
2734
2735                         /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
2736                         s_BoardInfos[dev->minor].i_Count++;
2737
2738                         for (i = s_BoardInfos[dev->minor].i_FirstChannel;
2739                                 i <= s_BoardInfos[dev->minor].i_LastChannel;
2740                                 i++) {
2741                                 i_APCI3200_GetChannelCalibrationValue(dev, i,
2742                                         &s_BoardInfos[dev->minor].
2743                                         ui_ScanValueArray[s_BoardInfos[dev->
2744                                                         minor].i_Count + ((i -
2745                                                                 s_BoardInfos
2746                                                                 [dev->minor].
2747                                                                 i_FirstChannel)
2748                                                         * 3)],
2749                                         &s_BoardInfos[dev->minor].
2750                                         ui_ScanValueArray[s_BoardInfos[dev->
2751                                                         minor].i_Count + ((i -
2752                                                                 s_BoardInfos
2753                                                                 [dev->minor].
2754                                                                 i_FirstChannel)
2755                                                         * 3) + 1],
2756                                         &s_BoardInfos[dev->minor].
2757                                         ui_ScanValueArray[s_BoardInfos[dev->
2758                                                         minor].i_Count + ((i -
2759                                                                 s_BoardInfos
2760                                                                 [dev->minor].
2761                                                                 i_FirstChannel)
2762                                                         * 3) + 2]);
2763                         }
2764
2765                         /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
2766
2767                         /* i_Count=-1; */
2768
2769                         s_BoardInfos[dev->minor].i_Count = -1;
2770
2771                         /* async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */
2772                         /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2773                         /* async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */
2774                         /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2775                         /* async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(unsigned int); */
2776                         /* Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2777                         /* async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(unsigned int); */
2778                         /* comedi_eos(dev,s); */
2779
2780                         /*  Set the event type (Comedi Buffer End Of Scan) */
2781                         s->async->events |= COMEDI_CB_EOS;
2782
2783                         /*  Test if enougth memory is available and allocate it for 7 values */
2784                         /* n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int)); */
2785                         n = comedi_buf_write_alloc(s->async,
2786                                 (7 + 12) * sizeof(unsigned int));
2787
2788                         /*  If not enough memory available, event is set to Comedi Buffer Error */
2789                         if (n > ((7 + 12) * sizeof(unsigned int))) {
2790                                 printk("\ncomedi_buf_write_alloc n = %i", n);
2791                                 s->async->events |= COMEDI_CB_ERROR;
2792                         }
2793                         /*  Write all 7 scan values in the comedi buffer */
2794                         comedi_buf_memcpy_to(s->async, 0,
2795                                 (unsigned int *) s_BoardInfos[dev->minor].
2796                                 ui_ScanValueArray, (7 + 12) * sizeof(unsigned int));
2797
2798                         /*  Update comedi buffer pinters indexes */
2799                         comedi_buf_write_free(s->async,
2800                                 (7 + 12) * sizeof(unsigned int));
2801
2802                         /*  Send events */
2803                         comedi_event(dev, s);
2804                         /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2805
2806                         /* BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2807                         /*  */
2808                         /* if (s->async->buf_int_ptr>=s->async->data_len) //  for buffer rool over */
2809                         /*   { */
2810                         /*     /* buffer rollover */ */
2811                         /*     s->async->buf_int_ptr=0; */
2812                         /*     comedi_eobuf(dev,s); */
2813                         /*   } */
2814                         /* End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68 */
2815                 }
2816                 /* i_Count++; */
2817                 s_BoardInfos[dev->minor].i_Count++;
2818         }
2819         /* i_InterruptFlag=0; */
2820         s_BoardInfos[dev->minor].i_InterruptFlag = 0;
2821         return 0;
2822 }
2823
2824 static void v_APCI3200_Interrupt(int irq, void *d)
2825 {
2826         struct comedi_device *dev = d;
2827         struct addi_private *devpriv = dev->private;
2828         unsigned int ui_StatusRegister = 0;
2829         unsigned int ui_ChannelNumber = 0;
2830         int i_CalibrationFlag = 0;
2831         int i_CJCFlag = 0;
2832         unsigned int ui_DummyValue = 0;
2833         unsigned int ui_DigitalTemperature = 0;
2834         unsigned int ui_DigitalInput = 0;
2835         int i_ConvertCJCCalibration;
2836         /* BEGIN JK TEST */
2837         int i_ReturnValue = 0;
2838         /* END JK TEST */
2839
2840         /* printk ("\n i_ScanType = %i i_ADDIDATAType = %i", s_BoardInfos [dev->minor].i_ScanType, s_BoardInfos [dev->minor].i_ADDIDATAType); */
2841
2842         /* switch(i_ScanType) */
2843         switch (s_BoardInfos[dev->minor].i_ScanType) {
2844         case 0:
2845         case 1:
2846                 /* switch(i_ADDIDATAType) */
2847                 switch (s_BoardInfos[dev->minor].i_ADDIDATAType) {
2848                 case 0:
2849                 case 1:
2850
2851           /************************************/
2852                         /*Read the interrupt status register */
2853           /************************************/
2854                         /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */
2855                         ui_StatusRegister =
2856                                 inl(devpriv->iobase +
2857                                 s_BoardInfos[dev->minor].i_Offset + 16);
2858                         if ((ui_StatusRegister & 0x2) == 0x2) {
2859                                 /* i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17); */
2860                                 i_CalibrationFlag =
2861                                         ((inl(devpriv->iobase +
2862                                                         s_BoardInfos[dev->
2863                                                                 minor].
2864                                                         i_Offset +
2865                                                         12) & 0x00060000) >>
2866                                         17);
2867               /*************************/
2868                                 /*Read the channel number */
2869               /*************************/
2870                                 /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */
2871
2872               /*************************************/
2873                                 /*Read the digital analog input value */
2874               /*************************************/
2875                                 /* ui_DigitalInput = inl(devpriv->iobase+i_Offset + 28); */
2876                                 ui_DigitalInput =
2877                                         inl(devpriv->iobase +
2878                                         s_BoardInfos[dev->minor].i_Offset + 28);
2879
2880               /***********************************************/
2881                                 /* Test if the value read is the channel value */
2882               /***********************************************/
2883                                 if (i_CalibrationFlag == 0) {
2884                                         /* ui_InterruptChannelValue[i_Count + 0] = ui_DigitalInput; */
2885                                         s_BoardInfos[dev->minor].
2886                                                 ui_InterruptChannelValue
2887                                                 [s_BoardInfos[dev->minor].
2888                                                 i_Count + 0] = ui_DigitalInput;
2889
2890                                         /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
2891                                         /*
2892                                            printk("\n 1 - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos %i", ui_ChannelNumber);
2893                                            i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num,
2894                                            &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6],
2895                                            &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7],
2896                                            &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 8]);
2897                                          */
2898                                         /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
2899
2900                   /******************************************************/
2901                                         /*Start the conversion of the calibration offset value */
2902                   /******************************************************/
2903                                         i_APCI3200_ReadCalibrationOffsetValue
2904                                                 (dev, &ui_DummyValue);
2905                                 }       /* if (i_CalibrationFlag == 0) */
2906               /**********************************************************/
2907                                 /* Test if the value read is the calibration offset value */
2908               /**********************************************************/
2909
2910                                 if (i_CalibrationFlag == 1) {
2911
2912                   /******************/
2913                                         /* Save the value */
2914                   /******************/
2915
2916                                         /* ui_InterruptChannelValue[i_Count + 1] = ui_DigitalInput; */
2917                                         s_BoardInfos[dev->minor].
2918                                                 ui_InterruptChannelValue
2919                                                 [s_BoardInfos[dev->minor].
2920                                                 i_Count + 1] = ui_DigitalInput;
2921
2922                   /******************************************************/
2923                                         /* Start the conversion of the calibration gain value */
2924                   /******************************************************/
2925                                         i_APCI3200_ReadCalibrationGainValue(dev,
2926                                                 &ui_DummyValue);
2927                                 }       /* if (i_CalibrationFlag == 1) */
2928               /******************************************************/
2929                                 /*Test if the value read is the calibration gain value */
2930               /******************************************************/
2931
2932                                 if (i_CalibrationFlag == 2) {
2933
2934                   /****************/
2935                                         /*Save the value */
2936                   /****************/
2937                                         /* ui_InterruptChannelValue[i_Count + 2] = ui_DigitalInput; */
2938                                         s_BoardInfos[dev->minor].
2939                                                 ui_InterruptChannelValue
2940                                                 [s_BoardInfos[dev->minor].
2941                                                 i_Count + 2] = ui_DigitalInput;
2942                                         /* if(i_ScanType==1) */
2943                                         if (s_BoardInfos[dev->minor].
2944                                                 i_ScanType == 1) {
2945
2946                                                 /* i_InterruptFlag=0; */
2947                                                 s_BoardInfos[dev->minor].
2948                                                         i_InterruptFlag = 0;
2949                                                 /* i_Count=i_Count + 6; */
2950                                                 /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
2951                                                 /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6; */
2952                                                 s_BoardInfos[dev->minor].
2953                                                         i_Count =
2954                                                         s_BoardInfos[dev->
2955                                                         minor].i_Count + 9;
2956                                                 /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
2957                                         }       /* if(i_ScanType==1) */
2958                                         else {
2959                                                 /* i_Count=0; */
2960                                                 s_BoardInfos[dev->minor].
2961                                                         i_Count = 0;
2962                                         }       /* elseif(i_ScanType==1) */
2963                                         /* if(i_ScanType!=1) */
2964                                         if (s_BoardInfos[dev->minor].
2965                                                 i_ScanType != 1) {
2966                                                 i_ReturnValue = send_sig(SIGIO, devpriv->tsk_Current, 0);       /*  send signal to the sample */
2967                                         }       /* if(i_ScanType!=1) */
2968                                         else {
2969                                                 /* if(i_ChannelCount==i_Sum) */
2970                                                 if (s_BoardInfos[dev->minor].
2971                                                         i_ChannelCount ==
2972                                                         s_BoardInfos[dev->
2973                                                                 minor].i_Sum) {
2974                                                         send_sig(SIGIO, devpriv->tsk_Current, 0);       /*  send signal to the sample */
2975                                                 }
2976                                         }       /* if(i_ScanType!=1) */
2977                                 }       /* if (i_CalibrationFlag == 2) */
2978                         }       /*  if ((ui_StatusRegister & 0x2) == 0x2) */
2979
2980                         break;
2981
2982                 case 2:
2983           /************************************/
2984                         /*Read the interrupt status register */
2985           /************************************/
2986
2987                         /* ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16); */
2988                         ui_StatusRegister =
2989                                 inl(devpriv->iobase +
2990                                 s_BoardInfos[dev->minor].i_Offset + 16);
2991           /*************************/
2992                         /*Test if interrupt occur */
2993           /*************************/
2994
2995                         if ((ui_StatusRegister & 0x2) == 0x2) {
2996
2997                                 /* i_CJCFlag = ((inl(devpriv->iobase+i_Offset + 4) & 0x00000400) >> 10); */
2998                                 i_CJCFlag =
2999                                         ((inl(devpriv->iobase +
3000                                                         s_BoardInfos[dev->
3001                                                                 minor].
3002                                                         i_Offset +
3003                                                         4) & 0x00000400) >> 10);
3004
3005                                 /* i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17); */
3006                                 i_CalibrationFlag =
3007                                         ((inl(devpriv->iobase +
3008                                                         s_BoardInfos[dev->
3009                                                                 minor].
3010                                                         i_Offset +
3011                                                         12) & 0x00060000) >>
3012                                         17);
3013
3014               /*************************/
3015                                 /*Read the channel number */
3016               /*************************/
3017
3018                                 /* ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24); */
3019                                 ui_ChannelNumber =
3020                                         inl(devpriv->iobase +
3021                                         s_BoardInfos[dev->minor].i_Offset + 24);
3022                                 /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3023                                 s_BoardInfos[dev->minor].ui_Channel_num =
3024                                         ui_ChannelNumber;
3025                                 /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3026
3027               /************************************/
3028                                 /*Read the digital temperature value */
3029               /************************************/
3030                                 /* ui_DigitalTemperature = inl(devpriv->iobase+i_Offset + 28); */
3031                                 ui_DigitalTemperature =
3032                                         inl(devpriv->iobase +
3033                                         s_BoardInfos[dev->minor].i_Offset + 28);
3034
3035               /*********************************************/
3036                                 /*Test if the value read is the channel value */
3037               /*********************************************/
3038
3039                                 if ((i_CalibrationFlag == 0)
3040                                         && (i_CJCFlag == 0)) {
3041                                         /* ui_InterruptChannelValue[i_Count + 0]=ui_DigitalTemperature; */
3042                                         s_BoardInfos[dev->minor].
3043                                                 ui_InterruptChannelValue
3044                                                 [s_BoardInfos[dev->minor].
3045                                                 i_Count + 0] =
3046                                                 ui_DigitalTemperature;
3047
3048                   /*********************************/
3049                                         /*Start the conversion of the CJC */
3050                   /*********************************/
3051                                         i_APCI3200_ReadCJCValue(dev,
3052                                                 &ui_DummyValue);
3053
3054                                 }       /* if ((i_CalibrationFlag == 0) && (i_CJCFlag == 0)) */
3055
3056                  /*****************************************/
3057                                 /*Test if the value read is the CJC value */
3058                  /*****************************************/
3059
3060                                 if ((i_CJCFlag == 1)
3061                                         && (i_CalibrationFlag == 0)) {
3062                                         /* ui_InterruptChannelValue[i_Count + 3]=ui_DigitalTemperature; */
3063                                         s_BoardInfos[dev->minor].
3064                                                 ui_InterruptChannelValue
3065                                                 [s_BoardInfos[dev->minor].
3066                                                 i_Count + 3] =
3067                                                 ui_DigitalTemperature;
3068
3069                   /******************************************************/
3070                                         /*Start the conversion of the calibration offset value */
3071                   /******************************************************/
3072                                         i_APCI3200_ReadCalibrationOffsetValue
3073                                                 (dev, &ui_DummyValue);
3074                                 }       /*  if ((i_CJCFlag == 1) && (i_CalibrationFlag == 0)) */
3075
3076                  /********************************************************/
3077                                 /*Test if the value read is the calibration offset value */
3078                  /********************************************************/
3079
3080                                 if ((i_CalibrationFlag == 1)
3081                                         && (i_CJCFlag == 0)) {
3082                                         /* ui_InterruptChannelValue[i_Count + 1]=ui_DigitalTemperature; */
3083                                         s_BoardInfos[dev->minor].
3084                                                 ui_InterruptChannelValue
3085                                                 [s_BoardInfos[dev->minor].
3086                                                 i_Count + 1] =
3087                                                 ui_DigitalTemperature;
3088
3089                   /****************************************************/
3090                                         /*Start the conversion of the calibration gain value */
3091                   /****************************************************/
3092                                         i_APCI3200_ReadCalibrationGainValue(dev,
3093                                                 &ui_DummyValue);
3094
3095                                 }       /* if ((i_CalibrationFlag == 1) && (i_CJCFlag == 0)) */
3096
3097               /******************************************************/
3098                                 /*Test if the value read is the calibration gain value */
3099               /******************************************************/
3100
3101                                 if ((i_CalibrationFlag == 2)
3102                                         && (i_CJCFlag == 0)) {
3103                                         /* ui_InterruptChannelValue[i_Count + 2]=ui_DigitalTemperature; */
3104                                         s_BoardInfos[dev->minor].
3105                                                 ui_InterruptChannelValue
3106                                                 [s_BoardInfos[dev->minor].
3107                                                 i_Count + 2] =
3108                                                 ui_DigitalTemperature;
3109
3110                   /**********************************************************/
3111                                         /*Test if the Calibration channel must be read for the CJC */
3112                   /**********************************************************/
3113
3114                                         /*Test if the polarity is the same */
3115                   /**********************************/
3116                                         /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
3117                                         if (s_BoardInfos[dev->minor].
3118                                                 i_CJCPolarity !=
3119                                                 s_BoardInfos[dev->minor].
3120                                                 i_ADDIDATAPolarity) {
3121                                                 i_ConvertCJCCalibration = 1;
3122                                         }       /* if(i_CJCPolarity!=i_ADDIDATAPolarity) */
3123                                         else {
3124                                                 /* if(i_CJCGain==i_ADDIDATAGain) */
3125                                                 if (s_BoardInfos[dev->minor].
3126                                                         i_CJCGain ==
3127                                                         s_BoardInfos[dev->
3128                                                                 minor].
3129                                                         i_ADDIDATAGain) {
3130                                                         i_ConvertCJCCalibration
3131                                                                 = 0;
3132                                                 }       /* if(i_CJCGain==i_ADDIDATAGain) */
3133                                                 else {
3134                                                         i_ConvertCJCCalibration
3135                                                                 = 1;
3136                                                 }       /* elseif(i_CJCGain==i_ADDIDATAGain) */
3137                                         }       /* elseif(i_CJCPolarity!=i_ADDIDATAPolarity) */
3138                                         if (i_ConvertCJCCalibration == 1) {
3139                       /****************************************************************/
3140                                                 /*Start the conversion of the calibration gain value for the CJC */
3141                       /****************************************************************/
3142                                                 i_APCI3200_ReadCJCCalOffset(dev,
3143                                                         &ui_DummyValue);
3144
3145                                         }       /* if(i_ConvertCJCCalibration==1) */
3146                                         else {
3147                                                 /* ui_InterruptChannelValue[i_Count + 4]=0; */
3148                                                 /* ui_InterruptChannelValue[i_Count + 5]=0; */
3149                                                 s_BoardInfos[dev->minor].
3150                                                         ui_InterruptChannelValue
3151                                                         [s_BoardInfos[dev->
3152                                                                 minor].i_Count +
3153                                                         4] = 0;
3154                                                 s_BoardInfos[dev->minor].
3155                                                         ui_InterruptChannelValue
3156                                                         [s_BoardInfos[dev->
3157                                                                 minor].i_Count +
3158                                                         5] = 0;
3159                                         }       /* elseif(i_ConvertCJCCalibration==1) */
3160                                 }       /* else if ((i_CalibrationFlag == 2) && (i_CJCFlag == 0)) */
3161
3162                  /********************************************************************/
3163                                 /*Test if the value read is the calibration offset value for the CJC */
3164                  /********************************************************************/
3165
3166                                 if ((i_CalibrationFlag == 1)
3167                                         && (i_CJCFlag == 1)) {
3168                                         /* ui_InterruptChannelValue[i_Count + 4]=ui_DigitalTemperature; */
3169                                         s_BoardInfos[dev->minor].
3170                                                 ui_InterruptChannelValue
3171                                                 [s_BoardInfos[dev->minor].
3172                                                 i_Count + 4] =
3173                                                 ui_DigitalTemperature;
3174
3175                   /****************************************************************/
3176                                         /*Start the conversion of the calibration gain value for the CJC */
3177                   /****************************************************************/
3178                                         i_APCI3200_ReadCJCCalGain(dev,
3179                                                 &ui_DummyValue);
3180
3181                                 }       /* if ((i_CalibrationFlag == 1) && (i_CJCFlag == 1)) */
3182
3183               /******************************************************************/
3184                                 /*Test if the value read is the calibration gain value for the CJC */
3185               /******************************************************************/
3186
3187                                 if ((i_CalibrationFlag == 2)
3188                                         && (i_CJCFlag == 1)) {
3189                                         /* ui_InterruptChannelValue[i_Count + 5]=ui_DigitalTemperature; */
3190                                         s_BoardInfos[dev->minor].
3191                                                 ui_InterruptChannelValue
3192                                                 [s_BoardInfos[dev->minor].
3193                                                 i_Count + 5] =
3194                                                 ui_DigitalTemperature;
3195
3196                                         /* if(i_ScanType==1) */
3197                                         if (s_BoardInfos[dev->minor].
3198                                                 i_ScanType == 1) {
3199
3200                                                 /* i_InterruptFlag=0; */
3201                                                 s_BoardInfos[dev->minor].
3202                                                         i_InterruptFlag = 0;
3203                                                 /* i_Count=i_Count + 6; */
3204                                                 /* Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3205                                                 /* s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6; */
3206                                                 s_BoardInfos[dev->minor].
3207                                                         i_Count =
3208                                                         s_BoardInfos[dev->
3209                                                         minor].i_Count + 9;
3210                                                 /* End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
3211                                         }       /* if(i_ScanType==1) */
3212                                         else {
3213                                                 /* i_Count=0; */
3214                                                 s_BoardInfos[dev->minor].
3215                                                         i_Count = 0;
3216                                         }       /* elseif(i_ScanType==1) */
3217
3218                                         /* if(i_ScanType!=1) */
3219                                         if (s_BoardInfos[dev->minor].
3220                                                 i_ScanType != 1) {
3221                                                 send_sig(SIGIO, devpriv->tsk_Current, 0);       /*  send signal to the sample */
3222                                         }       /* if(i_ScanType!=1) */
3223                                         else {
3224                                                 /* if(i_ChannelCount==i_Sum) */
3225                                                 if (s_BoardInfos[dev->minor].
3226                                                         i_ChannelCount ==
3227                                                         s_BoardInfos[dev->
3228                                                                 minor].i_Sum) {
3229                                                         send_sig(SIGIO, devpriv->tsk_Current, 0);       /*  send signal to the sample */
3230
3231                                                 }       /* if(i_ChannelCount==i_Sum) */
3232                                         }       /* else if(i_ScanType!=1) */
3233                                 }       /* if ((i_CalibrationFlag == 2) && (i_CJCFlag == 1)) */
3234
3235                         }       /* else if ((ui_StatusRegister & 0x2) == 0x2) */
3236                         break;
3237                 }               /* switch(i_ADDIDATAType) */
3238                 break;
3239         case 2:
3240         case 3:
3241                 i_APCI3200_InterruptHandleEos(dev);
3242                 break;
3243         }                       /* switch(i_ScanType) */
3244         return;
3245 }