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