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