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