hwdrv_apci3200.c revision dae0dc30be7fa21b15a9d9534589286c6c3e68a3
1/**
2@verbatim
3
4Copyright (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
14This 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
16This 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
18You 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
20You 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  unsigned int ui_Channel_num=0;
86  static int i_Count=0;
87  int i_Initialised=0;
88  unsigned int ui_InterruptChannelValue[96]; /* Buffer */
89*/
90struct str_BoardInfos s_BoardInfos[100];	/*  100 will be the max number of boards to be used */
91/* END JK 06.07.04: Management of sevrals boards */
92
93/* Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values */
94
95/*+----------------------------------------------------------------------------+*/
96/*| Function   Name   : int i_AddiHeaderRW_ReadEeprom                          |*/
97/*|                               (int    i_NbOfWordsToRead,                   |*/
98/*|                                unsigned int dw_PCIBoardEepromAddress,             |*/
99/*|                                unsigned short   w_EepromStartAddress,                |*/
100/*|                                unsigned short * pw_DataRead)                          |*/
101/*+----------------------------------------------------------------------------+*/
102/*| Task              : Read word from the 5920 eeprom.                        |*/
103/*+----------------------------------------------------------------------------+*/
104/*| Input Parameters  : int    i_NbOfWordsToRead : Nbr. of word to read        |*/
105/*|                     unsigned int dw_PCIBoardEepromAddress : Address of the eeprom |*/
106/*|                     unsigned short   w_EepromStartAddress : Eeprom strat address     |*/
107/*+----------------------------------------------------------------------------+*/
108/*| Output Parameters : unsigned short * pw_DataRead : Read data                          |*/
109/*+----------------------------------------------------------------------------+*/
110/*| Return Value      : -                                                      |*/
111/*+----------------------------------------------------------------------------+*/
112
113int i_AddiHeaderRW_ReadEeprom(int i_NbOfWordsToRead,
114	unsigned int dw_PCIBoardEepromAddress,
115	unsigned short w_EepromStartAddress, unsigned short *pw_DataRead)
116{
117	unsigned int dw_eeprom_busy = 0;
118	int i_Counter = 0;
119	int i_WordCounter;
120	int i;
121	unsigned char pb_ReadByte[1];
122	unsigned char b_ReadLowByte = 0;
123	unsigned char b_ReadHighByte = 0;
124	unsigned char b_SelectedAddressLow = 0;
125	unsigned char b_SelectedAddressHigh = 0;
126	unsigned short w_ReadWord = 0;
127
128	for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
129		i_WordCounter++) {
130		do {
131			dw_eeprom_busy =
132				inl(dw_PCIBoardEepromAddress +
133				AMCC_OP_REG_MCSR);
134			dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
135		}
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
261void v_GetAPCI3200EepromCalibrationValue(unsigned int dw_PCIBoardEepromAddress,
262	struct str_BoardInfos *BoardInformations)
263{
264	unsigned short w_AnalogInputMainHeaderAddress;
265	unsigned short w_AnalogInputComponentAddress;
266	unsigned short w_NumberOfModuls = 0;
267	unsigned short w_CurrentSources[2];
268	unsigned short w_ModulCounter = 0;
269	unsigned short w_FirstHeaderSize = 0;
270	unsigned short w_NumberOfInputs = 0;
271	unsigned short w_CJCFlag = 0;
272	unsigned short w_NumberOfGainValue = 0;
273	unsigned short w_SingleHeaderAddress = 0;
274	unsigned short w_SingleHeaderSize = 0;
275	unsigned short w_Input = 0;
276	unsigned short w_GainFactorAddress = 0;
277	unsigned short w_GainFactorValue[2];
278	unsigned short w_GainIndex = 0;
279	unsigned short 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
456int 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  |                     unsigned int ui_NoOfChannels    : No Of Channels To read  for Port
540  Channel Numberfor single channel
541  |                     unsigned int 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
553int i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
554	struct comedi_insn *insn, unsigned int *data)
555{
556	unsigned int ui_Temp = 0;
557	unsigned int 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*/
611int 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*/
656int i_APCI3200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
657	struct comedi_insn *insn, unsigned int *data)
658{
659	unsigned int ui_Temp = 0, ui_Temp1 = 0;
660	unsigned int 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  |                     unsigned int ui_NoOfChannels    : No Of Channels To read       |
756  |                     unsigned int *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*/
769int i_APCI3200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
770	struct comedi_insn *insn, unsigned int *data)
771{
772	unsigned int ui_Temp;
773	unsigned int 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*/
877int i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
878	struct comedi_insn *insn, unsigned int *data)
879{
880
881	unsigned int ul_Config = 0, ul_Temp = 0;
882	unsigned int ui_ChannelNo = 0;
883	unsigned int 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  |                     unsigned int ui_NoOfChannels    : No Of Channels To read       |
1344  |                     unsigned int *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*/
1364int i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
1365	struct comedi_insn *insn, unsigned int *data)
1366{
1367	unsigned int 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  |                     unsigned int ui_NoOfChannel    : Channel No to read            |
1643  |                     unsigned int *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*/
1654int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
1655	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
1656{
1657	unsigned int ui_EOC = 0;
1658	unsigned int ui_ChannelNo = 0;
1659	unsigned int 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  |                     unsigned int *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*/
1779int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, unsigned int *data)
1780{
1781	unsigned int ui_Temp = 0, ui_EOC = 0;
1782	unsigned int 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  |                     unsigned int *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*/
1915int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, unsigned int *data)
1916{
1917	unsigned int 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  |                     unsigned int *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
2051int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data)
2052{
2053	unsigned int 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  |                     unsigned int *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*/
2170int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data)
2171{
2172	unsigned int 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  |                     unsigned int ui_NoOfChannels    : No Of Channels To read       |
2275  |                     unsigned int *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*/
2286int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data)
2287{
2288	unsigned int 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
2407int i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
2408	struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
2409{
2410	unsigned int 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
2532int 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
2563int 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	unsigned int ui_ConvertTime = 0;
2570	unsigned int ui_ConvertTimeBase = 0;
2571	unsigned int ui_DelayTime = 0;
2572	unsigned int 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
2767int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s)
2768{
2769	unsigned int 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
2817int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s)
2818{
2819	struct comedi_cmd *cmd = &s->async->cmd;
2820	unsigned int ui_Configuration = 0;
2821	/* INT  i_CurrentSource = 0; */
2822	unsigned int ui_Trigger = 0;
2823	unsigned int ui_TriggerEdge = 0;
2824	unsigned int ui_Triggermode = 0;
2825	unsigned int ui_ScanMode = 0;
2826	unsigned int ui_ConvertTime = 0;
2827	unsigned int ui_ConvertTimeBase = 0;
2828	unsigned int ui_DelayTime = 0;
2829	unsigned int ui_DelayTimeBase = 0;
2830	unsigned int 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
3004int i_APCI3200_Reset(struct comedi_device *dev)
3005{
3006	int i_Temp;
3007	unsigned int 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*/
3060void v_APCI3200_Interrupt(int irq, void *d)
3061{
3062	struct comedi_device *dev = d;
3063	unsigned int ui_StatusRegister = 0;
3064	unsigned int ui_ChannelNumber = 0;
3065	int i_CalibrationFlag = 0;
3066	int i_CJCFlag = 0;
3067	unsigned int ui_DummyValue = 0;
3068	unsigned int ui_DigitalTemperature = 0;
3069	unsigned int 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*/
3502int i_APCI3200_InterruptHandleEos(struct comedi_device *dev)
3503{
3504	unsigned int 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(unsigned int); */
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(unsigned int); */
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(unsigned int); */
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(unsigned int); */
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}
3643