hwdrv_apci1564.c revision c995fe9475e062bab6f5a45ed28cd2d3d955ef43
1/**
2@verbatim
3
4Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
5
6        ADDI-DATA GmbH
7        Dieselstrasse 3
8        D-77833 Ottersweier
9        Tel: +19(0)7223/9493-0
10        Fax: +49(0)7223/9493-92
11        http://www.addi-data-com
12        info@addi-data.com
13
14This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20You shoud also find the complete GPL in the COPYING file accompanying this source code.
21
22@endverbatim
23*/
24/*
25
26  +-----------------------------------------------------------------------+
27  | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
28  +-----------------------------------------------------------------------+
29  | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
30  | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
31  +-------------------------------+---------------------------------------+
32  | Project     : APCI-1564       | Compiler   : GCC                      |
33  | Module name : hwdrv_apci1564.c| Version    : 2.96                     |
34  +-------------------------------+---------------------------------------+
35  | Project manager: Eric Stolz   | Date       :  02/12/2002              |
36  +-------------------------------+---------------------------------------+
37  | Description :   Hardware Layer Acces For APCI-1564                    |
38  +-----------------------------------------------------------------------+
39  |                             UPDATES                                   |
40  +----------+-----------+------------------------------------------------+
41  |   Date   |   Author  |          Description of updates                |
42  +----------+-----------+------------------------------------------------+
43  |          |           |                                                |
44  |          |           |                                                |
45  |          |           |                                                |
46  +----------+-----------+------------------------------------------------+
47*/
48
49/*
50+----------------------------------------------------------------------------+
51|                               Included files                               |
52+----------------------------------------------------------------------------+
53*/
54
55#include <linux/delay.h>
56#include "hwdrv_apci1564.h"
57
58//Global variables
59UINT ui_InterruptStatus_1564 = 0;
60UINT ui_InterruptData, ui_Type;
61
62/*
63+----------------------------------------------------------------------------+
64| Function   Name   : int i_APCI1564_ConfigDigitalInput                      |
65|			  (comedi_device *dev,comedi_subdevice *s,               |
66|                      comedi_insn *insn,lsampl_t *data)                     |
67+----------------------------------------------------------------------------+
68| Task              : Configures the digital input Subdevice                 |
69+----------------------------------------------------------------------------+
70| Input Parameters  : comedi_device *dev : Driver handle                     |
71|                     lsampl_t *data         : Data Pointer contains         |
72|                                          configuration parameters as below |
73|                                                                            |
74|			  data[0]            : 1 Enable  Digital Input Interrupt |
75|								   0 Disable Digital Input Interrupt |
76|			  data[1]            : 0 ADDIDATA Interrupt OR LOGIC	 |
77|								 : 1 ADDIDATA Interrupt AND LOGIC    |
78|			  data[2]			 : Interrupt mask for the mode 1	 |
79|			  data[3]			 : Interrupt mask for the mode 2	 |
80|																	 |
81+----------------------------------------------------------------------------+
82| Output Parameters :	--													 |
83+----------------------------------------------------------------------------+
84| Return Value      : TRUE  : No error occur                                 |
85|		            : FALSE : Error occur. Return the error          |
86|			                                                         |
87+----------------------------------------------------------------------------+
88*/
89INT i_APCI1564_ConfigDigitalInput(comedi_device * dev, comedi_subdevice * s,
90	comedi_insn * insn, lsampl_t * data)
91{
92	devpriv->tsk_Current = current;
93   /*******************************/
94	/* Set the digital input logic */
95   /*******************************/
96	if (data[0] == ADDIDATA_ENABLE) {
97		data[2] = data[2] << 4;
98		data[3] = data[3] << 4;
99		outl(data[2],
100			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
101			APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
102		outl(data[3],
103			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
104			APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
105		if (data[1] == ADDIDATA_OR) {
106			outl(0x4,
107				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
108				APCI1564_DIGITAL_IP_IRQ);
109		}		// if  (data[1] == ADDIDATA_OR)
110		else {
111			outl(0x6,
112				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
113				APCI1564_DIGITAL_IP_IRQ);
114		}		// else if  (data[1] == ADDIDATA_OR)
115	}			// if  (data[0] == ADDIDATA_ENABLE)
116	else {
117		outl(0x0,
118			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
119			APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
120		outl(0x0,
121			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
122			APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
123		outl(0x0,
124			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
125			APCI1564_DIGITAL_IP_IRQ);
126	}			// else if  (data[0] == ADDIDATA_ENABLE)
127
128	return insn->n;
129}
130
131/*
132+----------------------------------------------------------------------------+
133| Function   Name   : int i_APCI1564_Read1DigitalInput                       |
134|			  (comedi_device *dev,comedi_subdevice *s,               |
135|                      comedi_insn *insn,lsampl_t *data)                     |
136+----------------------------------------------------------------------------+
137| Task              : Return the status of the digital input                 |
138+----------------------------------------------------------------------------+
139| Input Parameters  : comedi_device *dev      : Driver handle                |
140|		              UINT ui_Channel : Channel number to read       |
141|                     lsampl_t *data          : Data Pointer to read status  |
142+----------------------------------------------------------------------------+
143| Output Parameters :	--													 |
144+----------------------------------------------------------------------------+
145| Return Value      : TRUE  : No error occur                                 |
146|		            : FALSE : Error occur. Return the error          |
147|			                                                         |
148+----------------------------------------------------------------------------+
149*/
150INT i_APCI1564_Read1DigitalInput(comedi_device * dev, comedi_subdevice * s,
151	comedi_insn * insn, lsampl_t * data)
152{
153	UINT ui_TmpValue = 0;
154	UINT ui_Channel;
155
156	ui_Channel = CR_CHAN(insn->chanspec);
157	if (ui_Channel >= 0 && ui_Channel <= 31) {
158		ui_TmpValue =
159			(UINT) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
160		//  since only 1 channel reqd  to bring it to last bit it is rotated
161		//  8 +(chan - 1) times then ANDed with 1 for last bit.
162		*data = (ui_TmpValue >> ui_Channel) & 0x1;
163	}			// if  (ui_Channel >= 0 && ui_Channel <=31)
164	else {
165		comedi_error(dev, "Not a valid channel number !!! \n");
166		return -EINVAL;	// "sorry channel spec wrong "
167	}			//else if  (ui_Channel >= 0 && ui_Channel <=31)
168	return insn->n;
169}
170
171/*
172+----------------------------------------------------------------------------+
173| Function   Name   : int i_APCI1564_ReadMoreDigitalInput                    |
174|			  (comedi_device *dev,comedi_subdevice *s,               |
175|                     comedi_insn *insn,lsampl_t *data)                      |
176+----------------------------------------------------------------------------+
177| Task              : Return the status of the Requested digital inputs      |
178+----------------------------------------------------------------------------+
179| Input Parameters  : comedi_device *dev      : Driver handle                |
180|                     UINT ui_NoOfChannels    : No Of Channels To be Read    |
181|                      UINT *data             : Data Pointer to read status  |
182+----------------------------------------------------------------------------+
183| Output Parameters :	--													 |
184+----------------------------------------------------------------------------+
185| Return Value      : TRUE  : No error occur                                 |
186|		            : FALSE : Error occur. Return the error          |
187|			                                                         |
188+----------------------------------------------------------------------------+
189*/
190INT i_APCI1564_ReadMoreDigitalInput(comedi_device * dev, comedi_subdevice * s,
191	comedi_insn * insn, lsampl_t * data)
192{
193	UINT ui_PortValue = data[0];
194	UINT ui_Mask = 0;
195	UINT ui_NoOfChannels;
196
197	ui_NoOfChannels = CR_CHAN(insn->chanspec);
198	if (data[1] == 0) {
199		*data = (UINT) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
200		switch (ui_NoOfChannels) {
201		case 2:
202			ui_Mask = 3;
203			*data = (*data >> (2 * ui_PortValue)) & ui_Mask;
204			break;
205		case 4:
206			ui_Mask = 15;
207			*data = (*data >> (4 * ui_PortValue)) & ui_Mask;
208			break;
209		case 8:
210			ui_Mask = 255;
211			*data = (*data >> (8 * ui_PortValue)) & ui_Mask;
212			break;
213		case 16:
214			ui_Mask = 65535;
215			*data = (*data >> (16 * ui_PortValue)) & ui_Mask;
216			break;
217		case 31:
218			break;
219		default:
220			comedi_error(dev, "Not a valid Channel number !!!\n");
221			return -EINVAL;	// "sorry channel spec wrong "
222			break;
223		}		// switch  (ui_NoOfChannels)
224	}			// if  (data[1]==0)
225	else {
226		if (data[1] == 1) {
227			*data = ui_InterruptStatus_1564;
228		}		// if  (data[1]==1)
229	}			// else if  (data[1]==0)
230	return insn->n;
231}
232
233/*
234+----------------------------------------------------------------------------+
235| Function   Name   : int i_APCI1564_ConfigDigitalOutput                     |
236|			  (comedi_device *dev,comedi_subdevice *s,               |
237|                      comedi_insn *insn,lsampl_t *data)                     |
238+----------------------------------------------------------------------------+
239| Task              : Configures The Digital Output Subdevice.               |
240+----------------------------------------------------------------------------+
241| Input Parameters  : comedi_device *dev : Driver handle                     |
242|                     UINT *data         : Data Pointer contains             |
243|                                          configuration parameters as below |
244|                                                                            |
245|					  data[1]            : 1 Enable  VCC  Interrupt  |
246|										   0 Disable VCC  Interrupt  |
247|					  data[2]            : 1 Enable  CC  Interrupt   |
248|										   0 Disable CC  Interrupt   |
249|																	 |
250+----------------------------------------------------------------------------+
251| Output Parameters :	--													 |
252+----------------------------------------------------------------------------+
253| Return Value      : TRUE  : No error occur                                 |
254|		            : FALSE : Error occur. Return the error          |
255|			                                                         |
256+----------------------------------------------------------------------------+
257*/
258INT i_APCI1564_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s,
259	comedi_insn * insn, lsampl_t * data)
260{
261	ULONG ul_Command = 0;
262
263	if ((data[0] != 0) && (data[0] != 1)) {
264		comedi_error(dev,
265			"Not a valid Data !!! ,Data should be 1 or 0\n");
266		return -EINVAL;
267	}			// if  ((data[0]!=0) && (data[0]!=1))
268	if (data[0]) {
269		devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
270	}			// if  (data[0])
271	else {
272		devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
273	}			// else if  (data[0])
274	if (data[1] == ADDIDATA_ENABLE) {
275		ul_Command = ul_Command | 0x1;
276	}			// if  (data[1] == ADDIDATA_ENABLE)
277	else {
278		ul_Command = ul_Command & 0xFFFFFFFE;
279	}			// else if  (data[1] == ADDIDATA_ENABLE)
280	if (data[2] == ADDIDATA_ENABLE) {
281		ul_Command = ul_Command | 0x2;
282	}			// if  (data[2] == ADDIDATA_ENABLE)
283	else {
284		ul_Command = ul_Command & 0xFFFFFFFD;
285	}			// else if  (data[2] == ADDIDATA_ENABLE)
286	outl(ul_Command,
287		devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
288		APCI1564_DIGITAL_OP_INTERRUPT);
289	ui_InterruptData =
290		inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
291		APCI1564_DIGITAL_OP_INTERRUPT);
292	devpriv->tsk_Current = current;
293	return insn->n;
294}
295
296/*
297+----------------------------------------------------------------------------+
298| Function   Name   : int i_APCI1564_WriteDigitalOutput                      |
299|			  (comedi_device *dev,comedi_subdevice *s,               |
300|                      comedi_insn *insn,lsampl_t *data)                     |
301+----------------------------------------------------------------------------+
302| Task              : Writes port value  To the selected port                |
303+----------------------------------------------------------------------------+
304| Input Parameters  : comedi_device *dev      : Driver handle                |
305|                     UINT ui_NoOfChannels    : No Of Channels To Write      |
306|                     UINT *data              : Data Pointer to read status  |
307+----------------------------------------------------------------------------+
308| Output Parameters :	--													 |
309+----------------------------------------------------------------------------+
310| Return Value      : TRUE  : No error occur                                 |
311|		            : FALSE : Error occur. Return the error          |
312|			                                                         |
313+----------------------------------------------------------------------------+
314*/
315INT i_APCI1564_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s,
316	comedi_insn * insn, lsampl_t * data)
317{
318	UINT ui_Temp, ui_Temp1;
319	UINT ui_NoOfChannel;
320
321	ui_NoOfChannel = CR_CHAN(insn->chanspec);
322	if (devpriv->b_OutputMemoryStatus) {
323		ui_Temp =
324			inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
325			APCI1564_DIGITAL_OP_RW);
326	}			// if  (devpriv->b_OutputMemoryStatus )
327	else {
328		ui_Temp = 0;
329	}			// else if  (devpriv->b_OutputMemoryStatus )
330	if (data[3] == 0) {
331		if (data[1] == 0) {
332			data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
333			outl(data[0],
334				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
335				APCI1564_DIGITAL_OP_RW);
336		}		// if  (data[1]==0)
337		else {
338			if (data[1] == 1) {
339				switch (ui_NoOfChannel) {
340				case 2:
341					data[0] =
342						(data[0] << (2 *
343							data[2])) | ui_Temp;
344					break;
345				case 4:
346					data[0] =
347						(data[0] << (4 *
348							data[2])) | ui_Temp;
349					break;
350				case 8:
351					data[0] =
352						(data[0] << (8 *
353							data[2])) | ui_Temp;
354					break;
355				case 16:
356					data[0] =
357						(data[0] << (16 *
358							data[2])) | ui_Temp;
359					break;
360				case 31:
361					data[0] = data[0] | ui_Temp;
362					break;
363				default:
364					comedi_error(dev, " chan spec wrong");
365					return -EINVAL;	// "sorry channel spec wrong "
366				}	// switch (ui_NoOfChannels)
367				outl(data[0],
368					devpriv->i_IobaseAmcc +
369					APCI1564_DIGITAL_OP +
370					APCI1564_DIGITAL_OP_RW);
371			}	// if  (data[1]==1)
372			else {
373				printk("\nSpecified channel not supported\n");
374			}	// else if  (data[1]==1)
375		}		// else if (data[1]==0)
376	}			//if(data[3]==0)
377	else {
378		if (data[3] == 1) {
379			if (data[1] == 0) {
380				data[0] = ~data[0] & 0x1;
381				ui_Temp1 = 1;
382				ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
383				ui_Temp = ui_Temp | ui_Temp1;
384				data[0] =
385					(data[0] << ui_NoOfChannel) ^
386					0xffffffff;
387				data[0] = data[0] & ui_Temp;
388				outl(data[0],
389					devpriv->i_IobaseAmcc +
390					APCI1564_DIGITAL_OP +
391					APCI1564_DIGITAL_OP_RW);
392			}	// if  (data[1]==0)
393			else {
394				if (data[1] == 1) {
395					switch (ui_NoOfChannel) {
396					case 2:
397						data[0] = ~data[0] & 0x3;
398						ui_Temp1 = 3;
399						ui_Temp1 =
400							ui_Temp1 << 2 * data[2];
401						ui_Temp = ui_Temp | ui_Temp1;
402						data[0] =
403							((data[0] << (2 *
404									data
405									[2])) ^
406							0xffffffff) & ui_Temp;
407						break;
408					case 4:
409						data[0] = ~data[0] & 0xf;
410						ui_Temp1 = 15;
411						ui_Temp1 =
412							ui_Temp1 << 4 * data[2];
413						ui_Temp = ui_Temp | ui_Temp1;
414						data[0] =
415							((data[0] << (4 *
416									data
417									[2])) ^
418							0xffffffff) & ui_Temp;
419						break;
420					case 8:
421						data[0] = ~data[0] & 0xff;
422						ui_Temp1 = 255;
423						ui_Temp1 =
424							ui_Temp1 << 8 * data[2];
425						ui_Temp = ui_Temp | ui_Temp1;
426						data[0] =
427							((data[0] << (8 *
428									data
429									[2])) ^
430							0xffffffff) & ui_Temp;
431						break;
432					case 16:
433						data[0] = ~data[0] & 0xffff;
434						ui_Temp1 = 65535;
435						ui_Temp1 =
436							ui_Temp1 << 16 *
437							data[2];
438						ui_Temp = ui_Temp | ui_Temp1;
439						data[0] =
440							((data[0] << (16 *
441									data
442									[2])) ^
443							0xffffffff) & ui_Temp;
444						break;
445					case 31:
446						break;
447					default:
448						comedi_error(dev,
449							" chan spec wrong");
450						return -EINVAL;	// "sorry channel spec wrong "
451					}	//switch(ui_NoOfChannels)
452					outl(data[0],
453						devpriv->i_IobaseAmcc +
454						APCI1564_DIGITAL_OP +
455						APCI1564_DIGITAL_OP_RW);
456				}	// if  (data[1]==1)
457				else {
458					printk("\nSpecified channel not supported\n");
459				}	// else if  (data[1]==1)
460			}	// else if  (data[1]==0)
461		}		// if  (data[3]==1);
462		else {
463			printk("\nSpecified functionality does not exist\n");
464			return -EINVAL;
465		}		// else if (data[3]==1)
466	}			// else if (data[3]==0)
467	return insn->n;
468}
469
470/*
471+----------------------------------------------------------------------------+
472| Function   Name   : int i_APCI1564_ReadDigitalOutput                       |
473|			  (comedi_device *dev,comedi_subdevice *s,               |
474|                      comedi_insn *insn,lsampl_t *data)                     |
475+----------------------------------------------------------------------------+
476| Task              : Read  value  of the selected channel or port           |
477+----------------------------------------------------------------------------+
478| Input Parameters  : comedi_device *dev      : Driver handle                |
479|                     UINT ui_NoOfChannels    : No Of Channels To read       |
480|                     UINT *data              : Data Pointer to read status  |
481+----------------------------------------------------------------------------+
482| Output Parameters :	--													 |
483+----------------------------------------------------------------------------+
484| Return Value      : TRUE  : No error occur                                 |
485|		            : FALSE : Error occur. Return the error          |
486|			                                                         |
487+----------------------------------------------------------------------------+
488*/
489INT i_APCI1564_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s,
490	comedi_insn * insn, lsampl_t * data)
491{
492	UINT ui_Temp;
493	UINT ui_NoOfChannel;
494
495	ui_NoOfChannel = CR_CHAN(insn->chanspec);
496	ui_Temp = data[0];
497	*data = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
498		APCI1564_DIGITAL_OP_RW);
499	if (ui_Temp == 0) {
500		*data = (*data >> ui_NoOfChannel) & 0x1;
501	}			// if  (ui_Temp==0)
502	else {
503		if (ui_Temp == 1) {
504			switch (ui_NoOfChannel) {
505			case 2:
506				*data = (*data >> (2 * data[1])) & 3;
507				break;
508
509			case 4:
510				*data = (*data >> (4 * data[1])) & 15;
511				break;
512
513			case 8:
514				*data = (*data >> (8 * data[1])) & 255;
515				break;
516
517			case 16:
518				*data = (*data >> (16 * data[1])) & 65535;
519				break;
520
521			case 31:
522				break;
523
524			default:
525				comedi_error(dev, " chan spec wrong");
526				return -EINVAL;	// "sorry channel spec wrong "
527				break;
528			}	// switch(ui_NoOfChannels)
529		}		// if  (ui_Temp==1)
530		else {
531			printk("\nSpecified channel not supported \n");
532		}		// else if (ui_Temp==1)
533	}			// else if  (ui_Temp==0)
534	return insn->n;
535}
536
537/*
538+----------------------------------------------------------------------------+
539| Function   Name   : int i_APCI1564_ConfigTimerCounterWatchdog              |
540|			  (comedi_device *dev,comedi_subdevice *s,               |
541|                      comedi_insn *insn,lsampl_t *data)                     |
542+----------------------------------------------------------------------------+
543| Task              : Configures The Timer , Counter or Watchdog             |
544+----------------------------------------------------------------------------+
545| Input Parameters  : comedi_device *dev : Driver handle                     |
546|                     UINT *data         : Data Pointer contains             |
547|                                          configuration parameters as below |
548|                                                                            |
549|					  data[0]            : 0 Configure As Timer      |
550|										   1 Configure As Counter    |
551|										   2 Configure As Watchdog   |
552|					  data[1]            : 1 Enable  Interrupt       |
553|										   0 Disable Interrupt 	     |
554|					  data[2]            : Time Unit                 |
555|					  data[3]			 : Reload Value			     |
556|					  data[4]            : Timer Mode             	 |
557|					  data[5]			 : Timer Counter Watchdog Number|
558                              data[6]            :  Counter Direction
559+----------------------------------------------------------------------------+
560| Output Parameters :	--													 |
561+----------------------------------------------------------------------------+
562| Return Value      : TRUE  : No error occur                                 |
563|		            : FALSE : Error occur. Return the error          |
564|			                                                         |
565+----------------------------------------------------------------------------+
566*/
567INT i_APCI1564_ConfigTimerCounterWatchdog(comedi_device * dev,
568	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
569{
570	ULONG ul_Command1 = 0;
571	devpriv->tsk_Current = current;
572	if (data[0] == ADDIDATA_WATCHDOG) {
573		devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
574
575		//Disable the watchdog
576		outl(0x0,
577			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
578			APCI1564_TCW_PROG);
579		//Loading the Reload value
580		outl(data[3],
581			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
582			APCI1564_TCW_RELOAD_VALUE);
583	}			// if  (data[0]==ADDIDATA_WATCHDOG)
584	else if (data[0] == ADDIDATA_TIMER) {
585		//First Stop The Timer
586		ul_Command1 =
587			inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
588			APCI1564_TCW_PROG);
589		ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
590		outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);	//Stop The Timer
591
592		devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
593		if (data[1] == 1) {
594			outl(0x02, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);	//Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
595			outl(0x0,
596				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
597				APCI1564_DIGITAL_IP_IRQ);
598			outl(0x0,
599				devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
600				APCI1564_DIGITAL_OP_IRQ);
601			outl(0x0,
602				devpriv->i_IobaseAmcc +
603				APCI1564_DIGITAL_OP_WATCHDOG +
604				APCI1564_TCW_IRQ);
605			outl(0x0,
606				devpriv->iobase + APCI1564_COUNTER1 +
607				APCI1564_TCW_IRQ);
608			outl(0x0,
609				devpriv->iobase + APCI1564_COUNTER2 +
610				APCI1564_TCW_IRQ);
611			outl(0x0,
612				devpriv->iobase + APCI1564_COUNTER3 +
613				APCI1564_TCW_IRQ);
614			outl(0x0,
615				devpriv->iobase + APCI1564_COUNTER4 +
616				APCI1564_TCW_IRQ);
617		}		// if  (data[1]==1)
618		else {
619			outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);	//disable Timer interrupt
620		}		// else if  (data[1]==1)
621
622		// Loading Timebase
623
624		outl(data[2],
625			devpriv->i_IobaseAmcc + APCI1564_TIMER +
626			APCI1564_TCW_TIMEBASE);
627
628		//Loading the Reload value
629		outl(data[3],
630			devpriv->i_IobaseAmcc + APCI1564_TIMER +
631			APCI1564_TCW_RELOAD_VALUE);
632
633		ul_Command1 =
634			inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
635			APCI1564_TCW_PROG);
636		ul_Command1 =
637			(ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
638		outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);	//mode 2
639	}			// else if  (data[0]==ADDIDATA_TIMER)
640	else if (data[0] == ADDIDATA_COUNTER) {
641		devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
642		devpriv->b_ModeSelectRegister = data[5];
643
644		//First Stop The Counter
645		ul_Command1 =
646			inl(devpriv->iobase + ((data[5] - 1) * 0x20) +
647			APCI1564_TCW_PROG);
648		ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
649		outl(ul_Command1, devpriv->iobase + ((data[5] - 1) * 0x20) + APCI1564_TCW_PROG);	//Stop The Timer
650
651      /************************/
652		/* Set the reload value */
653      /************************/
654		outl(data[3],
655			devpriv->iobase + ((data[5] - 1) * 0x20) +
656			APCI1564_TCW_RELOAD_VALUE);
657
658      /******************************/
659		/* Set the mode :             */
660		/* - Disable the hardware     */
661		/* - Disable the counter mode */
662		/* - Disable the warning      */
663		/* - Disable the reset        */
664		/* - Disable the timer mode   */
665		/* - Enable the counter mode  */
666      /******************************/
667		ul_Command1 =
668			(ul_Command1 & 0xFFFC19E2UL) | 0x80000UL |
669			(ULONG) ((ULONG) data[4] << 16UL);
670		outl(ul_Command1,
671			devpriv->iobase + ((data[5] - 1) * 0x20) +
672			APCI1564_TCW_PROG);
673
674		// Enable or Disable Interrupt
675		ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
676		outl(ul_Command1,
677			devpriv->iobase + ((data[5] - 1) * 0x20) +
678			APCI1564_TCW_PROG);
679
680      /*****************************/
681		/* Set the Up/Down selection */
682      /*****************************/
683		ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
684		outl(ul_Command1,
685			devpriv->iobase + ((data[5] - 1) * 0x20) +
686			APCI1564_TCW_PROG);
687	}			// else if  (data[0]==ADDIDATA_COUNTER)
688	else {
689		printk(" Invalid subdevice.");
690	}			// else if  (data[0]==ADDIDATA_WATCHDOG)
691
692	return insn->n;
693}
694
695/*
696+----------------------------------------------------------------------------+
697| Function   Name   : int i_APCI1564_StartStopWriteTimerCounterWatchdog      |
698|			  (comedi_device *dev,comedi_subdevice *s,               |
699|                      comedi_insn *insn,lsampl_t *data)                     |
700+----------------------------------------------------------------------------+
701| Task              : Start / Stop The Selected Timer , Counter or Watchdog  |
702+----------------------------------------------------------------------------+
703| Input Parameters  : comedi_device *dev : Driver handle                     |
704|                     UINT *data         : Data Pointer contains             |
705|                                          configuration parameters as below |
706|                                                                            |
707|					  data[0]            : 0 Timer                   |
708|										   1 Counter                 |
709|										   2 Watchdog        		 |                             |					         data[1]            : 1 Start                   |
710|										   0 Stop                    |
711|                                                  2 Trigger             	 |
712|                                                    Clear (Only Counter)    |
713+----------------------------------------------------------------------------+
714| Output Parameters :	--													 |
715+----------------------------------------------------------------------------+
716| Return Value      : TRUE  : No error occur                                 |
717|		            : FALSE : Error occur. Return the error          |
718|			                                                         |
719+----------------------------------------------------------------------------+
720*/
721INT i_APCI1564_StartStopWriteTimerCounterWatchdog(comedi_device * dev,
722	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
723{
724	ULONG ul_Command1 = 0;
725	if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
726		switch (data[1]) {
727		case 0:	//stop the watchdog
728			outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_PROG);	//disable the watchdog
729			break;
730		case 1:	//start the watchdog
731			outl(0x0001,
732				devpriv->i_IobaseAmcc +
733				APCI1564_DIGITAL_OP_WATCHDOG +
734				APCI1564_TCW_PROG);
735			break;
736		case 2:	//Software trigger
737			outl(0x0201,
738				devpriv->i_IobaseAmcc +
739				APCI1564_DIGITAL_OP_WATCHDOG +
740				APCI1564_TCW_PROG);
741			break;
742		default:
743			printk("\nSpecified functionality does not exist\n");
744			return -EINVAL;
745		}		// switch (data[1])
746	}			// if  (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
747	if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
748		if (data[1] == 1) {
749			ul_Command1 =
750				inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
751				APCI1564_TCW_PROG);
752			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
753
754			//Enable the Timer
755			outl(ul_Command1,
756				devpriv->i_IobaseAmcc + APCI1564_TIMER +
757				APCI1564_TCW_PROG);
758		}		// if  (data[1]==1)
759		else if (data[1] == 0) {
760			//Stop The Timer
761
762			ul_Command1 =
763				inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
764				APCI1564_TCW_PROG);
765			ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
766			outl(ul_Command1,
767				devpriv->i_IobaseAmcc + APCI1564_TIMER +
768				APCI1564_TCW_PROG);
769		}		// else if(data[1]==0)
770	}			// if  (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
771	if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
772		ul_Command1 =
773			inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
774					1) * 0x20) + APCI1564_TCW_PROG);
775		if (data[1] == 1) {
776			//Start the Counter subdevice
777			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
778		}		// if  (data[1] == 1)
779		else if (data[1] == 0) {
780			// Stops the Counter subdevice
781			ul_Command1 = 0;
782
783		}		// else if  (data[1] == 0)
784		else if (data[1] == 2) {
785			// Clears the Counter subdevice
786			ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
787		}		// else if  (data[1] == 3)
788		outl(ul_Command1,
789			devpriv->iobase + ((devpriv->b_ModeSelectRegister -
790					1) * 0x20) + APCI1564_TCW_PROG);
791	}			// if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
792	return insn->n;
793}
794
795/*
796+----------------------------------------------------------------------------+
797| Function   Name   : int i_APCI1564_ReadTimerCounterWatchdog                |
798|			  (comedi_device *dev,comedi_subdevice *s,               |
799|                      comedi_insn *insn,lsampl_t *data)                     |
800+----------------------------------------------------------------------------+
801| Task              : Read The Selected Timer , Counter or Watchdog          |
802+----------------------------------------------------------------------------+
803| Input Parameters  : comedi_device *dev : Driver handle                     |
804|                     UINT *data         : Data Pointer contains             |
805|                                          configuration parameters as below |
806|                                                                            |
807
808+----------------------------------------------------------------------------+
809| Output Parameters :	--													 |
810+----------------------------------------------------------------------------+
811| Return Value      : TRUE  : No error occur                                 |
812|		            : FALSE : Error occur. Return the error          |
813|			                                                         |
814+----------------------------------------------------------------------------+
815*/
816INT i_APCI1564_ReadTimerCounterWatchdog(comedi_device * dev,
817	comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
818{
819	ULONG ul_Command1 = 0;
820
821	if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
822		// Stores the status of the Watchdog
823		data[0] =
824			inl(devpriv->i_IobaseAmcc +
825			APCI1564_DIGITAL_OP_WATCHDOG +
826			APCI1564_TCW_TRIG_STATUS) & 0x1;
827		data[1] =
828			inl(devpriv->i_IobaseAmcc +
829			APCI1564_DIGITAL_OP_WATCHDOG);
830	}			// if  (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
831	else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
832		// Stores the status of the Timer
833		data[0] =
834			inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
835			APCI1564_TCW_TRIG_STATUS) & 0x1;
836
837		// Stores the Actual value of the Timer
838		data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER);
839	}			// else if  (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
840	else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
841		// Read the Counter Actual Value.
842		data[0] =
843			inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
844					1) * 0x20) +
845			APCI1564_TCW_SYNC_ENABLEDISABLE);
846		ul_Command1 =
847			inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
848					1) * 0x20) + APCI1564_TCW_TRIG_STATUS);
849
850      /***********************************/
851		/* Get the software trigger status */
852      /***********************************/
853		data[1] = (BYTE) ((ul_Command1 >> 1) & 1);
854
855      /***********************************/
856		/* Get the hardware trigger status */
857      /***********************************/
858		data[2] = (BYTE) ((ul_Command1 >> 2) & 1);
859
860      /*********************************/
861		/* Get the software clear status */
862      /*********************************/
863		data[3] = (BYTE) ((ul_Command1 >> 3) & 1);
864
865      /***************************/
866		/* Get the overflow status */
867      /***************************/
868		data[4] = (BYTE) ((ul_Command1 >> 0) & 1);
869	}			// else  if  (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
870	else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
871		&& (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)
872		&& (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) {
873		printk("\n Invalid Subdevice !!!\n");
874	}			// else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG)&& (devpriv->b_TimerSelectMode!=ADDIDATA_COUNTER))
875	return insn->n;
876}
877
878/*
879+----------------------------------------------------------------------------+
880| Function   Name   :  int i_APCI1564_ReadInterruptStatus                    |
881|			  (comedi_device *dev,comedi_subdevice *s,               |
882|                      comedi_insn *insn,lsampl_t *data)                     |
883+----------------------------------------------------------------------------+
884| Task              :Reads the interrupt status register                     |
885+----------------------------------------------------------------------------+
886| Input Parameters  :                                                        |
887+----------------------------------------------------------------------------+
888| Output Parameters :	--													 |
889+----------------------------------------------------------------------------+
890| Return Value      :                                                        |
891|			                                                         |
892+----------------------------------------------------------------------------+
893*/
894
895int i_APCI1564_ReadInterruptStatus(comedi_device * dev, comedi_subdevice * s,
896	comedi_insn * insn, lsampl_t * data)
897{
898	*data = ui_Type;
899	return insn->n;
900}
901
902/*
903+----------------------------------------------------------------------------+
904| Function   Name   : static void v_APCI1564_Interrupt					     |
905|					  (int irq , void *d)      |
906+----------------------------------------------------------------------------+
907| Task              : Interrupt handler for the interruptible digital inputs |
908+----------------------------------------------------------------------------+
909| Input Parameters  : int irq                 : irq number                   |
910|                     void *d                 : void pointer                 |
911+----------------------------------------------------------------------------+
912| Output Parameters :	--													 |
913+----------------------------------------------------------------------------+
914| Return Value      : TRUE  : No error occur                                 |
915|		            : FALSE : Error occur. Return the error          |
916|			                                                         |
917+----------------------------------------------------------------------------+
918*/
919static VOID v_APCI1564_Interrupt(int irq, void *d)
920{
921	comedi_device *dev = d;
922	UINT ui_DO, ui_DI;
923	UINT ui_Timer;
924	UINT ui_C1, ui_C2, ui_C3, ui_C4;
925	ULONG ul_Command2 = 0;
926	ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
927		APCI1564_DIGITAL_IP_IRQ) & 0x01;
928	ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
929		APCI1564_DIGITAL_OP_IRQ) & 0x01;
930	ui_Timer =
931		inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
932		APCI1564_TCW_IRQ) & 0x01;
933	ui_C1 = inl(devpriv->iobase + APCI1564_COUNTER1 +
934		APCI1564_TCW_IRQ) & 0x1;
935	ui_C2 = inl(devpriv->iobase + APCI1564_COUNTER2 +
936		APCI1564_TCW_IRQ) & 0x1;
937	ui_C3 = inl(devpriv->iobase + APCI1564_COUNTER3 +
938		APCI1564_TCW_IRQ) & 0x1;
939	ui_C4 = inl(devpriv->iobase + APCI1564_COUNTER4 +
940		APCI1564_TCW_IRQ) & 0x1;
941	if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
942		&& ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
943		printk("\nInterrupt from unknown source\n");
944	}			// if(ui_DI==0 && ui_DO==0 && ui_Timer==0 && ui_C1==0 && ui_C2==0 && ui_C3==0 && ui_C4==0)
945
946	if (ui_DI == 1) {
947		ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
948			APCI1564_DIGITAL_IP_IRQ);
949		outl(0x0,
950			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
951			APCI1564_DIGITAL_IP_IRQ);
952		ui_InterruptStatus_1564 =
953			inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
954			APCI1564_DIGITAL_IP_INTERRUPT_STATUS);
955		ui_InterruptStatus_1564 = ui_InterruptStatus_1564 & 0X000FFFF0;
956		send_sig(SIGIO, devpriv->tsk_Current, 0);	// send signal to the sample
957		outl(ui_DI, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ);	//enable the interrupt
958		return;
959	}
960
961	if (ui_DO == 1) {
962		// Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
963		ui_Type =
964			inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
965			APCI1564_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
966		//Disable the  Interrupt
967		outl(0x0,
968			devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
969			APCI1564_DIGITAL_OP_INTERRUPT);
970
971		//Sends signal to user space
972		send_sig(SIGIO, devpriv->tsk_Current, 0);
973
974	}			// if  (ui_DO)
975
976	if ((ui_Timer == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_TIMER)) {
977		// Disable Timer Interrupt
978		ul_Command2 =
979			inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
980			APCI1564_TCW_PROG);
981		outl(0x0,
982			devpriv->i_IobaseAmcc + APCI1564_TIMER +
983			APCI1564_TCW_PROG);
984
985		//Send a signal to from kernel to user space
986		send_sig(SIGIO, devpriv->tsk_Current, 0);
987
988		// Enable Timer Interrupt
989
990		outl(ul_Command2,
991			devpriv->i_IobaseAmcc + APCI1564_TIMER +
992			APCI1564_TCW_PROG);
993	}			// if  ((ui_Timer == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_TIMER))
994
995	if ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
996		// Disable Counter Interrupt
997		ul_Command2 =
998			inl(devpriv->iobase + APCI1564_COUNTER1 +
999			APCI1564_TCW_PROG);
1000		outl(0x0,
1001			devpriv->iobase + APCI1564_COUNTER1 +
1002			APCI1564_TCW_PROG);
1003
1004		//Send a signal to from kernel to user space
1005		send_sig(SIGIO, devpriv->tsk_Current, 0);
1006
1007		// Enable Counter Interrupt
1008		outl(ul_Command2,
1009			devpriv->iobase + APCI1564_COUNTER1 +
1010			APCI1564_TCW_PROG);
1011	}			// if  ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER))
1012
1013	if ((ui_C2 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
1014		// Disable Counter Interrupt
1015		ul_Command2 =
1016			inl(devpriv->iobase + APCI1564_COUNTER2 +
1017			APCI1564_TCW_PROG);
1018		outl(0x0,
1019			devpriv->iobase + APCI1564_COUNTER2 +
1020			APCI1564_TCW_PROG);
1021
1022		//Send a signal to from kernel to user space
1023		send_sig(SIGIO, devpriv->tsk_Current, 0);
1024
1025		// Enable Counter Interrupt
1026		outl(ul_Command2,
1027			devpriv->iobase + APCI1564_COUNTER2 +
1028			APCI1564_TCW_PROG);
1029	}			// if  ((ui_C2 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
1030
1031	if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
1032		// Disable Counter Interrupt
1033		ul_Command2 =
1034			inl(devpriv->iobase + APCI1564_COUNTER3 +
1035			APCI1564_TCW_PROG);
1036		outl(0x0,
1037			devpriv->iobase + APCI1564_COUNTER3 +
1038			APCI1564_TCW_PROG);
1039
1040		//Send a signal to from kernel to user space
1041		send_sig(SIGIO, devpriv->tsk_Current, 0);
1042
1043		// Enable Counter Interrupt
1044		outl(ul_Command2,
1045			devpriv->iobase + APCI1564_COUNTER3 +
1046			APCI1564_TCW_PROG);
1047	}			// if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
1048
1049	if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
1050		// Disable Counter Interrupt
1051		ul_Command2 =
1052			inl(devpriv->iobase + APCI1564_COUNTER4 +
1053			APCI1564_TCW_PROG);
1054		outl(0x0,
1055			devpriv->iobase + APCI1564_COUNTER4 +
1056			APCI1564_TCW_PROG);
1057
1058		//Send a signal to from kernel to user space
1059		send_sig(SIGIO, devpriv->tsk_Current, 0);
1060
1061		// Enable Counter Interrupt
1062		outl(ul_Command2,
1063			devpriv->iobase + APCI1564_COUNTER4 +
1064			APCI1564_TCW_PROG);
1065	}			// if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
1066	return;
1067}
1068
1069/*
1070+----------------------------------------------------------------------------+
1071| Function   Name   : int i_APCI1564_Reset(comedi_device *dev)               |                                                       |
1072+----------------------------------------------------------------------------+
1073| Task              :resets all the registers                                |
1074+----------------------------------------------------------------------------+
1075| Input Parameters  : comedi_device *dev
1076+----------------------------------------------------------------------------+
1077| Output Parameters :	--													 |
1078+----------------------------------------------------------------------------+
1079| Return Value      :                                                        |
1080|			                                                         |
1081+----------------------------------------------------------------------------+
1082*/
1083
1084INT i_APCI1564_Reset(comedi_device * dev)
1085{
1086	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ);	//disable the interrupts
1087	inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS);	//Reset the interrupt status register
1088	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1);	//Disable the and/or interrupt
1089	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
1090	devpriv->b_DigitalOutputRegister = 0;
1091	ui_Type = 0;
1092	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP);	//Resets the output channels
1093	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_INTERRUPT);	//Disables the interrupt.
1094	outl(0x0,
1095		devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
1096		APCI1564_TCW_RELOAD_VALUE);
1097	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER);
1098	outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
1099
1100	outl(0x0, devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
1101	outl(0x0, devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
1102	outl(0x0, devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
1103	outl(0x0, devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);
1104	return 0;
1105}
1106