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