hwdrv_APCI1710.c revision fcea115462c690ba09f9df7471d60dda0d86a4ea
1//**
2@verbatim
3
4Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
5
6	ADDI-DATA GmbH
7	Dieselstrasse 3
8	D-77833 Ottersweier
9	Tel: +19(0)7223/9493-0
10	Fax: +49(0)7223/9493-92
11	http://www.addi-data-com
12	info@addi-data.com
13
14This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20You shoud also find the complete GPL in the COPYING file accompanying this source code.
21
22@endverbatim
23*/
24/*
25  +-----------------------------------------------------------------------+
26  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
27  +-----------------------------------------------------------------------+
28  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
29  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
30  +-------------------------------+---------------------------------------+
31  | Project     : APCI-1710       | Compiler   : GCC                      |
32  | Module name : hwdrv_apci1710.c| Version    : 2.96                     |
33  +-------------------------------+---------------------------------------+
34  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
35  +-------------------------------+---------------------------------------+
36  | Description :   Hardware Layer Acces For APCI-1710                    |
37  +-----------------------------------------------------------------------+
38  |                             UPDATES                                   |
39  +----------+-----------+------------------------------------------------+
40  |   Date   |   Author  |          Description of updates                |
41  +----------+-----------+------------------------------------------------+
42  |          |           |                                                |
43  |          |           |                                                |
44  |          |           |                                                |
45  +----------+-----------+------------------------------------------------+
46*/
47#include "hwdrv_APCI1710.h"
48#include "APCI1710_Inp_cpt.c"
49
50#include "APCI1710_Ssi.c"
51#include "APCI1710_Tor.c"
52#include "APCI1710_Ttl.c"
53#include "APCI1710_Dig_io.c"
54#include "APCI1710_82x54.c"
55#include "APCI1710_Chrono.c"
56#include "APCI1710_Pwm.c"
57#include "APCI1710_INCCPT.c"
58
59void i_ADDI_AttachPCI1710(struct comedi_device *dev)
60{
61	struct comedi_subdevice *s;
62	int ret = 0;
63	int n_subdevices = 9;
64
65	/* Update-0.7.57->0.7.68dev->n_subdevices = 9; */
66	ret = alloc_subdevices(dev, n_subdevices);
67	if (ret < 0)
68		return;
69
70	/*  Allocate and Initialise Timer Subdevice Structures */
71	s = dev->subdevices + 0;
72
73	s->type = COMEDI_SUBD_TIMER;
74	s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
75	s->n_chan = 3;
76	s->maxdata = 0;
77	s->len_chanlist = 3;
78	s->range_table = &range_digital;
79	s->insn_write = i_APCI1710_InsnWriteEnableDisableTimer;
80	s->insn_read = i_APCI1710_InsnReadAllTimerValue;
81	s->insn_config = i_APCI1710_InsnConfigInitTimer;
82	s->insn_bits = i_APCI1710_InsnBitsTimer;
83
84	/*  Allocate and Initialise DIO Subdevice Structures */
85	s = dev->subdevices + 1;
86
87	s->type = COMEDI_SUBD_DIO;
88	s->subdev_flags =
89		SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
90	s->n_chan = 7;
91	s->maxdata = 1;
92	s->len_chanlist = 7;
93	s->range_table = &range_digital;
94	s->insn_config = i_APCI1710_InsnConfigDigitalIO;
95	s->insn_read = i_APCI1710_InsnReadDigitalIOChlValue;
96	s->insn_bits = i_APCI1710_InsnBitsDigitalIOPortOnOff;
97	s->insn_write = i_APCI1710_InsnWriteDigitalIOChlOnOff;
98
99	/*  Allocate and Initialise Chrono Subdevice Structures */
100	s = dev->subdevices + 2;
101
102	s->type = COMEDI_SUBD_CHRONO;
103	s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
104	s->n_chan = 4;
105	s->maxdata = 0;
106	s->len_chanlist = 4;
107	s->range_table = &range_digital;
108	s->insn_write = i_APCI1710_InsnWriteEnableDisableChrono;
109	s->insn_read = i_APCI1710_InsnReadChrono;
110	s->insn_config = i_APCI1710_InsnConfigInitChrono;
111	s->insn_bits = i_APCI1710_InsnBitsChronoDigitalIO;
112
113	/*  Allocate and Initialise PWM Subdevice Structures */
114	s = dev->subdevices + 3;
115	s->type = COMEDI_SUBD_PWM;
116	s->subdev_flags =
117		SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
118	s->n_chan = 3;
119	s->maxdata = 1;
120	s->len_chanlist = 3;
121	s->range_table = &range_digital;
122	s->io_bits = 0;		/* all bits input */
123	s->insn_config = i_APCI1710_InsnConfigPWM;
124	s->insn_read = i_APCI1710_InsnReadGetPWMStatus;
125	s->insn_write = i_APCI1710_InsnWritePWM;
126	s->insn_bits = i_APCI1710_InsnBitsReadPWMInterrupt;
127
128	/*  Allocate and Initialise TTLIO Subdevice Structures */
129	s = dev->subdevices + 4;
130	s->type = COMEDI_SUBD_TTLIO;
131	s->subdev_flags =
132		SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
133	s->n_chan = 8;
134	s->maxdata = 1;
135	s->len_chanlist = 8;
136	s->range_table = &range_apci1710_ttl;	/*  to pass arguments in range */
137	s->insn_config = i_APCI1710_InsnConfigInitTTLIO;
138	s->insn_bits = i_APCI1710_InsnBitsReadTTLIO;
139	s->insn_write = i_APCI1710_InsnWriteSetTTLIOChlOnOff;
140	s->insn_read = i_APCI1710_InsnReadTTLIOAllPortValue;
141
142	/*  Allocate and Initialise TOR Subdevice Structures */
143	s = dev->subdevices + 5;
144	s->type = COMEDI_SUBD_TOR;
145	s->subdev_flags =
146		SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
147	s->n_chan = 8;
148	s->maxdata = 1;
149	s->len_chanlist = 8;
150	s->range_table = &range_digital;
151	s->io_bits = 0;		/* all bits input */
152	s->insn_config = i_APCI1710_InsnConfigInitTorCounter;
153	s->insn_read = i_APCI1710_InsnReadGetTorCounterInitialisation;
154	s->insn_write = i_APCI1710_InsnWriteEnableDisableTorCounter;
155	s->insn_bits = i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue;
156
157	/*  Allocate and Initialise SSI Subdevice Structures */
158	s = dev->subdevices + 6;
159	s->type = COMEDI_SUBD_SSI;
160	s->subdev_flags =
161		SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
162	s->n_chan = 4;
163	s->maxdata = 1;
164	s->len_chanlist = 4;
165	s->range_table = &range_apci1710_ssi;
166	s->insn_config = i_APCI1710_InsnConfigInitSSI;
167	s->insn_read = i_APCI1710_InsnReadSSIValue;
168	s->insn_bits = i_APCI1710_InsnBitsSSIDigitalIO;
169
170	/*  Allocate and Initialise PULSEENCODER Subdevice Structures */
171	s = dev->subdevices + 7;
172	s->type = COMEDI_SUBD_PULSEENCODER;
173	s->subdev_flags =
174		SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
175	s->n_chan = 4;
176	s->maxdata = 1;
177	s->len_chanlist = 4;
178	s->range_table = &range_digital;
179	s->insn_config = i_APCI1710_InsnConfigInitPulseEncoder;
180	s->insn_write = i_APCI1710_InsnWriteEnableDisablePulseEncoder;
181	s->insn_bits = i_APCI1710_InsnBitsReadWritePulseEncoder;
182	s->insn_read = i_APCI1710_InsnReadInterruptPulseEncoder;
183
184	/*  Allocate and Initialise INCREMENTALCOUNTER Subdevice Structures */
185	s = dev->subdevices + 8;
186	s->type = COMEDI_SUBD_INCREMENTALCOUNTER;
187	s->subdev_flags =
188		SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
189	s->n_chan = 500;
190	s->maxdata = 1;
191	s->len_chanlist = 500;
192	s->range_table = &range_apci1710_inccpt;
193	s->insn_config = i_APCI1710_InsnConfigINCCPT;
194	s->insn_write = i_APCI1710_InsnWriteINCCPT;
195	s->insn_read = i_APCI1710_InsnReadINCCPT;
196	s->insn_bits = i_APCI1710_InsnBitsINCCPT;
197}
198
199int i_APCI1710_Reset(struct comedi_device *dev);
200void v_APCI1710_Interrupt(int irq, void *d);
201/* for 1710 */
202
203int i_APCI1710_Reset(struct comedi_device *dev)
204{
205	int ret;
206	unsigned int dw_Dummy;
207
208	/*********************************/
209	/* Read all module configuration */
210	/*********************************/
211	ret = inl(devpriv->s_BoardInfos.ui_Address + 60);
212	devpriv->s_BoardInfos.dw_MolduleConfiguration[0] = ret;
213
214	ret = inl(devpriv->s_BoardInfos.ui_Address + 124);
215	devpriv->s_BoardInfos.dw_MolduleConfiguration[1] = ret;
216
217	ret = inl(devpriv->s_BoardInfos.ui_Address + 188);
218	devpriv->s_BoardInfos.dw_MolduleConfiguration[2] = ret;
219
220	ret = inl(devpriv->s_BoardInfos.ui_Address + 252);
221	devpriv->s_BoardInfos.dw_MolduleConfiguration[3] = ret;
222
223	/*  outl(0x80808082,devpriv->s_BoardInfos.ui_Address+0x60); */
224	outl(0x83838383, devpriv->s_BoardInfos.ui_Address + 0x60);
225
226	devpriv->s_BoardInfos.b_BoardVersion = 1;
227
228	/*  Enable the interrupt for the controler */
229	dw_Dummy = inl(devpriv->s_BoardInfos.ui_Address + 0x38);
230	outl(dw_Dummy | 0x2000, devpriv->s_BoardInfos.ui_Address + 0x38);
231
232	return 0;
233}
234
235/*
236+----------------------------------------------------------------------------+
237| Function's Name   : __void__ v_APCI1710_InterruptFunction                  |
238|				(unsigned char b_Interrupt, __CPPARGS)                |
239+----------------------------------------------------------------------------+
240| Task              : APCI-1710 interrupt function                           |
241+----------------------------------------------------------------------------+
242| Input Parameters  : unsigned char b_Interrupt : Interrupt number                    |
243+----------------------------------------------------------------------------+
244| Output Parameters : -                                                      |
245+----------------------------------------------------------------------------+
246| Return Value      : 0 : OK                                                 |
247|                    -1 : Error                                              |
248+----------------------------------------------------------------------------+
249*/
250
251void v_APCI1710_Interrupt(int irq, void *d)
252{
253	struct comedi_device *dev = d;
254	unsigned char b_ModuleCpt = 0;
255	unsigned char b_InterruptFlag = 0;
256	unsigned char b_PWMCpt = 0;
257	unsigned char b_TorCounterCpt = 0;
258	unsigned char b_PulseIncoderCpt = 0;
259	unsigned int ui_16BitValue;
260	unsigned int ul_InterruptLatchReg = 0;
261	unsigned int ul_LatchRegisterValue = 0;
262	unsigned int ul_82X54InterruptStatus;
263	unsigned int ul_StatusRegister;
264
265	union str_ModuleInfo *ps_ModuleInfo;
266
267	printk("APCI1710 Interrupt\n");
268	for (b_ModuleCpt = 0; b_ModuleCpt < 4; b_ModuleCpt++, ps_ModuleInfo++) {
269
270		 /**************************/
271		/* 1199/0225 to 0100/0226 */
272		 /**************************/
273		ps_ModuleInfo = &devpriv->s_ModuleInfo[b_ModuleCpt];
274
275		 /***********************/
276		/* Test if 82X54 timer */
277		 /***********************/
278
279		if ((devpriv->s_BoardInfos.
280				dw_MolduleConfiguration[b_ModuleCpt] &
281				0xFFFF0000UL) == APCI1710_82X54_TIMER) {
282
283			/* printk("TIMER Interrupt Occurred\n"); */
284			ul_82X54InterruptStatus = inl(devpriv->s_BoardInfos.
285				ui_Address + 12 + (64 * b_ModuleCpt));
286
287		    /***************************/
288			/* Test if interrupt occur */
289		    /***************************/
290
291			if ((ul_82X54InterruptStatus & ps_ModuleInfo->
292					s_82X54ModuleInfo.
293					b_InterruptMask) != 0) {
294				devpriv->
295					s_InterruptParameters.
296					s_FIFOInterruptParameters[devpriv->
297					s_InterruptParameters.
298					ui_Write].
299					ul_OldInterruptMask =
300					(ul_82X54InterruptStatus &
301					ps_ModuleInfo->s_82X54ModuleInfo.
302					b_InterruptMask) << 4;
303
304				devpriv->
305					s_InterruptParameters.
306					s_FIFOInterruptParameters[devpriv->
307					s_InterruptParameters.
308					ui_Write].
309					b_OldModuleMask = 1 << b_ModuleCpt;
310
311				devpriv->
312					s_InterruptParameters.
313					s_FIFOInterruptParameters[devpriv->
314					s_InterruptParameters.
315					ui_Write].ul_OldCounterLatchValue = 0;
316
317				devpriv->
318					s_InterruptParameters.
319					ul_InterruptOccur++;
320
321		       /****************************/
322				/* Increment the write FIFO */
323		       /****************************/
324
325				devpriv->
326					s_InterruptParameters.
327					ui_Write = (devpriv->
328					s_InterruptParameters.
329					ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
330
331				b_InterruptFlag = 1;
332
333			     /**********************/
334				/* Call user function */
335			     /**********************/
336				/* Send a signal to from kernel to user space */
337				send_sig(SIGIO, devpriv->tsk_Current, 0);
338
339			}	/*  if ((ul_82X54InterruptStatus & 0x7) != 0) */
340		}		/*  82X54 timer */
341
342		 /***************************/
343		/* Test if increm. counter */
344		 /***************************/
345
346		if ((devpriv->s_BoardInfos.
347				dw_MolduleConfiguration[b_ModuleCpt] &
348				0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
349
350			ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
351				ui_Address + (64 * b_ModuleCpt));
352
353		    /*********************/
354			/* Test if interrupt */
355		    /*********************/
356
357			if ((ul_InterruptLatchReg & 0x22) && (ps_ModuleInfo->
358					s_SiemensCounterInfo.
359					s_ModeRegister.
360					s_ByteModeRegister.
361					b_ModeRegister2 & 0x80)) {
362		       /************************************/
363				/* Test if strobe latch I interrupt */
364		       /************************************/
365
366				if (ul_InterruptLatchReg & 2) {
367					ul_LatchRegisterValue =
368						inl(devpriv->s_BoardInfos.
369						ui_Address + 4 +
370						(64 * b_ModuleCpt));
371
372					devpriv->
373						s_InterruptParameters.
374						s_FIFOInterruptParameters
375						[devpriv->s_InterruptParameters.
376						ui_Write].ul_OldInterruptMask =
377						1UL;
378
379					devpriv->
380						s_InterruptParameters.
381						s_FIFOInterruptParameters
382						[devpriv->s_InterruptParameters.
383						ui_Write].b_OldModuleMask =
384						1 << b_ModuleCpt;
385
386					devpriv->
387						s_InterruptParameters.
388						s_FIFOInterruptParameters
389						[devpriv->s_InterruptParameters.
390						ui_Write].
391						ul_OldCounterLatchValue =
392						ul_LatchRegisterValue;
393
394					devpriv->
395						s_InterruptParameters.
396						ul_InterruptOccur++;
397
398			  /****************************/
399					/* 0899/0224 to 1199/0225   */
400			  /****************************/
401					/* Increment the write FIFO */
402		      /****************************/
403
404					devpriv->
405						s_InterruptParameters.
406						ui_Write = (devpriv->
407						s_InterruptParameters.
408						ui_Write +
409						1) % APCI1710_SAVE_INTERRUPT;
410
411					b_InterruptFlag = 1;
412
413				/**********************/
414					/* Call user function */
415				/**********************/
416					/* Send a signal to from kernel to user space */
417					send_sig(SIGIO, devpriv->tsk_Current,
418						0);
419
420				}
421
422		       /*************************************/
423				/* Test if strobe latch II interrupt */
424		       /*************************************/
425
426				if (ul_InterruptLatchReg & 0x20) {
427
428					ul_LatchRegisterValue =
429						inl(devpriv->s_BoardInfos.
430						ui_Address + 8 +
431						(64 * b_ModuleCpt));
432
433					devpriv->
434						s_InterruptParameters.
435						s_FIFOInterruptParameters
436						[devpriv->s_InterruptParameters.
437						ui_Write].ul_OldInterruptMask =
438						2UL;
439
440					devpriv->
441						s_InterruptParameters.
442						s_FIFOInterruptParameters
443						[devpriv->s_InterruptParameters.
444						ui_Write].b_OldModuleMask =
445						1 << b_ModuleCpt;
446
447					devpriv->
448						s_InterruptParameters.
449						s_FIFOInterruptParameters
450						[devpriv->s_InterruptParameters.
451						ui_Write].
452						ul_OldCounterLatchValue =
453						ul_LatchRegisterValue;
454
455					devpriv->
456						s_InterruptParameters.
457						ul_InterruptOccur++;
458
459			  /****************************/
460					/* 0899/0224 to 1199/0225   */
461			  /****************************/
462					/* Increment the write FIFO */
463			  /****************************/
464
465					devpriv->
466						s_InterruptParameters.
467						ui_Write = (devpriv->
468						s_InterruptParameters.
469						ui_Write +
470						1) % APCI1710_SAVE_INTERRUPT;
471
472					b_InterruptFlag = 1;
473
474			    /**********************/
475					/* Call user function */
476				/**********************/
477					/* Send a signal to from kernel to user space */
478					send_sig(SIGIO, devpriv->tsk_Current,
479						0);
480
481				}
482			}
483
484			ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
485				ui_Address + 24 + (64 * b_ModuleCpt));
486
487		    /***************************/
488			/* Test if index interrupt */
489		    /***************************/
490
491			if (ul_InterruptLatchReg & 0x8) {
492				ps_ModuleInfo->
493					s_SiemensCounterInfo.
494					s_InitFlag.b_IndexInterruptOccur = 1;
495
496				if (ps_ModuleInfo->
497					s_SiemensCounterInfo.
498					s_ModeRegister.
499					s_ByteModeRegister.
500					b_ModeRegister2 &
501					APCI1710_INDEX_AUTO_MODE) {
502
503					outl(ps_ModuleInfo->
504						s_SiemensCounterInfo.
505						s_ModeRegister.
506						dw_ModeRegister1_2_3_4,
507						devpriv->s_BoardInfos.
508						ui_Address + 20 +
509						(64 * b_ModuleCpt));
510				}
511
512		       /*****************************/
513				/* Test if interrupt enabled */
514		       /*****************************/
515
516				if ((ps_ModuleInfo->
517						s_SiemensCounterInfo.
518						s_ModeRegister.
519						s_ByteModeRegister.
520						b_ModeRegister3 &
521						APCI1710_ENABLE_INDEX_INT) ==
522					APCI1710_ENABLE_INDEX_INT) {
523					devpriv->s_InterruptParameters.
524						s_FIFOInterruptParameters
525						[devpriv->s_InterruptParameters.
526						ui_Write].ul_OldInterruptMask =
527						4UL;
528
529					devpriv->
530						s_InterruptParameters.
531						s_FIFOInterruptParameters
532						[devpriv->s_InterruptParameters.
533						ui_Write].b_OldModuleMask =
534						1 << b_ModuleCpt;
535
536					devpriv->
537						s_InterruptParameters.
538						s_FIFOInterruptParameters
539						[devpriv->s_InterruptParameters.
540						ui_Write].
541						ul_OldCounterLatchValue =
542						ul_LatchRegisterValue;
543
544					devpriv->
545						s_InterruptParameters.
546						ul_InterruptOccur++;
547
548			  /****************************/
549					/* 0899/0224 to 1199/0225   */
550			  /****************************/
551					/* Increment the write FIFO */
552			  /****************************/
553
554					devpriv->
555						s_InterruptParameters.
556						ui_Write = (devpriv->
557						s_InterruptParameters.
558						ui_Write +
559						1) % APCI1710_SAVE_INTERRUPT;
560
561					b_InterruptFlag = 1;
562
563				/**********************/
564					/* Call user function */
565				/**********************/
566					/* Send a signal to from kernel to user space */
567					send_sig(SIGIO, devpriv->tsk_Current,
568						0);
569
570				}
571			}
572
573		    /*****************************/
574			/* Test if compare interrupt */
575		    /*****************************/
576
577			if (ul_InterruptLatchReg & 0x10) {
578		       /*****************************/
579				/* Test if interrupt enabled */
580		       /*****************************/
581
582				if ((ps_ModuleInfo->
583						s_SiemensCounterInfo.
584						s_ModeRegister.
585						s_ByteModeRegister.
586						b_ModeRegister3 &
587						APCI1710_ENABLE_COMPARE_INT) ==
588					APCI1710_ENABLE_COMPARE_INT) {
589					devpriv->s_InterruptParameters.
590						s_FIFOInterruptParameters
591						[devpriv->s_InterruptParameters.
592						ui_Write].ul_OldInterruptMask =
593						8UL;
594
595					devpriv->
596						s_InterruptParameters.
597						s_FIFOInterruptParameters
598						[devpriv->s_InterruptParameters.
599						ui_Write].b_OldModuleMask =
600						1 << b_ModuleCpt;
601
602					devpriv->
603						s_InterruptParameters.
604						s_FIFOInterruptParameters
605						[devpriv->s_InterruptParameters.
606						ui_Write].
607						ul_OldCounterLatchValue =
608						ul_LatchRegisterValue;
609
610					devpriv->
611						s_InterruptParameters.
612						ul_InterruptOccur++;
613
614			  /****************************/
615					/* 0899/0224 to 1199/0225   */
616			  /****************************/
617					/* Increment the write FIFO */
618		      /****************************/
619
620					devpriv->
621						s_InterruptParameters.
622						ui_Write = (devpriv->
623						s_InterruptParameters.
624						ui_Write +
625						1) % APCI1710_SAVE_INTERRUPT;
626
627					b_InterruptFlag = 1;
628
629				/**********************/
630					/* Call user function */
631				/**********************/
632					/* Send a signal to from kernel to user space */
633					send_sig(SIGIO, devpriv->tsk_Current,
634						0);
635
636				}
637			}
638
639		    /*******************************************/
640			/* Test if frequency measurement interrupt */
641		    /*******************************************/
642
643			if (ul_InterruptLatchReg & 0x20) {
644		       /*******************/
645				/* Read the status */
646		       /*******************/
647
648				ul_StatusRegister = inl(devpriv->s_BoardInfos.
649					ui_Address + 32 + (64 * b_ModuleCpt));
650
651		       /******************/
652				/* Read the value */
653		       /******************/
654
655				ul_LatchRegisterValue =
656					inl(devpriv->s_BoardInfos.ui_Address +
657					28 + (64 * b_ModuleCpt));
658
659				switch ((ul_StatusRegister >> 1) & 3) {
660				case 0:
661			       /*************************/
662					/* Test the counter mode */
663			       /*************************/
664
665					if ((devpriv->s_ModuleInfo[b_ModuleCpt].
666							s_SiemensCounterInfo.
667							s_ModeRegister.
668							s_ByteModeRegister.
669							b_ModeRegister1 &
670							APCI1710_16BIT_COUNTER)
671						== APCI1710_16BIT_COUNTER) {
672				  /****************************************/
673						/* Test if 16-bit counter 1 pulse occur */
674				  /****************************************/
675
676						if ((ul_LatchRegisterValue &
677								0xFFFFU) != 0) {
678							ui_16BitValue =
679								(unsigned int)
680								ul_LatchRegisterValue
681								& 0xFFFFU;
682							ul_LatchRegisterValue =
683								(ul_LatchRegisterValue
684								& 0xFFFF0000UL)
685								| (0xFFFFU -
686								ui_16BitValue);
687						}
688
689				  /****************************************/
690						/* Test if 16-bit counter 2 pulse occur */
691				  /****************************************/
692
693						if ((ul_LatchRegisterValue &
694								0xFFFF0000UL) !=
695							0) {
696							ui_16BitValue =
697								(unsigned int) (
698								(ul_LatchRegisterValue
699									>> 16) &
700								0xFFFFU);
701							ul_LatchRegisterValue =
702								(ul_LatchRegisterValue
703								& 0xFFFFUL) |
704								((0xFFFFU -
705									ui_16BitValue)
706								<< 16);
707						}
708					} else {
709						if (ul_LatchRegisterValue != 0) {
710							ul_LatchRegisterValue =
711								0xFFFFFFFFUL -
712								ul_LatchRegisterValue;
713						}
714					}
715					break;
716
717				case 1:
718			       /****************************************/
719					/* Test if 16-bit counter 2 pulse occur */
720			       /****************************************/
721
722					if ((ul_LatchRegisterValue &
723							0xFFFF0000UL) != 0) {
724						ui_16BitValue =
725							(unsigned int) (
726							(ul_LatchRegisterValue
727								>> 16) &
728							0xFFFFU);
729						ul_LatchRegisterValue =
730							(ul_LatchRegisterValue &
731							0xFFFFUL) | ((0xFFFFU -
732								ui_16BitValue)
733							<< 16);
734					}
735					break;
736
737				case 2:
738			       /****************************************/
739					/* Test if 16-bit counter 1 pulse occur */
740			       /****************************************/
741
742					if ((ul_LatchRegisterValue & 0xFFFFU) !=
743						0) {
744						ui_16BitValue =
745							(unsigned int)
746							ul_LatchRegisterValue &
747							0xFFFFU;
748						ul_LatchRegisterValue =
749							(ul_LatchRegisterValue &
750							0xFFFF0000UL) | (0xFFFFU
751							- ui_16BitValue);
752					}
753					break;
754				}
755
756				devpriv->
757					s_InterruptParameters.
758					s_FIFOInterruptParameters[devpriv->
759					s_InterruptParameters.
760					ui_Write].
761					ul_OldInterruptMask = 0x10000UL;
762
763				devpriv->
764					s_InterruptParameters.
765					s_FIFOInterruptParameters[devpriv->
766					s_InterruptParameters.
767					ui_Write].
768					b_OldModuleMask = 1 << b_ModuleCpt;
769
770				devpriv->
771					s_InterruptParameters.
772					s_FIFOInterruptParameters[devpriv->
773					s_InterruptParameters.
774					ui_Write].
775					ul_OldCounterLatchValue =
776					ul_LatchRegisterValue;
777
778				devpriv->
779					s_InterruptParameters.
780					ul_InterruptOccur++;
781
782		       /****************************/
783				/* 0899/0224 to 1199/0225   */
784		       /****************************/
785				/* Increment the write FIFO */
786		       /****************************/
787
788				devpriv->
789					s_InterruptParameters.
790					ui_Write = (devpriv->
791					s_InterruptParameters.
792					ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
793
794				b_InterruptFlag = 1;
795
796			     /**********************/
797				/* Call user function */
798			     /**********************/
799				/* Send a signal to from kernel to user space */
800				send_sig(SIGIO, devpriv->tsk_Current, 0);
801
802			}
803		}		/*  Incremental counter */
804
805		 /***************/
806		/* Test if CDA */
807		 /***************/
808
809		if ((devpriv->s_BoardInfos.
810				dw_MolduleConfiguration[b_ModuleCpt] &
811				0xFFFF0000UL) == APCI1710_CDA) {
812		    /******************************************/
813			/* Test if CDA enable and functionality 0 */
814		    /******************************************/
815
816			if ((devpriv->s_ModuleInfo[b_ModuleCpt].
817					s_CDAModuleInfo.
818					b_CDAEnable == APCI1710_ENABLE)
819				&& (devpriv->s_ModuleInfo[b_ModuleCpt].
820					s_CDAModuleInfo.b_FctSelection == 0)) {
821		       /****************************/
822				/* Get the interrupt status */
823		       /****************************/
824
825				ul_StatusRegister = inl(devpriv->s_BoardInfos.
826					ui_Address + 16 + (64 * b_ModuleCpt));
827		       /***************************/
828				/* Test if interrupt occur */
829		       /***************************/
830
831				if (ul_StatusRegister & 1) {
832					devpriv->
833						s_InterruptParameters.
834						s_FIFOInterruptParameters
835						[devpriv->s_InterruptParameters.
836						ui_Write].ul_OldInterruptMask =
837						0x80000UL;
838
839					devpriv->
840						s_InterruptParameters.
841						s_FIFOInterruptParameters
842						[devpriv->s_InterruptParameters.
843						ui_Write].b_OldModuleMask =
844						1 << b_ModuleCpt;
845
846					devpriv->
847						s_InterruptParameters.
848						s_FIFOInterruptParameters
849						[devpriv->s_InterruptParameters.
850						ui_Write].
851						ul_OldCounterLatchValue = 0;
852
853					devpriv->
854						s_InterruptParameters.
855						ul_InterruptOccur++;
856
857			  /****************************/
858					/* Increment the write FIFO */
859			  /****************************/
860
861					devpriv->
862						s_InterruptParameters.
863						ui_Write = (devpriv->
864						s_InterruptParameters.
865						ui_Write +
866						1) % APCI1710_SAVE_INTERRUPT;
867
868					b_InterruptFlag = 1;
869
870				/**********************/
871					/* Call user function */
872				/**********************/
873
874					/* Send a signal to from kernel to user space */
875					send_sig(SIGIO, devpriv->tsk_Current,
876						0);
877
878				}	/*  if (ul_StatusRegister & 1) */
879
880			}
881		}		/*  CDA */
882
883		 /***********************/
884		/* Test if PWM counter */
885		 /***********************/
886
887		if ((devpriv->s_BoardInfos.
888				dw_MolduleConfiguration[b_ModuleCpt] &
889				0xFFFF0000UL) == APCI1710_PWM) {
890			for (b_PWMCpt = 0; b_PWMCpt < 2; b_PWMCpt++) {
891		       /*************************************/
892				/* Test if PWM interrupt initialised */
893		       /*************************************/
894
895				if (devpriv->
896					s_ModuleInfo[b_ModuleCpt].
897					s_PWMModuleInfo.
898					s_PWMInfo[b_PWMCpt].
899					b_InterruptEnable == APCI1710_ENABLE) {
900			  /*****************************/
901					/* Read the interrupt status */
902			  /*****************************/
903
904					ul_StatusRegister =
905						inl(devpriv->s_BoardInfos.
906						ui_Address + 16 +
907						(20 * b_PWMCpt) +
908						(64 * b_ModuleCpt));
909
910			  /***************************/
911					/* Test if interrupt occur */
912			  /***************************/
913
914					if (ul_StatusRegister & 0x1) {
915						devpriv->
916							s_InterruptParameters.
917							s_FIFOInterruptParameters
918							[devpriv->
919							s_InterruptParameters.
920							ui_Write].
921							ul_OldInterruptMask =
922							0x4000UL << b_PWMCpt;
923
924						devpriv->
925							s_InterruptParameters.
926							s_FIFOInterruptParameters
927							[devpriv->
928							s_InterruptParameters.
929							ui_Write].
930							b_OldModuleMask =
931							1 << b_ModuleCpt;
932
933						devpriv->
934							s_InterruptParameters.
935							ul_InterruptOccur++;
936
937			     /****************************/
938						/* Increment the write FIFO */
939			     /****************************/
940
941						devpriv->
942							s_InterruptParameters.
943							ui_Write = (devpriv->
944							s_InterruptParameters.
945							ui_Write +
946							1) %
947							APCI1710_SAVE_INTERRUPT;
948
949						b_InterruptFlag = 1;
950
951				   /**********************/
952						/* Call user function */
953				   /**********************/
954						/* Send a signal to from kernel to user space */
955						send_sig(SIGIO,
956							devpriv->tsk_Current,
957							0);
958
959					}	/*  if (ul_StatusRegister & 0x1) */
960				}	/*  if (APCI1710_ENABLE) */
961			}	/*  for (b_PWMCpt == 0; b_PWMCpt < 0; b_PWMCpt ++) */
962		}		/*  PWM counter */
963
964		 /***********************/
965		/* Test if tor counter */
966		 /***********************/
967
968		if ((devpriv->s_BoardInfos.
969				dw_MolduleConfiguration[b_ModuleCpt] &
970				0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
971			for (b_TorCounterCpt = 0; b_TorCounterCpt < 2;
972				b_TorCounterCpt++) {
973		       /*************************************/
974				/* Test if tor interrupt initialised */
975		       /*************************************/
976
977				if (devpriv->
978					s_ModuleInfo[b_ModuleCpt].
979					s_TorCounterModuleInfo.
980					s_TorCounterInfo[b_TorCounterCpt].
981					b_InterruptEnable == APCI1710_ENABLE) {
982			  /*****************************/
983					/* Read the interrupt status */
984			  /*****************************/
985
986					ul_StatusRegister =
987						inl(devpriv->s_BoardInfos.
988						ui_Address + 12 +
989						(16 * b_TorCounterCpt) +
990						(64 * b_ModuleCpt));
991
992			  /***************************/
993					/* Test if interrupt occur */
994			  /***************************/
995
996					if (ul_StatusRegister & 0x1) {
997			     /******************************/
998						/* Read the tor counter value */
999			     /******************************/
1000
1001						ul_LatchRegisterValue =
1002							inl(devpriv->
1003							s_BoardInfos.
1004							ui_Address + 0 +
1005							(16 * b_TorCounterCpt) +
1006							(64 * b_ModuleCpt));
1007
1008						devpriv->
1009							s_InterruptParameters.
1010							s_FIFOInterruptParameters
1011							[devpriv->
1012							s_InterruptParameters.
1013							ui_Write].
1014							ul_OldInterruptMask =
1015							0x1000UL <<
1016							b_TorCounterCpt;
1017
1018						devpriv->
1019							s_InterruptParameters.
1020							s_FIFOInterruptParameters
1021							[devpriv->
1022							s_InterruptParameters.
1023							ui_Write].
1024							b_OldModuleMask =
1025							1 << b_ModuleCpt;
1026
1027						devpriv->
1028							s_InterruptParameters.
1029							s_FIFOInterruptParameters
1030							[devpriv->
1031							s_InterruptParameters.
1032							ui_Write].
1033							ul_OldCounterLatchValue
1034							= ul_LatchRegisterValue;
1035
1036						devpriv->
1037							s_InterruptParameters.
1038							ul_InterruptOccur++;
1039
1040			     /****************************/
1041						/* Increment the write FIFO */
1042			     /****************************/
1043
1044						devpriv->
1045							s_InterruptParameters.
1046							ui_Write = (devpriv->
1047							s_InterruptParameters.
1048							ui_Write +
1049							1) %
1050							APCI1710_SAVE_INTERRUPT;
1051
1052						b_InterruptFlag = 1;
1053
1054				   /**********************/
1055						/* Call user function */
1056				   /**********************/
1057
1058						/* Send a signal to from kernel to user space */
1059						send_sig(SIGIO,
1060							devpriv->tsk_Current,
1061							0);
1062					}	/*  if (ul_StatusRegister & 0x1) */
1063				}	/*  if (APCI1710_ENABLE) */
1064			}	/*  for (b_TorCounterCpt == 0; b_TorCounterCpt < 0; b_TorCounterCpt ++) */
1065		}		/*  Tor counter */
1066
1067		 /***********************/
1068		/* Test if chronometer */
1069		 /***********************/
1070
1071		if ((devpriv->s_BoardInfos.
1072				dw_MolduleConfiguration[b_ModuleCpt] &
1073				0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1074
1075			/* printk("APCI1710 Chrono Interrupt\n"); */
1076		    /*****************************/
1077			/* Read the interrupt status */
1078		    /*****************************/
1079
1080			ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
1081				ui_Address + 12 + (64 * b_ModuleCpt));
1082
1083		    /***************************/
1084			/* Test if interrupt occur */
1085		    /***************************/
1086
1087			if ((ul_InterruptLatchReg & 0x8) == 0x8) {
1088		       /****************************/
1089				/* Clear the interrupt flag */
1090		       /****************************/
1091
1092				outl(0, devpriv->s_BoardInfos.
1093					ui_Address + 32 + (64 * b_ModuleCpt));
1094
1095		       /***************************/
1096				/* Test if continuous mode */
1097		       /***************************/
1098
1099				if (ps_ModuleInfo->
1100					s_ChronoModuleInfo.
1101					b_CycleMode == APCI1710_ENABLE) {
1102			  /********************/
1103					/* Clear the status */
1104			  /********************/
1105
1106					outl(0, devpriv->s_BoardInfos.
1107						ui_Address + 36 +
1108						(64 * b_ModuleCpt));
1109				}
1110
1111		       /*************************/
1112				/* Read the timing value */
1113		       /*************************/
1114
1115				ul_LatchRegisterValue =
1116					inl(devpriv->s_BoardInfos.ui_Address +
1117					4 + (64 * b_ModuleCpt));
1118
1119		       /*****************************/
1120				/* Test if interrupt enabled */
1121		       /*****************************/
1122
1123				if (ps_ModuleInfo->
1124					s_ChronoModuleInfo.b_InterruptMask) {
1125					devpriv->
1126						s_InterruptParameters.
1127						s_FIFOInterruptParameters
1128						[devpriv->s_InterruptParameters.
1129						ui_Write].ul_OldInterruptMask =
1130						0x80;
1131
1132					devpriv->
1133						s_InterruptParameters.
1134						s_FIFOInterruptParameters
1135						[devpriv->s_InterruptParameters.
1136						ui_Write].b_OldModuleMask =
1137						1 << b_ModuleCpt;
1138
1139					devpriv->
1140						s_InterruptParameters.
1141						s_FIFOInterruptParameters
1142						[devpriv->s_InterruptParameters.
1143						ui_Write].
1144						ul_OldCounterLatchValue =
1145						ul_LatchRegisterValue;
1146
1147					devpriv->
1148						s_InterruptParameters.
1149						ul_InterruptOccur++;
1150
1151			  /****************************/
1152					/* Increment the write FIFO */
1153		      /****************************/
1154
1155					devpriv->
1156						s_InterruptParameters.
1157						ui_Write = (devpriv->
1158						s_InterruptParameters.
1159						ui_Write +
1160						1) % APCI1710_SAVE_INTERRUPT;
1161
1162					b_InterruptFlag = 1;
1163
1164				/**********************/
1165					/* Call user function */
1166				/**********************/
1167					/* Send a signal to from kernel to user space */
1168					send_sig(SIGIO, devpriv->tsk_Current,
1169						0);
1170
1171				}
1172			}
1173		}		/*  Chronometer */
1174
1175		 /*************************/
1176		/* Test if pulse encoder */
1177		 /*************************/
1178
1179		if ((devpriv->s_BoardInfos.
1180				dw_MolduleConfiguration[b_ModuleCpt] &
1181				0xFFFF0000UL) == APCI1710_PULSE_ENCODER) {
1182		    /****************************/
1183			/* Read the status register */
1184		    /****************************/
1185
1186			ul_StatusRegister = inl(devpriv->s_BoardInfos.
1187				ui_Address + 20 + (64 * b_ModuleCpt));
1188
1189			if (ul_StatusRegister & 0xF) {
1190				for (b_PulseIncoderCpt = 0;
1191					b_PulseIncoderCpt < 4;
1192					b_PulseIncoderCpt++) {
1193			  /*************************************/
1194					/* Test if pulse encoder initialised */
1195			  /*************************************/
1196
1197					if ((ps_ModuleInfo->
1198							s_PulseEncoderModuleInfo.
1199							s_PulseEncoderInfo
1200							[b_PulseIncoderCpt].
1201							b_PulseEncoderInit == 1)
1202						&& (((ps_ModuleInfo->s_PulseEncoderModuleInfo.dw_SetRegister >> b_PulseIncoderCpt) & 1) == 1) && (((ul_StatusRegister >> (b_PulseIncoderCpt)) & 1) == 1)) {
1203						devpriv->s_InterruptParameters.
1204							s_FIFOInterruptParameters
1205							[devpriv->
1206							s_InterruptParameters.
1207							ui_Write].
1208							ul_OldInterruptMask =
1209							0x100UL <<
1210							b_PulseIncoderCpt;
1211
1212						devpriv->
1213							s_InterruptParameters.
1214							s_FIFOInterruptParameters
1215							[devpriv->
1216							s_InterruptParameters.
1217							ui_Write].
1218							b_OldModuleMask =
1219							1 << b_ModuleCpt;
1220
1221						devpriv->
1222							s_InterruptParameters.
1223							s_FIFOInterruptParameters
1224							[devpriv->
1225							s_InterruptParameters.
1226							ui_Write].
1227							ul_OldCounterLatchValue
1228							= ul_LatchRegisterValue;
1229
1230						devpriv->
1231							s_InterruptParameters.
1232							ul_InterruptOccur++;
1233
1234			     /****************************/
1235						/* 0899/0224 to 1199/0225   */
1236			     /****************************/
1237						/* Increment the write FIFO */
1238			     /****************************/
1239
1240						devpriv->
1241							s_InterruptParameters.
1242							ui_Write = (devpriv->
1243							s_InterruptParameters.
1244							ui_Write +
1245							1) %
1246							APCI1710_SAVE_INTERRUPT;
1247
1248						b_InterruptFlag = 1;
1249
1250				   /**********************/
1251						/* Call user function */
1252				   /**********************/
1253						/* Send a signal to from kernel to user space */
1254						send_sig(SIGIO,
1255							devpriv->tsk_Current,
1256							0);
1257
1258					}
1259				}
1260			}
1261		}		/* pulse encoder */
1262
1263	}
1264	return;
1265
1266}
1267