Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ericvh...
[pandora-kernel.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 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 */
59 static unsigned int ui_InterruptStatus_1564 = 0;
60 static 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 */
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 |                             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 */
150 int 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 */
192 int 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 */
260 int 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 */
317 int 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 */
491 int 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 */
569 int 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 */
723 int 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 */
818 int 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
897 int 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 */
921 static 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
1107 int 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 }