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