Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux...
[sfrench/cifs-2.6.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci1564.c
1 /**
2 @verbatim
3
4 Copyright (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
14 This 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
16 This 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
18 You 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
20 You 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
59 UINT ui_InterruptStatus_1564 = 0;
60 UINT 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 */
89 INT 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 |                             UINT 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 */
150 INT i_APCI1564_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
151         struct comedi_insn * insn, unsigned int * 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 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
175 |                     struct comedi_insn *insn,unsigned int *data)                      |
176 +----------------------------------------------------------------------------+
177 | Task              : Return the status of the Requested digital inputs      |
178 +----------------------------------------------------------------------------+
179 | Input Parameters  : struct 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 */
190 INT i_APCI1564_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
191         struct comedi_insn * insn, unsigned int * 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 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
237 |                      struct comedi_insn *insn,unsigned int *data)                     |
238 +----------------------------------------------------------------------------+
239 | Task              : Configures The Digital Output Subdevice.               |
240 +----------------------------------------------------------------------------+
241 | Input Parameters  : struct 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 */
258 INT i_APCI1564_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
259         struct comedi_insn * insn, unsigned int * 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 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
300 |                      struct comedi_insn *insn,unsigned int *data)                     |
301 +----------------------------------------------------------------------------+
302 | Task              : Writes port value  To the selected port                |
303 +----------------------------------------------------------------------------+
304 | Input Parameters  : struct 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 */
315 INT i_APCI1564_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
316         struct comedi_insn * insn, unsigned int * 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 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
474 |                      struct comedi_insn *insn,unsigned int *data)                     |
475 +----------------------------------------------------------------------------+
476 | Task              : Read  value  of the selected channel or port           |
477 +----------------------------------------------------------------------------+
478 | Input Parameters  : struct 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 */
489 INT i_APCI1564_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
490         struct comedi_insn * insn, unsigned int * 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 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
541 |                      struct comedi_insn *insn,unsigned int *data)                     |
542 +----------------------------------------------------------------------------+
543 | Task              : Configures The Timer , Counter or Watchdog             |
544 +----------------------------------------------------------------------------+
545 | Input Parameters  : struct 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 */
567 INT i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device * dev,
568         struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * 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 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
699 |                      struct comedi_insn *insn,unsigned int *data)                     |
700 +----------------------------------------------------------------------------+
701 | Task              : Start / Stop The Selected Timer , Counter or Watchdog  |
702 +----------------------------------------------------------------------------+
703 | Input Parameters  : struct 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 */
721 INT i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev,
722         struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * 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 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
799 |                      struct comedi_insn *insn,unsigned int *data)                     |
800 +----------------------------------------------------------------------------+
801 | Task              : Read The Selected Timer , Counter or Watchdog          |
802 +----------------------------------------------------------------------------+
803 | Input Parameters  : struct 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 */
816 INT i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device * dev,
817         struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * 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 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
882 |                      struct comedi_insn *insn,unsigned int *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
895 int i_APCI1564_ReadInterruptStatus(struct comedi_device * dev, struct comedi_subdevice * s,
896         struct comedi_insn * insn, unsigned int * 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 */
919 static void v_APCI1564_Interrupt(int irq, void *d)
920 {
921         struct 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(struct comedi_device *dev)               |                                                       |
1072 +----------------------------------------------------------------------------+
1073 | Task              :resets all the registers                                |
1074 +----------------------------------------------------------------------------+
1075 | Input Parameters  : struct comedi_device *dev
1076 +----------------------------------------------------------------------------+
1077 | Output Parameters :   --                                                                                                       |
1078 +----------------------------------------------------------------------------+
1079 | Return Value      :                                                        |
1080 |                                                                                |
1081 +----------------------------------------------------------------------------+
1082 */
1083
1084 INT i_APCI1564_Reset(struct 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 }