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