Merge branch 'staging-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[pandora-kernel.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci1500.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-1500       | Compiler   : GCC                      |
33   | Module name : hwdrv_apci1500.c| Version    : 2.96                     |
34   +-------------------------------+---------------------------------------+
35   | Project manager: Eric Stolz   | Date       :  02/12/2002              |
36   +-------------------------------+---------------------------------------+
37   | Description :   Hardware Layer Access For APCI-1500                   |
38   +-----------------------------------------------------------------------+
39   |                             UPDATES                                   |
40   +----------+-----------+------------------------------------------------+
41   |   Date   |   Author  |          Description of updates                |
42   +----------+-----------+------------------------------------------------+
43   |          |           |                                                |
44   |          |           |                                                |
45   |          |           |                                                |
46   +----------+-----------+------------------------------------------------+
47 */
48 #include "hwdrv_apci1500.h"
49
50 static int i_TimerCounter1Init = 0;
51 static int i_TimerCounter2Init = 0;
52 static int i_WatchdogCounter3Init = 0;
53 static int i_Event1Status = 0, i_Event2Status = 0;
54 static int i_TimerCounterWatchdogInterrupt = 0;
55 static int i_Logic = 0, i_CounterLogic = 0;
56 static int i_InterruptMask = 0;
57 static int i_InputChannel = 0;
58 static int i_TimerCounter1Enabled = 0, i_TimerCounter2Enabled = 0,
59            i_WatchdogCounter3Enabled = 0;
60
61 /*
62   +----------------------------------------------------------------------------+
63 | Function   Name   : int i_APCI1500_ConfigDigitalInputEvent                 |
64 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
65 |                      struct comedi_insn *insn,unsigned int *data)                     |
66 +----------------------------------------------------------------------------+
67 | Task              : An event can be generated for each port.               |
68 |                     The first event is related to the first 8 channels     |
69 |                     (port 1) and the second to the following 6 channels    |
70 |                     (port 2). An interrupt is generated when one or both   |
71 |                     events have occurred                                   |
72 +----------------------------------------------------------------------------+
73 | Input Parameters  : struct comedi_device *dev : Driver handle                     |
74 |                     unsigned int *data     : Data Pointer contains             |
75 |                                          configuration parameters as below |
76 |                                                                            |
77 |                         data[0]            :Number of the input port on        |
78 |                                         which the event will take place    |
79 |                                         (1 or 2)
80 |                      data[1]            : The event logic for port 1 has    |
81 |                                            three possibilities             |
82 |                                        :0  APCI1500_AND       :This logic  |
83 |                                                                links       |
84 |                                                                the inputs  |
85 |                                                                with an AND |
86 |                                                                logic.      |
87 |                                          1 APCI1500_OR        :This logic  |
88 |                                                                links       |
89 |                                                                the inputs  |
90 |                                                                with a      |
91 |                                                                OR logic.   |
92 |                                          2    APCI1500_OR_PRIORITY        |
93 |                                                               :This logic                          |
94 |                                                                links       |
95 |                                                                the inputs  |
96 |                                                                with a      |
97 |                                                                priority    |
98 |                                                                OR logic.   |
99 |                                                                Input 1     |
100 |                                                                has the     |
101 |                                                                highest     |
102 |                                                                priority    |
103 |                                                                level and   |
104 |                                                                input   8   |
105 |                                                                the smallest|
106 |                                            For the second port the user has|
107 |                                            1 possibility:                  |
108 |                                            APCI1500_OR        :This logic  |
109 |                                                                links       |
110 |                                                                the inputs  |
111 |                                                                with a      |
112 |                                                                polarity    |
113 |                                                                OR logic    |
114 |                     data[2]              : These 8-character word for port1|
115 |                                            and 6-character word for port 2 |
116 |                                            give the mask of the event.     |
117 |                                            Each place gives the state      |
118 |                                            of the input channels and can   |
119 |                                            have one of these six characters|
120 |                                                     |
121 |                                       0  : This input must be on 0         |
122 |                                       1  : This input must be on 1         |
123 |                                       2  : This input reacts to            |
124 |                                            a falling edge                  |
125 |                                       3  : This input reacts to a          |
126 |                                            rising edge                     |
127 |                                       4  : This input reacts to both edges |
128 |
129 |                                                               5  : This input is not               |
130 |                                            used for event                              |
131 +----------------------------------------------------------------------------+
132 | Output Parameters :   --                                                                                                       |
133 +----------------------------------------------------------------------------+
134 | Return Value      : TRUE  : No error occur                                 |
135 |                           : FALSE : Error occur. Return the error          |
136 |                                                                                |
137 +----------------------------------------------------------------------------+
138 */
139 static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev,
140                                               struct comedi_subdevice *s,
141                                               struct comedi_insn *insn,
142                                               unsigned int *data)
143 {
144         int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0;
145         int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0;
146         int i_PatternTransitionCount = 0, i_RegValue;
147         int i;
148
149       /*************************************************/
150         /* Selects the master interrupt control register */
151       /*************************************************/
152         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
153                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
154       /**********************************************/
155         /* Disables  the main interrupt on the board */
156       /**********************************************/
157         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
158
159         if (data[0] == 1) {
160                 i_MaxChannel = 8;
161         }                       /*  if (data[0] == 1) */
162         else {
163                 if (data[0] == 2) {
164                         i_MaxChannel = 6;
165                 }               /*  if(data[0]==2) */
166                 else {
167                         printk("\nThe specified port event  does not exist\n");
168                         return -EINVAL;
169                 }               /* else if(data[0]==2) */
170         }                       /* else  if (data[0] == 1) */
171         switch (data[1]) {
172         case 0:
173                 data[1] = APCI1500_AND;
174                 break;
175         case 1:
176                 data[1] = APCI1500_OR;
177                 break;
178         case 2:
179                 data[1] = APCI1500_OR_PRIORITY;
180                 break;
181         default:
182                 printk("\nThe specified interrupt logic does not exist\n");
183                 return -EINVAL;
184         }                       /* switch(data[1]); */
185
186         i_Logic = data[1];
187         for (i_Count = i_MaxChannel, i = 0; i_Count > 0; i_Count--, i++) {
188                 i_EventMask = data[2 + i];
189                 switch (i_EventMask) {
190                 case 0:
191                         i_PatternMask =
192                                 i_PatternMask | (1 << (i_MaxChannel - i_Count));
193                         break;
194                 case 1:
195                         i_PatternMask =
196                                 i_PatternMask | (1 << (i_MaxChannel - i_Count));
197                         i_PatternPolarity =
198                                 i_PatternPolarity | (1 << (i_MaxChannel -
199                                         i_Count));
200                         break;
201                 case 2:
202                         i_PatternMask =
203                                 i_PatternMask | (1 << (i_MaxChannel - i_Count));
204                         i_PatternTransition =
205                                 i_PatternTransition | (1 << (i_MaxChannel -
206                                         i_Count));
207                         break;
208                 case 3:
209                         i_PatternMask =
210                                 i_PatternMask | (1 << (i_MaxChannel - i_Count));
211                         i_PatternPolarity =
212                                 i_PatternPolarity | (1 << (i_MaxChannel -
213                                         i_Count));
214                         i_PatternTransition =
215                                 i_PatternTransition | (1 << (i_MaxChannel -
216                                         i_Count));
217                         break;
218                 case 4:
219                         i_PatternTransition =
220                                 i_PatternTransition | (1 << (i_MaxChannel -
221                                         i_Count));
222                         break;
223                 case 5:
224                         break;
225                 default:
226                         printk("\nThe option indicated in the event mask does not exist\n");
227                         return -EINVAL;
228                 }               /*  switch(i_EventMask) */
229         }                       /* for (i_Count = i_MaxChannel; i_Count >0;i_Count --) */
230
231         if (data[0] == 1) {
232                     /****************************/
233                 /* Test the interrupt logic */
234                     /****************************/
235
236                 if (data[1] == APCI1500_AND ||
237                         data[1] == APCI1500_OR ||
238                         data[1] == APCI1500_OR_PRIORITY) {
239                        /**************************************/
240                         /* Tests if a transition was declared */
241                         /* for a OR PRIORITY logic            */
242                        /**************************************/
243
244                         if (data[1] == APCI1500_OR_PRIORITY
245                                 && i_PatternTransition != 0) {
246                               /********************************************/
247                                 /* Transition error on an OR PRIORITY logic */
248                               /********************************************/
249                                 printk("\nTransition error on an OR PRIORITY logic\n");
250                                 return -EINVAL;
251                         }       /*  if (data[1]== APCI1500_OR_PRIORITY && i_PatternTransition != 0) */
252
253                        /*************************************/
254                         /* Tests if more than one transition */
255                         /* was declared for an AND logic     */
256                        /*************************************/
257
258                         if (data[1] == APCI1500_AND) {
259                                 for (i_Count = 0; i_Count < 8; i_Count++) {
260                                         i_PatternTransitionCount =
261                                                 i_PatternTransitionCount +
262                                                 ((i_PatternTransition >>
263                                                         i_Count) & 0x1);
264
265                                 }       /* for (i_Count = 0; i_Count < 8; i_Count++) */
266
267                                 if (i_PatternTransitionCount > 1) {
268                                   /****************************************/
269                                         /* Transition error on an AND logic     */
270                                   /****************************************/
271                                         printk("\n Transition error on an AND logic\n");
272                                         return -EINVAL;
273                                 }       /*  if (i_PatternTransitionCount > 1) */
274                         }       /*  if (data[1]== APCI1500_AND) */
275
276                             /*****************************************************************/
277                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
278                             /*****************************************************************/
279                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
280                                 devpriv->iobase +
281                                 APCI1500_Z8536_CONTROL_REGISTER);
282                         /******************/
283                         /* Disable Port A */
284                             /******************/
285                         outb(0xF0,
286                                 devpriv->iobase +
287                                 APCI1500_Z8536_CONTROL_REGISTER);
288                         /**********************************************/
289                         /* Selects the polarity register of port 1    */
290                             /**********************************************/
291                         outb(APCI1500_RW_PORT_A_PATTERN_POLARITY,
292                                 devpriv->iobase +
293                                 APCI1500_Z8536_CONTROL_REGISTER);
294                         outb(i_PatternPolarity,
295                                 devpriv->iobase +
296                                 APCI1500_Z8536_CONTROL_REGISTER);
297
298                         /*********************************************/
299                         /* Selects the pattern mask register of      */
300                         /* port 1                                    */
301                             /*********************************************/
302                         outb(APCI1500_RW_PORT_A_PATTERN_MASK,
303                                 devpriv->iobase +
304                                 APCI1500_Z8536_CONTROL_REGISTER);
305                         outb(i_PatternMask,
306                                 devpriv->iobase +
307                                 APCI1500_Z8536_CONTROL_REGISTER);
308                         /********************************************/
309                         /* Selects the pattern transition register  */
310                         /* of port 1                                */
311                             /********************************************/
312                         outb(APCI1500_RW_PORT_A_PATTERN_TRANSITION,
313                                 devpriv->iobase +
314                                 APCI1500_Z8536_CONTROL_REGISTER);
315                         outb(i_PatternTransition,
316                                 devpriv->iobase +
317                                 APCI1500_Z8536_CONTROL_REGISTER);
318
319                       /******************************************/
320                         /* Selects the mode specification mask    */
321                         /* register of port 1                     */
322                           /******************************************/
323                         outb(APCI1500_RW_PORT_A_SPECIFICATION,
324                                 devpriv->iobase +
325                                 APCI1500_Z8536_CONTROL_REGISTER);
326                         i_RegValue =
327                                 inb(devpriv->iobase +
328                                 APCI1500_Z8536_CONTROL_REGISTER);
329
330                       /******************************************/
331                         /* Selects the mode specification mask    */
332                         /* register of port 1                     */
333                           /******************************************/
334                         outb(APCI1500_RW_PORT_A_SPECIFICATION,
335                                 devpriv->iobase +
336                                 APCI1500_Z8536_CONTROL_REGISTER);
337
338                       /**********************/
339                         /* Port A new mode    */
340                           /**********************/
341
342                         i_RegValue = (i_RegValue & 0xF9) | data[1] | 0x9;
343                         outb(i_RegValue,
344                                 devpriv->iobase +
345                                 APCI1500_Z8536_CONTROL_REGISTER);
346
347                         i_Event1Status = 1;
348
349                       /*****************************************************************/
350                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
351                           /*****************************************************************/
352
353                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
354                                 devpriv->iobase +
355                                 APCI1500_Z8536_CONTROL_REGISTER);
356                       /*****************/
357                         /* Enable Port A */
358                           /*****************/
359                         outb(0xF4,
360                                 devpriv->iobase +
361                                 APCI1500_Z8536_CONTROL_REGISTER);
362
363                 }               /*  if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY) */
364                 else {
365                         printk("\nThe choice for interrupt logic does not exist\n");
366                         return -EINVAL;
367                 }               /*  else }// if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY) */
368         }                       /*    if (data[0]== 1) */
369
370                  /************************************/
371         /* Test if event setting for port 2 */
372                  /************************************/
373
374         if (data[0] == 2) {
375                     /************************/
376                 /* Test the event logic */
377                     /************************/
378
379                 if (data[1] == APCI1500_OR) {
380                        /*****************************************************************/
381                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
382                        /*****************************************************************/
383                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
384                                 devpriv->iobase +
385                                 APCI1500_Z8536_CONTROL_REGISTER);
386                        /******************/
387                         /* Disable Port B */
388                        /******************/
389                         outb(0x74,
390                                 devpriv->iobase +
391                                 APCI1500_Z8536_CONTROL_REGISTER);
392                        /****************************************/
393                         /* Selects the mode specification mask  */
394                         /* register of port B                   */
395                        /****************************************/
396                         outb(APCI1500_RW_PORT_B_SPECIFICATION,
397                                 devpriv->iobase +
398                                 APCI1500_Z8536_CONTROL_REGISTER);
399                         i_RegValue =
400                                 inb(devpriv->iobase +
401                                 APCI1500_Z8536_CONTROL_REGISTER);
402
403                        /******************************************/
404                         /* Selects the mode specification mask    */
405                         /* register of port B                     */
406                        /******************************************/
407                         outb(APCI1500_RW_PORT_B_SPECIFICATION,
408                                 devpriv->iobase +
409                                 APCI1500_Z8536_CONTROL_REGISTER);
410                         i_RegValue = i_RegValue & 0xF9;
411                         outb(i_RegValue,
412                                 devpriv->iobase +
413                                 APCI1500_Z8536_CONTROL_REGISTER);
414
415                        /**********************************/
416                         /* Selects error channels 1 and 2 */
417                        /**********************************/
418
419                         i_PatternMask = (i_PatternMask | 0xC0);
420                         i_PatternPolarity = (i_PatternPolarity | 0xC0);
421                         i_PatternTransition = (i_PatternTransition | 0xC0);
422
423                        /**********************************************/
424                         /* Selects the polarity register of port 2    */
425                        /**********************************************/
426                         outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
427                                 devpriv->iobase +
428                                 APCI1500_Z8536_CONTROL_REGISTER);
429                         outb(i_PatternPolarity,
430                                 devpriv->iobase +
431                                 APCI1500_Z8536_CONTROL_REGISTER);
432                        /**********************************************/
433                         /* Selects the pattern transition register    */
434                         /* of port 2                                  */
435                        /**********************************************/
436                         outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
437                                 devpriv->iobase +
438                                 APCI1500_Z8536_CONTROL_REGISTER);
439                         outb(i_PatternTransition,
440                                 devpriv->iobase +
441                                 APCI1500_Z8536_CONTROL_REGISTER);
442                        /**********************************************/
443                         /* Selects the pattern Mask register    */
444                         /* of port 2                                  */
445                        /**********************************************/
446
447                         outb(APCI1500_RW_PORT_B_PATTERN_MASK,
448                                 devpriv->iobase +
449                                 APCI1500_Z8536_CONTROL_REGISTER);
450                         outb(i_PatternMask,
451                                 devpriv->iobase +
452                                 APCI1500_Z8536_CONTROL_REGISTER);
453
454                        /******************************************/
455                         /* Selects the mode specification mask    */
456                         /* register of port 2                     */
457                        /******************************************/
458                         outb(APCI1500_RW_PORT_B_SPECIFICATION,
459                                 devpriv->iobase +
460                                 APCI1500_Z8536_CONTROL_REGISTER);
461                         i_RegValue =
462                                 inb(devpriv->iobase +
463                                 APCI1500_Z8536_CONTROL_REGISTER);
464                        /******************************************/
465                         /* Selects the mode specification mask    */
466                         /* register of port 2                     */
467                        /******************************************/
468                         outb(APCI1500_RW_PORT_B_SPECIFICATION,
469                                 devpriv->iobase +
470                                 APCI1500_Z8536_CONTROL_REGISTER);
471                         i_RegValue = (i_RegValue & 0xF9) | 4;
472                         outb(i_RegValue,
473                                 devpriv->iobase +
474                                 APCI1500_Z8536_CONTROL_REGISTER);
475
476                         i_Event2Status = 1;
477                        /*****************************************************************/
478                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
479                        /*****************************************************************/
480
481                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
482                                 devpriv->iobase +
483                                 APCI1500_Z8536_CONTROL_REGISTER);
484                        /*****************/
485                         /* Enable Port B */
486                        /*****************/
487
488                         outb(0xF4,
489                                 devpriv->iobase +
490                                 APCI1500_Z8536_CONTROL_REGISTER);
491                 }               /*   if (data[1] == APCI1500_OR) */
492                 else {
493                         printk("\nThe choice for interrupt logic does not exist\n");
494                         return -EINVAL;
495                 }               /* elseif (data[1] == APCI1500_OR) */
496         }                       /* if(data[0]==2) */
497
498         return insn->n;
499 }
500
501 /*
502 +----------------------------------------------------------------------------+
503 | Function   Name   : int i_APCI1500_StartStopInputEvent                     |
504 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
505 |                      struct comedi_insn *insn,unsigned int *data)                     |
506 +----------------------------------------------------------------------------+
507 | Task              :  Allows or disallows a port event                      |
508 +----------------------------------------------------------------------------+
509 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
510 |                             unsigned int ui_Channel : Channel number to read       |
511 |                     unsigned int *data          : Data Pointer to read status  |
512 |                      data[0]                 :0 Start input event
513 |                                               1 Stop input event
514 |                      data[1]                 :No of port (1 or 2)
515 +----------------------------------------------------------------------------+
516 | Output Parameters :   --                                                                                                       |
517 +----------------------------------------------------------------------------+
518 | Return Value      : TRUE  : No error occur                                 |
519 |                           : FALSE : Error occur. Return the error          |
520 |                                                                                |
521 +----------------------------------------------------------------------------+
522 */
523 static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev,
524                                           struct comedi_subdevice *s,
525                                           struct comedi_insn *insn,
526                                           unsigned int *data)
527 {
528         int i_Event1InterruptStatus = 0, i_Event2InterruptStatus =
529                 0, i_RegValue;
530         switch (data[0]) {
531         case START:
532               /*************************/
533                 /* Tests the port number */
534               /*************************/
535
536                 if (data[1] == 1 || data[1] == 2) {
537                   /***************************/
538                         /* Test if port 1 selected */
539                   /***************************/
540
541                         if (data[1] == 1) {
542                     /*****************************/
543                                 /* Test if event initialised */
544                     /*****************************/
545                                 if (i_Event1Status == 1) {
546                        /*****************************************************************/
547                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
548                        /*****************************************************************/
549                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
550                        /******************/
551                                         /* Disable Port A */
552                        /******************/
553                                         outb(0xF0,
554                                                 devpriv->iobase +
555                                                 APCI1500_Z8536_CONTROL_REGISTER);
556                        /***************************************************/
557                                         /* Selects the command and status register of      */
558                                         /* port 1                                          */
559                        /***************************************************/
560                                         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
561                        /*************************************/
562                                         /* Allows the pattern interrupt      */
563                        /*************************************/
564                                         outb(0xC0,
565                                                 devpriv->iobase +
566                                                 APCI1500_Z8536_CONTROL_REGISTER);
567                        /*****************************************************************/
568                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
569                        /*****************************************************************/
570                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
571                        /*****************/
572                                         /* Enable Port A */
573                        /*****************/
574                                         outb(0xF4,
575                                                 devpriv->iobase +
576                                                 APCI1500_Z8536_CONTROL_REGISTER);
577                                         i_Event1InterruptStatus = 1;
578                                         outb(APCI1500_RW_PORT_A_SPECIFICATION,
579                                                 devpriv->iobase +
580                                                 APCI1500_Z8536_CONTROL_REGISTER);
581                                         i_RegValue =
582                                                 inb(devpriv->iobase +
583                                                 APCI1500_Z8536_CONTROL_REGISTER);
584
585                                         /* Selects the master interrupt control register */
586                        /*************************************************/
587                                         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
588                        /**********************************************/
589                                         /* Authorizes the main interrupt on the board */
590                        /**********************************************/
591                                         outb(0xD0,
592                                                 devpriv->iobase +
593                                                 APCI1500_Z8536_CONTROL_REGISTER);
594
595                                 }       /*  if(i_Event1Status==1) */
596                                 else {
597                                         printk("\nEvent 1 not initialised\n");
598                                         return -EINVAL;
599                                 }       /* else if(i_Event1Status==1) */
600                         }       /* if (data[1]==1) */
601                         if (data[1] == 2) {
602
603                                 if (i_Event2Status == 1) {
604                             /*****************************************************************/
605                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
606                             /*****************************************************************/
607                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
608                        /******************/
609                                         /* Disable Port B */
610                        /******************/
611                                         outb(0x74,
612                                                 devpriv->iobase +
613                                                 APCI1500_Z8536_CONTROL_REGISTER);
614                        /***************************************************/
615                                         /* Selects the command and status register of      */
616                                         /* port 2                                          */
617                        /***************************************************/
618                                         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
619                        /*************************************/
620                                         /* Allows the pattern interrupt      */
621                        /*************************************/
622                                         outb(0xC0,
623                                                 devpriv->iobase +
624                                                 APCI1500_Z8536_CONTROL_REGISTER);
625                        /*****************************************************************/
626                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
627                        /*****************************************************************/
628                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
629                        /*****************/
630                                         /* Enable Port B */
631                        /*****************/
632                                         outb(0xF4,
633                                                 devpriv->iobase +
634                                                 APCI1500_Z8536_CONTROL_REGISTER);
635
636                                         /* Selects the master interrupt control register */
637                        /*************************************************/
638                                         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
639                        /**********************************************/
640                                         /* Authorizes the main interrupt on the board */
641                        /**********************************************/
642                                         outb(0xD0,
643                                                 devpriv->iobase +
644                                                 APCI1500_Z8536_CONTROL_REGISTER);
645                                         i_Event2InterruptStatus = 1;
646                                 }       /*  if(i_Event2Status==1) */
647                                 else {
648                                         printk("\nEvent 2 not initialised\n");
649                                         return -EINVAL;
650                                 }       /* else if(i_Event2Status==1) */
651                         }       /*  if(data[1]==2) */
652                 }               /*  if (data[1] == 1 || data[0] == 2) */
653                 else {
654                         printk("\nThe port parameter is in error\n");
655                         return -EINVAL;
656                 }               /* else if (data[1] == 1 || data[0] == 2) */
657
658                 break;
659
660         case STOP:
661                   /*************************/
662                 /* Tests the port number */
663                   /*************************/
664
665                 if (data[1] == 1 || data[1] == 2) {
666                   /***************************/
667                         /* Test if port 1 selected */
668                   /***************************/
669
670                         if (data[1] == 1) {
671                     /*****************************/
672                                 /* Test if event initialised */
673                     /*****************************/
674                                 if (i_Event1Status == 1) {
675                        /*****************************************************************/
676                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
677                        /*****************************************************************/
678                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
679                        /******************/
680                                         /* Disable Port A */
681                        /******************/
682                                         outb(0xF0,
683                                                 devpriv->iobase +
684                                                 APCI1500_Z8536_CONTROL_REGISTER);
685                        /***************************************************/
686                                         /* Selects the command and status register of      */
687                                         /* port 1                                          */
688                        /***************************************************/
689                                         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
690                        /*************************************/
691                                         /* Inhibits the pattern interrupt      */
692                        /*************************************/
693                                         outb(0xE0,
694                                                 devpriv->iobase +
695                                                 APCI1500_Z8536_CONTROL_REGISTER);
696                        /*****************************************************************/
697                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
698                        /*****************************************************************/
699                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
700                        /*****************/
701                                         /* Enable Port A */
702                        /*****************/
703                                         outb(0xF4,
704                                                 devpriv->iobase +
705                                                 APCI1500_Z8536_CONTROL_REGISTER);
706                                         i_Event1InterruptStatus = 0;
707                                 }       /*  if(i_Event1Status==1) */
708                                 else {
709                                         printk("\nEvent 1 not initialised\n");
710                                         return -EINVAL;
711                                 }       /* else if(i_Event1Status==1) */
712                         }       /* if (data[1]==1) */
713                         if (data[1] == 2) {
714                          /*****************************/
715                                 /* Test if event initialised */
716                          /*****************************/
717                                 if (i_Event2Status == 1) {
718                           /*****************************************************************/
719                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
720                           /*****************************************************************/
721                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
722                           /******************/
723                                         /* Disable Port B */
724                           /******************/
725                                         outb(0x74,
726                                                 devpriv->iobase +
727                                                 APCI1500_Z8536_CONTROL_REGISTER);
728                           /***************************************************/
729                                         /* Selects the command and status register of      */
730                                         /* port 2                                         */
731                           /***************************************************/
732                                         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
733                        /*************************************/
734                                         /* Inhibits the pattern interrupt      */
735                        /*************************************/
736                                         outb(0xE0,
737                                                 devpriv->iobase +
738                                                 APCI1500_Z8536_CONTROL_REGISTER);
739                        /*****************************************************************/
740                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
741                        /*****************************************************************/
742                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
743                        /*****************/
744                                         /* Enable Port B */
745                        /*****************/
746                                         outb(0xF4,
747                                                 devpriv->iobase +
748                                                 APCI1500_Z8536_CONTROL_REGISTER);
749                                         i_Event2InterruptStatus = 0;
750                                 }       /*  if(i_Event2Status==1) */
751                                 else {
752                                         printk("\nEvent 2 not initialised\n");
753                                         return -EINVAL;
754                                 }       /* else if(i_Event2Status==1) */
755                         }       /* if(data[1]==2) */
756
757                 }               /*  if (data[1] == 1 || data[1] == 2) */
758                 else {
759                         printk("\nThe port parameter is in error\n");
760                         return -EINVAL;
761                 }               /* else if (data[1] == 1 || data[1] == 2) */
762                 break;
763         default:
764                 printk("\nThe option of START/STOP logic does not exist\n");
765                 return -EINVAL;
766         }                       /* switch(data[0]) */
767
768         return insn->n;
769 }
770
771 /*
772 +----------------------------------------------------------------------------+
773 | Function   Name   : int i_APCI1500_Initialisation                          |
774 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
775 |                      struct comedi_insn *insn,unsigned int *data)                     |
776 +----------------------------------------------------------------------------+
777 | Task              : Return the status of the digital input                 |
778 +----------------------------------------------------------------------------+
779 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
780 |                             unsigned int ui_Channel : Channel number to read       |
781 |                     unsigned int *data          : Data Pointer to read status  |
782 +----------------------------------------------------------------------------+
783 | Output Parameters :   --                                                                                                       |
784 +----------------------------------------------------------------------------+
785 | Return Value      : TRUE  : No error occur                                 |
786 |                           : FALSE : Error occur. Return the error          |
787 |                                                                                |
788 +----------------------------------------------------------------------------+
789 */
790 static int i_APCI1500_Initialisation(struct comedi_device *dev,
791                                      struct comedi_subdevice *s,
792                                      struct comedi_insn *insn,
793                                      unsigned int *data)
794 {
795         int i_DummyRead = 0;
796     /******************/
797         /* Software reset */
798     /******************/
799         i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
800         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
801         i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
802         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
803         outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
804         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
805
806  /*****************************************************/
807         /* Selects the master configuration control register */
808  /*****************************************************/
809         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
810                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
811         outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
812
813         /*****************************************************/
814         /* Selects the mode specification register of port A */
815         /*****************************************************/
816         outb(APCI1500_RW_PORT_A_SPECIFICATION,
817                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
818         outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
819
820         /* Selects the data path polarity register of port A */
821         outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
822                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
823         /* High level of port A means 1 */
824         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
825
826         /* Selects the data direction register of port A */
827         outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
828                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
829         /* All bits used as inputs */
830         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
831         /* Selects the command and status register of port A */
832         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
833                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
834         /* Deletes IP and IUS */
835         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
836         /*  Selects the command and status register of port A */
837         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
838                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
839         /* Deactivates the interrupt management of port A:  */
840         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
841         /* Selects the handshake specification register of port A */
842         outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
843                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
844         /* Deletes the register */
845         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
846
847          /*****************************************************/
848         /* Selects the mode specification register of port B */
849          /*****************************************************/
850         outb(APCI1500_RW_PORT_B_SPECIFICATION,
851                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
852         outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
853         /* Selects the data path polarity register of port B */
854         outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
855                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
856         /* A high level of port B means 1 */
857         outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
858         /* Selects the data direction register of port B */
859         outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
860                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
861         /* All bits used as inputs */
862         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
863         /* Selects the command and status register of port B */
864         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
865                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
866         /* Deletes IP and IUS */
867         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
868         /* Selects the command and status register of port B */
869         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
870                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
871         /* Deactivates the interrupt management of port B:         */
872         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
873         /* Selects the handshake specification register of port B */
874         outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
875                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
876         /* Deletes the register */
877         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
878
879            /*****************************************************/
880         /* Selects the data path polarity register of port C */
881            /*****************************************************/
882         outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
883                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
884         /* High level of port C means 1 */
885         outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
886         /* Selects the data direction register of port C */
887         outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
888                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
889         /* All bits used as inputs except channel 1 */
890         outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
891         /* Selects the special IO register of port C */
892         outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
893                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
894         /* Deletes it */
895         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
896            /******************************************************/
897         /* Selects the command and status register of timer 1 */
898            /******************************************************/
899         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
900                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
901         /* Deletes IP and IUS */
902         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
903         /* Selects the command and status register of timer 1 */
904         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
905                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
906         /* Deactivates the interrupt management of timer 1         */
907         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
908            /******************************************************/
909         /* Selects the command and status register of timer 2 */
910            /******************************************************/
911         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
912                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
913         /* Deletes IP and IUS */
914         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
915         /* Selects the command and status register of timer 2 */
916         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
917                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
918         /* Deactivates Timer 2 interrupt management:               */
919         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
920           /******************************************************/
921         /* Selects the command and status register of timer 3 */
922           /******************************************************/
923         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
924                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
925         /* Deletes IP and IUS */
926         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
927         /* Selects the command and status register of Timer 3 */
928         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
929                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
930         /* Deactivates interrupt management of timer 3:            */
931         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
932          /*************************************************/
933         /* Selects the master interrupt control register */
934          /*************************************************/
935         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
936                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
937         /* Deletes all interrupts */
938         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
939         return insn->n;
940 }
941
942 /*
943 +----------------------------------------------------------------------------+
944 | Function   Name   : int i_APCI1500_ReadMoreDigitalInput                    |
945 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
946 |                     struct comedi_insn *insn,unsigned int *data)                      |
947 +----------------------------------------------------------------------------+
948 | Task              : Return the status of the Requested digital inputs      |
949 +----------------------------------------------------------------------------+
950 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
951 |                     unsigned int ui_NoOfChannels    : No Of Channels To be Read    |
952 |                      unsigned int *data             : Data Pointer
953 |                      data[0]                 : 0 Read a single channel
954 |                                                1 read a port value
955 |                      data[1]                 : port value
956 +----------------------------------------------------------------------------+
957 | Output Parameters :   --      data[0]    :The read status value
958 +----------------------------------------------------------------------------+
959 | Return Value      : TRUE  : No error occur                                 |
960 |                           : FALSE : Error occur. Return the error          |
961 |                                                                                |
962 +----------------------------------------------------------------------------+
963 */
964 static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev,
965                                            struct comedi_subdevice *s,
966                                            struct comedi_insn *insn,
967                                            unsigned int *data)
968 {
969         unsigned int ui_PortValue = data[1];
970         unsigned int ui_Mask = 0;
971         unsigned int ui_Channel;
972         unsigned int ui_TmpValue = 0;
973         ui_Channel = CR_CHAN(insn->chanspec);
974
975         switch (data[0]) {
976         case 0:
977                 if (ui_Channel <= 15) {
978                         ui_TmpValue =
979                                 (unsigned int) inw(devpriv->i_IobaseAddon +
980                                 APCI1500_DIGITAL_IP);
981                         *data = (ui_TmpValue >> ui_Channel) & 0x1;
982                 }               /* if(ui_Channel >= 0 && ui_Channel <=15) */
983                 else {
984                         printk("\nThe channel specification are in error\n");
985                         return -EINVAL; /*  "sorry channel spec wrong " */
986                 }               /* else if(ui_Channel >= 0 && ui_Channel <=15) */
987                 break;
988         case 1:
989
990                 *data = (unsigned int) inw(devpriv->i_IobaseAddon +
991                         APCI1500_DIGITAL_IP);
992                 switch (ui_Channel) {
993                 case 2:
994                         ui_Mask = 3;
995                         *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
996                         break;
997                 case 4:
998                         ui_Mask = 15;
999                         *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
1000                         break;
1001                 case 8:
1002                         ui_Mask = 255;
1003                         *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
1004                         break;
1005                 case 15:
1006                         break;
1007
1008                 default:
1009                         printk("\nSpecified channel cannot be read \n");
1010                         return -EINVAL; /*  "sorry channel spec wrong " */
1011                         break;
1012                 }               /* switch(ui_Channel) */
1013                 break;
1014         default:
1015                 printk("\nThe specified functionality does not exist\n");
1016                 return -EINVAL;
1017         }                       /* switch(data[0]) */
1018         return insn->n;
1019 }
1020
1021 /*
1022 +----------------------------------------------------------------------------+
1023 | Function   Name   : int i_APCI1500_ConfigDigitalOutputErrorInterrupt
1024 |                      (struct comedi_device *dev,struct comedi_subdevice *s struct comedi_insn
1025 |                      *insn,unsigned int *data)                                  |
1026 |                                                                                    |
1027 +----------------------------------------------------------------------------+
1028 | Task              : Configures the digital output memory and the digital
1029 |                      output error interrupt                                 |
1030 +----------------------------------------------------------------------------+
1031 | Input Parameters  : struct comedi_device *dev : Driver handle                     |
1032 |                     unsigned int *data         : Data Pointer contains         |
1033 |                                          configuration parameters as below |
1034 |                      struct comedi_subdevice *s,   :pointer to subdevice structure
1035 |                       struct comedi_insn *insn      :pointer to insn structure                                                                                                                |
1036 |                                         data[0]  :1:Memory on                          |
1037 |                                                   0:Memory off                         |
1038 |                              data[1]  :1 Enable the voltage error interrupt
1039 |                                                          :0 Disable the voltage error interrupt                                                                                                                   |
1040 |                                                                                                                                        |
1041 +----------------------------------------------------------------------------+
1042 | Output Parameters :   --                                                                                                       |
1043 +----------------------------------------------------------------------------+
1044 | Return Value      : TRUE  : No error occur                                 |
1045 |                           : FALSE : Error occur. Return the error          |
1046 |                                                                                |
1047 +----------------------------------------------------------------------------+
1048 */
1049 static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev,
1050                                                         struct comedi_subdevice *s,
1051                                                         struct comedi_insn *insn,
1052                                                         unsigned int *data)
1053 {
1054         devpriv->b_OutputMemoryStatus = data[0];
1055         return insn->n;
1056 }
1057
1058 /*
1059 +----------------------------------------------------------------------------+
1060 | Function   Name   : int i_APCI1500_WriteDigitalOutput                      |
1061 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
1062 |                      struct comedi_insn *insn,unsigned int *data)                     |
1063 +----------------------------------------------------------------------------+
1064 | Task              : Writes port value  To the selected port                |
1065 +----------------------------------------------------------------------------+
1066 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
1067 |                     unsigned int ui_NoOfChannels    : No Of Channels To Write      |
1068 |                     unsigned int *data              : Data Pointer to read status  |
1069 +----------------------------------------------------------------------------+
1070 | Output Parameters :   --                                                                                                       |
1071 +----------------------------------------------------------------------------+
1072 | Return Value      : TRUE  : No error occur                                 |
1073 |                           : FALSE : Error occur. Return the error          |
1074 |                                                                                |
1075 +----------------------------------------------------------------------------+
1076 */
1077 static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev,
1078                                          struct comedi_subdevice *s,
1079                                          struct comedi_insn *insn,
1080                                          unsigned int *data)
1081 {
1082         static unsigned int ui_Temp = 0;
1083         unsigned int ui_Temp1;
1084
1085         unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec);  /*  get the channel */
1086
1087         if (!devpriv->b_OutputMemoryStatus) {
1088                 ui_Temp = 0;
1089
1090         }                       /* if(!devpriv->b_OutputMemoryStatus ) */
1091         if (data[3] == 0) {
1092                 if (data[1] == 0) {
1093                         data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
1094                         outw(data[0],
1095                                 devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
1096                 }               /* if(data[1]==0) */
1097                 else {
1098                         if (data[1] == 1) {
1099                                 switch (ui_NoOfChannel) {
1100
1101                                 case 2:
1102                                         data[0] =
1103                                                 (data[0] << (2 *
1104                                                         data[2])) | ui_Temp;
1105                                         break;
1106
1107                                 case 4:
1108                                         data[0] =
1109                                                 (data[0] << (4 *
1110                                                         data[2])) | ui_Temp;
1111                                         break;
1112
1113                                 case 8:
1114                                         data[0] =
1115                                                 (data[0] << (8 *
1116                                                         data[2])) | ui_Temp;
1117                                         break;
1118
1119                                 case 15:
1120                                         data[0] = data[0] | ui_Temp;
1121                                         break;
1122
1123                                 default:
1124                                         comedi_error(dev, " chan spec wrong");
1125                                         return -EINVAL; /*  "sorry channel spec wrong " */
1126
1127                                 }       /* switch(ui_NoOfChannels) */
1128
1129                                 outw(data[0],
1130                                         devpriv->i_IobaseAddon +
1131                                         APCI1500_DIGITAL_OP);
1132                         }       /*  if(data[1]==1) */
1133                         else {
1134                                 printk("\nSpecified channel not supported\n");
1135                         }       /* else if(data[1]==1) */
1136                 }               /* elseif(data[1]==0) */
1137         }                       /* if(data[3]==0) */
1138         else {
1139                 if (data[3] == 1) {
1140                         if (data[1] == 0) {
1141                                 data[0] = ~data[0] & 0x1;
1142                                 ui_Temp1 = 1;
1143                                 ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
1144                                 ui_Temp = ui_Temp | ui_Temp1;
1145                                 data[0] =
1146                                         (data[0] << ui_NoOfChannel) ^
1147                                         0xffffffff;
1148                                 data[0] = data[0] & ui_Temp;
1149                                 outw(data[0],
1150                                         devpriv->i_IobaseAddon +
1151                                         APCI1500_DIGITAL_OP);
1152                         }       /* if(data[1]==0) */
1153                         else {
1154                                 if (data[1] == 1) {
1155                                         switch (ui_NoOfChannel) {
1156
1157                                         case 2:
1158                                                 data[0] = ~data[0] & 0x3;
1159                                                 ui_Temp1 = 3;
1160                                                 ui_Temp1 =
1161                                                         ui_Temp1 << 2 * data[2];
1162                                                 ui_Temp = ui_Temp | ui_Temp1;
1163                                                 data[0] =
1164                                                         ((data[0] << (2 *
1165                                                                         data
1166                                                                         [2])) ^
1167                                                         0xffffffff) & ui_Temp;
1168                                                 break;
1169
1170                                         case 4:
1171                                                 data[0] = ~data[0] & 0xf;
1172                                                 ui_Temp1 = 15;
1173                                                 ui_Temp1 =
1174                                                         ui_Temp1 << 4 * data[2];
1175                                                 ui_Temp = ui_Temp | ui_Temp1;
1176                                                 data[0] =
1177                                                         ((data[0] << (4 *
1178                                                                         data
1179                                                                         [2])) ^
1180                                                         0xffffffff) & ui_Temp;
1181                                                 break;
1182
1183                                         case 8:
1184                                                 data[0] = ~data[0] & 0xff;
1185                                                 ui_Temp1 = 255;
1186                                                 ui_Temp1 =
1187                                                         ui_Temp1 << 8 * data[2];
1188                                                 ui_Temp = ui_Temp | ui_Temp1;
1189                                                 data[0] =
1190                                                         ((data[0] << (8 *
1191                                                                         data
1192                                                                         [2])) ^
1193                                                         0xffffffff) & ui_Temp;
1194                                                 break;
1195
1196                                         case 15:
1197                                                 break;
1198
1199                                         default:
1200                                                 comedi_error(dev,
1201                                                         " chan spec wrong");
1202                                                 return -EINVAL; /*  "sorry channel spec wrong " */
1203
1204                                         }       /* switch(ui_NoOfChannels) */
1205
1206                                         outw(data[0],
1207                                                 devpriv->i_IobaseAddon +
1208                                                 APCI1500_DIGITAL_OP);
1209                                 }       /*  if(data[1]==1) */
1210                                 else {
1211                                         printk("\nSpecified channel not supported\n");
1212                                 }       /* else if(data[1]==1) */
1213                         }       /* elseif(data[1]==0) */
1214                 }               /* if(data[3]==1); */
1215                 else {
1216                         printk("\nSpecified functionality does not exist\n");
1217                         return -EINVAL;
1218                 }               /* if else data[3]==1) */
1219         }                       /* if else data[3]==0) */
1220         ui_Temp = data[0];
1221         return insn->n;
1222 }
1223
1224 /*
1225 +----------------------------------------------------------------------------+
1226 | Function   Name   : int i_APCI1500_ConfigCounterTimerWatchdog(comedi_device
1227 |                   *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
1228 |                                                                                    |
1229 +----------------------------------------------------------------------------+
1230 | Task              : Configures The Watchdog                                |
1231 +----------------------------------------------------------------------------+
1232 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
1233 |                     struct comedi_subdevice *s,   :pointer to subdevice structure
1234 |                      struct comedi_insn *insn      :pointer to insn structure      |
1235 |                     unsigned int *data         : Data Pointer to read status                                                       data[0]                : 2     APCI1500_1_8_KHZ
1236 |                                              1     APCI1500_3_6_KHZ        |
1237 |                                              0     APCI1500_115_KHZ
1238 |                      data[1]                : 0     Counter1/Timer1
1239 |                                               1     Counter2/Timer2
1240 |                                               2     Counter3/Watchdog
1241 |                      data[2]                : 0     Counter
1242 |                                               1     Timer/Watchdog
1243 |                      data[3]                :         This parameter has    |
1244 |                                                      two meanings.         |
1245 |                                                    - If the counter/timer  |
1246 |                                                      is used as a counter  |
1247 |                                                      the limit value of    |
1248 |                                                      the counter is given  |
1249 |                                                                            |
1250 |                                                    - If the counter/timer  |
1251 |                                                      is used as a timer,   |
1252 |                                                      the divider factor    |
1253 |                                                      for the output is     |
1254 |                                                      given.
1255 |                       data[4]                 : 0    APCI1500_CONTINUOUS
1256 |                                                 1    APCI1500_SINGLE
1257 |                       data[5]                 : 0    Software Trigger
1258 |                                                 1    Hardware Trigger
1259 |
1260 |                       data[6]                  :0    Software gate
1261 |                                                 1    Hardware gate
1262 |                       data[7]                  :0    Interrupt Disable
1263 |                                                 1    Interrupt Enable
1264 +----------------------------------------------------------------------------+
1265 | Output Parameters :   --                                                                                                       |
1266 +----------------------------------------------------------------------------+
1267 | Return Value      : TRUE  : No error occur                                 |
1268 |                           : FALSE : Error occur. Return the error          |
1269 |                                                                                |
1270 +----------------------------------------------------------------------------+
1271 */
1272 static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev,
1273                                                  struct comedi_subdevice *s,
1274                                                  struct comedi_insn *insn,
1275                                                  unsigned int *data)
1276 {
1277         int i_TimerCounterMode, i_MasterConfiguration;
1278
1279         devpriv->tsk_Current = current;
1280
1281 /* Selection of the input clock */
1282         if (data[0] == 0 || data[0] == 1 || data[0] == 2) {
1283                 outw(data[0], devpriv->i_IobaseAddon + APCI1500_CLK_SELECT);
1284         }                       /*  if(data[0]==0||data[0]==1||data[0]==2) */
1285         else {
1286                 if (data[0] != 3) {
1287                         printk("\nThe option for input clock selection does not exist\n");
1288                         return -EINVAL;
1289                 }               /*  if(data[0]!=3) */
1290         }                       /* elseif(data[0]==0||data[0]==1||data[0]==2) */
1291         /* Select the counter/timer */
1292         switch (data[1]) {
1293         case COUNTER1:
1294                 /* selecting counter or timer */
1295                 switch (data[2]) {
1296                 case 0:
1297                         data[2] = APCI1500_COUNTER;
1298                         break;
1299                 case 1:
1300                         data[2] = APCI1500_TIMER;
1301                         break;
1302                 default:
1303                         printk("\nThis choice is not a timer nor a counter\n");
1304                         return -EINVAL;
1305                 }               /*  switch(data[2]) */
1306
1307                 /* Selecting  single or continuous mode */
1308                 switch (data[4]) {
1309                 case 0:
1310                         data[4] = APCI1500_CONTINUOUS;
1311                         break;
1312                 case 1:
1313                         data[4] = APCI1500_SINGLE;
1314                         break;
1315                 default:
1316                         printk("\nThis option for single/continuous mode does not exist\n");
1317                         return -EINVAL;
1318                 }               /*  switch(data[4]) */
1319
1320                 i_TimerCounterMode = data[2] | data[4] | 7;
1321                          /*************************/
1322                 /* Test the reload value */
1323                          /*************************/
1324
1325                 if ((data[3] >= 0) && (data[3] <= 65535)) {
1326                         if (data[7] == APCI1500_ENABLE
1327                                 || data[7] == APCI1500_DISABLE) {
1328
1329                                 /************************************************/
1330                                 /* Selects the mode register of timer/counter 1 */
1331                                 /************************************************/
1332                                 outb(APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
1333                                         devpriv->iobase +
1334                                         APCI1500_Z8536_CONTROL_REGISTER);
1335                                 /***********************/
1336                                 /* Writes the new mode */
1337                                 /***********************/
1338                                 outb(i_TimerCounterMode,
1339                                         devpriv->iobase +
1340                                         APCI1500_Z8536_CONTROL_REGISTER);
1341
1342                                 /****************************************************/
1343                                 /* Selects the constant register of timer/counter 1 */
1344                                 /****************************************************/
1345
1346                                 outb(APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
1347                                         devpriv->iobase +
1348                                         APCI1500_Z8536_CONTROL_REGISTER);
1349
1350                                   /*************************/
1351                                 /* Writes the low value  */
1352                                   /*************************/
1353
1354                                 outb(data[3],
1355                                         devpriv->iobase +
1356                                         APCI1500_Z8536_CONTROL_REGISTER);
1357
1358                                    /****************************************************/
1359                                 /* Selects the constant register of timer/counter 1 */
1360                                    /****************************************************/
1361
1362                                 outb(APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
1363                                         devpriv->iobase +
1364                                         APCI1500_Z8536_CONTROL_REGISTER);
1365
1366                                   /**************************/
1367                                 /* Writes the high value  */
1368                                   /**************************/
1369
1370                                 data[3] = data[3] >> 8;
1371                                 outb(data[3],
1372                                         devpriv->iobase +
1373                                         APCI1500_Z8536_CONTROL_REGISTER);
1374
1375                                      /*********************************************/
1376                                 /* Selects the master configuration register */
1377                                      /*********************************************/
1378
1379                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1380                                         devpriv->iobase +
1381                                         APCI1500_Z8536_CONTROL_REGISTER);
1382
1383                                      /**********************/
1384                                 /* Reads the register */
1385                                      /**********************/
1386
1387                                 i_MasterConfiguration =
1388                                         inb(devpriv->iobase +
1389                                         APCI1500_Z8536_CONTROL_REGISTER);
1390
1391                                        /********************************************************/
1392                                 /* Enables timer/counter 1 and triggers timer/counter 1 */
1393                                        /********************************************************/
1394
1395                                 i_MasterConfiguration =
1396                                         i_MasterConfiguration | 0x40;
1397
1398                                     /*********************************************/
1399                                 /* Selects the master configuration register */
1400                                     /*********************************************/
1401                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1402                                         devpriv->iobase +
1403                                         APCI1500_Z8536_CONTROL_REGISTER);
1404
1405                                       /********************************/
1406                                 /* Writes the new configuration */
1407                                       /********************************/
1408                                 outb(i_MasterConfiguration,
1409                                         devpriv->iobase +
1410                                         APCI1500_Z8536_CONTROL_REGISTER);
1411                                          /****************************************/
1412                                 /* Selects the commands register of     */
1413                                 /* timer/counter 1                      */
1414                                          /****************************************/
1415
1416                                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1417                                         devpriv->iobase +
1418                                         APCI1500_Z8536_CONTROL_REGISTER);
1419
1420                                        /***************************/
1421                                 /* Disable timer/counter 1 */
1422                                        /***************************/
1423
1424                                 outb(0x0,
1425                                         devpriv->iobase +
1426                                         APCI1500_Z8536_CONTROL_REGISTER);
1427                                           /****************************************/
1428                                 /* Selects the commands register of     */
1429                                 /* timer/counter 1                      */
1430                                           /****************************************/
1431                                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1432                                         devpriv->iobase +
1433                                         APCI1500_Z8536_CONTROL_REGISTER);
1434
1435                                       /***************************/
1436                                 /* Trigger timer/counter 1 */
1437                                       /***************************/
1438                                 outb(0x2,
1439                                         devpriv->iobase +
1440                                         APCI1500_Z8536_CONTROL_REGISTER);
1441                         }       /* if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */
1442                         else {
1443                                 printk("\nError in selection of interrupt enable or disable\n");
1444                                 return -EINVAL;
1445                         }       /* elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */
1446                 }               /*  if ((data[3]>= 0) && (data[3] <= 65535)) */
1447                 else {
1448                         printk("\nError in selection of reload value\n");
1449                         return -EINVAL;
1450                 }               /* else if ((data[3]>= 0) && (data[3] <= 65535)) */
1451                 i_TimerCounterWatchdogInterrupt = data[7];
1452                 i_TimerCounter1Init = 1;
1453                 break;
1454
1455         case COUNTER2:          /* selecting counter or timer */
1456                 switch (data[2]) {
1457                 case 0:
1458                         data[2] = APCI1500_COUNTER;
1459                         break;
1460                 case 1:
1461                         data[2] = APCI1500_TIMER;
1462                         break;
1463                 default:
1464                         printk("\nThis choice is not a timer nor a counter\n");
1465                         return -EINVAL;
1466                 }               /*  switch(data[2]) */
1467
1468                 /* Selecting  single or continuous mode */
1469                 switch (data[4]) {
1470                 case 0:
1471                         data[4] = APCI1500_CONTINUOUS;
1472                         break;
1473                 case 1:
1474                         data[4] = APCI1500_SINGLE;
1475                         break;
1476                 default:
1477                         printk("\nThis option for single/continuous mode does not exist\n");
1478                         return -EINVAL;
1479                 }               /*  switch(data[4]) */
1480
1481                 /* Selecting  software or hardware trigger */
1482                 switch (data[5]) {
1483                 case 0:
1484                         data[5] = APCI1500_SOFTWARE_TRIGGER;
1485                         break;
1486                 case 1:
1487                         data[5] = APCI1500_HARDWARE_TRIGGER;
1488                         break;
1489                 default:
1490                         printk("\nThis choice for software or hardware trigger does not exist\n");
1491                         return -EINVAL;
1492                 }               /*  switch(data[5]) */
1493
1494                 /* Selecting  software or hardware gate */
1495                 switch (data[6]) {
1496                 case 0:
1497                         data[6] = APCI1500_SOFTWARE_GATE;
1498                         break;
1499                 case 1:
1500                         data[6] = APCI1500_HARDWARE_GATE;
1501                         break;
1502                 default:
1503                         printk("\nThis choice for software or hardware gate does not exist\n");
1504                         return -EINVAL;
1505                 }               /*  switch(data[6]) */
1506
1507                 i_TimerCounterMode = data[2] | data[4] | data[5] | data[6] | 7;
1508
1509                              /*************************/
1510                 /* Test the reload value */
1511                              /*************************/
1512
1513                 if ((data[3] >= 0) && (data[3] <= 65535)) {
1514                         if (data[7] == APCI1500_ENABLE
1515                                 || data[7] == APCI1500_DISABLE) {
1516
1517                                 /************************************************/
1518                                 /* Selects the mode register of timer/counter 2 */
1519                                 /************************************************/
1520                                 outb(APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
1521                                         devpriv->iobase +
1522                                         APCI1500_Z8536_CONTROL_REGISTER);
1523                                 /***********************/
1524                                 /* Writes the new mode */
1525                                 /***********************/
1526                                 outb(i_TimerCounterMode,
1527                                         devpriv->iobase +
1528                                         APCI1500_Z8536_CONTROL_REGISTER);
1529
1530                                 /****************************************************/
1531                                 /* Selects the constant register of timer/counter 2 */
1532                                 /****************************************************/
1533
1534                                 outb(APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
1535                                         devpriv->iobase +
1536                                         APCI1500_Z8536_CONTROL_REGISTER);
1537
1538                                   /*************************/
1539                                 /* Writes the low value  */
1540                                   /*************************/
1541
1542                                 outb(data[3],
1543                                         devpriv->iobase +
1544                                         APCI1500_Z8536_CONTROL_REGISTER);
1545
1546                                    /****************************************************/
1547                                 /* Selects the constant register of timer/counter 2 */
1548                                    /****************************************************/
1549
1550                                 outb(APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
1551                                         devpriv->iobase +
1552                                         APCI1500_Z8536_CONTROL_REGISTER);
1553
1554                                   /**************************/
1555                                 /* Writes the high value  */
1556                                   /**************************/
1557
1558                                 data[3] = data[3] >> 8;
1559                                 outb(data[3],
1560                                         devpriv->iobase +
1561                                         APCI1500_Z8536_CONTROL_REGISTER);
1562
1563                                      /*********************************************/
1564                                 /* Selects the master configuration register */
1565                                      /*********************************************/
1566
1567                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1568                                         devpriv->iobase +
1569                                         APCI1500_Z8536_CONTROL_REGISTER);
1570
1571                                      /**********************/
1572                                 /* Reads the register */
1573                                      /**********************/
1574
1575                                 i_MasterConfiguration =
1576                                         inb(devpriv->iobase +
1577                                         APCI1500_Z8536_CONTROL_REGISTER);
1578
1579                                        /********************************************************/
1580                                 /* Enables timer/counter 2 and triggers timer/counter 2 */
1581                                        /********************************************************/
1582
1583                                 i_MasterConfiguration =
1584                                         i_MasterConfiguration | 0x20;
1585
1586                                     /*********************************************/
1587                                 /* Selects the master configuration register */
1588                                     /*********************************************/
1589                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1590                                         devpriv->iobase +
1591                                         APCI1500_Z8536_CONTROL_REGISTER);
1592
1593                                       /********************************/
1594                                 /* Writes the new configuration */
1595                                       /********************************/
1596                                 outb(i_MasterConfiguration,
1597                                         devpriv->iobase +
1598                                         APCI1500_Z8536_CONTROL_REGISTER);
1599                                          /****************************************/
1600                                 /* Selects the commands register of     */
1601                                 /* timer/counter 2                      */
1602                                          /****************************************/
1603
1604                                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1605                                         devpriv->iobase +
1606                                         APCI1500_Z8536_CONTROL_REGISTER);
1607
1608                                        /***************************/
1609                                 /* Disable timer/counter 2 */
1610                                        /***************************/
1611
1612                                 outb(0x0,
1613                                         devpriv->iobase +
1614                                         APCI1500_Z8536_CONTROL_REGISTER);
1615                                           /****************************************/
1616                                 /* Selects the commands register of     */
1617                                 /* timer/counter 2                      */
1618                                           /****************************************/
1619                                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1620                                         devpriv->iobase +
1621                                         APCI1500_Z8536_CONTROL_REGISTER);
1622
1623                                       /***************************/
1624                                 /* Trigger timer/counter 1 */
1625                                       /***************************/
1626                                 outb(0x2,
1627                                         devpriv->iobase +
1628                                         APCI1500_Z8536_CONTROL_REGISTER);
1629                         }       /* if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */
1630                         else {
1631                                 printk("\nError in selection of interrupt enable or disable\n");
1632                                 return -EINVAL;
1633                         }       /* elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */
1634                 }               /*  if ((data[3]>= 0) && (data[3] <= 65535)) */
1635                 else {
1636                         printk("\nError in selection of reload value\n");
1637                         return -EINVAL;
1638                 }               /* else if ((data[3]>= 0) && (data[3] <= 65535)) */
1639                 i_TimerCounterWatchdogInterrupt = data[7];
1640                 i_TimerCounter2Init = 1;
1641                 break;
1642
1643         case COUNTER3:          /* selecting counter or watchdog */
1644                 switch (data[2]) {
1645                 case 0:
1646                         data[2] = APCI1500_COUNTER;
1647                         break;
1648                 case 1:
1649                         data[2] = APCI1500_WATCHDOG;
1650                         break;
1651                 default:
1652                         printk("\nThis choice is not a watchdog nor a counter\n");
1653                         return -EINVAL;
1654                 }               /*  switch(data[2]) */
1655
1656                 /* Selecting  single or continuous mode */
1657                 switch (data[4]) {
1658                 case 0:
1659                         data[4] = APCI1500_CONTINUOUS;
1660                         break;
1661                 case 1:
1662                         data[4] = APCI1500_SINGLE;
1663                         break;
1664                 default:
1665                         printk("\nThis option for single/continuous mode does not exist\n");
1666                         return -EINVAL;
1667                 }               /*  switch(data[4]) */
1668
1669                 /* Selecting  software or hardware gate */
1670                 switch (data[6]) {
1671                 case 0:
1672                         data[6] = APCI1500_SOFTWARE_GATE;
1673                         break;
1674                 case 1:
1675                         data[6] = APCI1500_HARDWARE_GATE;
1676                         break;
1677                 default:
1678                         printk("\nThis choice for software or hardware gate does not exist\n");
1679                         return -EINVAL;
1680                 }               /*  switch(data[6]) */
1681
1682                       /*****************************/
1683                 /* Test if used for watchdog */
1684                           /*****************************/
1685
1686                 if (data[2] == APCI1500_WATCHDOG) {
1687                              /*****************************/
1688                         /* - Enables the output line */
1689                         /* - Enables retrigger       */
1690                         /* - Pulses output           */
1691                              /*****************************/
1692                         i_TimerCounterMode = data[2] | data[4] | 0x54;
1693                 }               /* if (data[2] == APCI1500_WATCHDOG) */
1694                 else {
1695                         i_TimerCounterMode = data[2] | data[4] | data[6] | 7;
1696                 }               /* elseif (data[2] == APCI1500_WATCHDOG) */
1697                                  /*************************/
1698                 /* Test the reload value */
1699                              /*************************/
1700
1701                 if ((data[3] >= 0) && (data[3] <= 65535)) {
1702                         if (data[7] == APCI1500_ENABLE
1703                                 || data[7] == APCI1500_DISABLE) {
1704
1705                                 /************************************************/
1706                                 /* Selects the mode register of watchdog/counter 3 */
1707                                 /************************************************/
1708                                 outb(APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
1709                                         devpriv->iobase +
1710                                         APCI1500_Z8536_CONTROL_REGISTER);
1711                                 /***********************/
1712                                 /* Writes the new mode */
1713                                 /***********************/
1714                                 outb(i_TimerCounterMode,
1715                                         devpriv->iobase +
1716                                         APCI1500_Z8536_CONTROL_REGISTER);
1717
1718                                 /****************************************************/
1719                                 /* Selects the constant register of watchdog/counter 3 */
1720                                 /****************************************************/
1721
1722                                 outb(APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
1723                                         devpriv->iobase +
1724                                         APCI1500_Z8536_CONTROL_REGISTER);
1725
1726                                   /*************************/
1727                                 /* Writes the low value  */
1728                                   /*************************/
1729
1730                                 outb(data[3],
1731                                         devpriv->iobase +
1732                                         APCI1500_Z8536_CONTROL_REGISTER);
1733
1734                                    /****************************************************/
1735                                 /* Selects the constant register of watchdog/counter 3 */
1736                                    /****************************************************/
1737
1738                                 outb(APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
1739                                         devpriv->iobase +
1740                                         APCI1500_Z8536_CONTROL_REGISTER);
1741
1742                                   /**************************/
1743                                 /* Writes the high value  */
1744                                   /**************************/
1745
1746                                 data[3] = data[3] >> 8;
1747                                 outb(data[3],
1748                                         devpriv->iobase +
1749                                         APCI1500_Z8536_CONTROL_REGISTER);
1750
1751                                      /*********************************************/
1752                                 /* Selects the master configuration register */
1753                                      /*********************************************/
1754
1755                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1756                                         devpriv->iobase +
1757                                         APCI1500_Z8536_CONTROL_REGISTER);
1758
1759                                      /**********************/
1760                                 /* Reads the register */
1761                                      /**********************/
1762
1763                                 i_MasterConfiguration =
1764                                         inb(devpriv->iobase +
1765                                         APCI1500_Z8536_CONTROL_REGISTER);
1766
1767                                        /********************************************************/
1768                                 /* Enables watchdog/counter 3 and triggers watchdog/counter 3 */
1769                                        /********************************************************/
1770
1771                                 i_MasterConfiguration =
1772                                         i_MasterConfiguration | 0x10;
1773
1774                                     /*********************************************/
1775                                 /* Selects the master configuration register */
1776                                     /*********************************************/
1777                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1778                                         devpriv->iobase +
1779                                         APCI1500_Z8536_CONTROL_REGISTER);
1780
1781                                       /********************************/
1782                                 /* Writes the new configuration */
1783                                       /********************************/
1784                                 outb(i_MasterConfiguration,
1785                                         devpriv->iobase +
1786                                         APCI1500_Z8536_CONTROL_REGISTER);
1787
1788                                       /********************/
1789                                 /* Test if COUNTER */
1790                                           /********************/
1791                                 if (data[2] == APCI1500_COUNTER) {
1792
1793                                             /*************************************/
1794                                         /* Selects the command register of   */
1795                                         /* watchdog/counter 3                */
1796                                                  /*************************************/
1797                                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1798                                                 devpriv->iobase +
1799                                                 APCI1500_Z8536_CONTROL_REGISTER);
1800                                               /*************************************************/
1801                                         /* Disable the  watchdog/counter 3 and starts it */
1802                                                   /*************************************************/
1803                                         outb(0x0,
1804                                                 devpriv->iobase +
1805                                                 APCI1500_Z8536_CONTROL_REGISTER);
1806
1807                                               /*************************************/
1808                                         /* Selects the command register of   */
1809                                         /* watchdog/counter 3                */
1810                                                   /*************************************/
1811
1812                                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1813                                                 devpriv->iobase +
1814                                                 APCI1500_Z8536_CONTROL_REGISTER);
1815                                              /*************************************************/
1816                                         /* Trigger the  watchdog/counter 3 and starts it */
1817                                                  /*************************************************/
1818                                         outb(0x2,
1819                                                 devpriv->iobase +
1820                                                 APCI1500_Z8536_CONTROL_REGISTER);
1821
1822                                 }       /* elseif(data[2]==APCI1500_COUNTER) */
1823
1824                         }       /* if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */
1825                         else {
1826                                 printk("\nError in selection of interrupt enable or disable\n");
1827                                 return -EINVAL;
1828                         }       /* elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */
1829                 }               /*  if ((data[3]>= 0) && (data[3] <= 65535)) */
1830                 else {
1831                         printk("\nError in selection of reload value\n");
1832                         return -EINVAL;
1833                 }               /* else if ((data[3]>= 0) && (data[3] <= 65535)) */
1834                 i_TimerCounterWatchdogInterrupt = data[7];
1835                 i_WatchdogCounter3Init = 1;
1836                 break;
1837
1838         default:
1839                 printk("\nThe specified counter\timer option does not exist\n");
1840         }                       /* switch(data[1]) */
1841         i_CounterLogic = data[2];
1842         return insn->n;
1843 }
1844
1845 /*
1846 +----------------------------------------------------------------------------+
1847 | Function   Name   : int i_APCI1500_StartStopTriggerTimerCounterWatchdog      |
1848 |                               (struct comedi_device *dev,struct comedi_subdevice *s,
1849 |                         struct comedi_insn *insn,unsigned int *data);                  |
1850 +----------------------------------------------------------------------------+
1851 | Task              : Start / Stop or trigger the timer counter or Watchdog  |
1852 +----------------------------------------------------------------------------+
1853 | Input Parameters  : struct comedi_device *dev     : Driver handle                 |
1854 |                     struct comedi_subdevice *s,   :pointer to subdevice structure
1855 |                      struct comedi_insn *insn      :pointer to insn structure      |
1856 |                     unsigned int *data         : Data Pointer to read status   |
1857 |                      data[0]                : 0     Counter1/Timer1
1858 |                                               1     Counter2/Timer2
1859 |                                               2     Counter3/Watchdog
1860 |                      data[1]                : 0     start
1861 |                                               1     stop
1862 |                                               2     Trigger
1863 |                      data[2]                : 0     Counter
1864 |                                               1     Timer/Watchdog
1865 +----------------------------------------------------------------------------+
1866 | Output Parameters :   --                                                                                                       |
1867 +----------------------------------------------------------------------------+
1868 | Return Value      : TRUE  : No error occur                                 |
1869 |                           : FALSE : Error occur. Return the error          |
1870 |                                                                                |
1871 +----------------------------------------------------------------------------+
1872 */
1873 static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev,
1874                                                            struct comedi_subdevice *s,
1875                                                            struct comedi_insn *insn,
1876                                                            unsigned int *data)
1877 {
1878         int i_CommandAndStatusValue;
1879
1880         switch (data[0]) {
1881         case COUNTER1:
1882                 switch (data[1]) {
1883                 case START:
1884                         if (i_TimerCounter1Init == 1) {
1885                                 if (i_TimerCounterWatchdogInterrupt == 1) {
1886                                         i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1887                                 }       /*  if(i_TimerCounterWatchdogInterrupt==1) */
1888                                 else {
1889                                         i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1890                                 }       /* elseif(i_TimerCounterWatchdogInterrupt==1) */
1891                                               /**************************/
1892                                 /* Starts timer/counter 1 */
1893                                               /**************************/
1894                                 i_TimerCounter1Enabled = 1;
1895                                                 /********************************************/
1896                                 /* Selects the commands and status register */
1897                                                 /********************************************/
1898                                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1899                                         devpriv->iobase +
1900                                         APCI1500_Z8536_CONTROL_REGISTER);
1901                                 outb(i_CommandAndStatusValue,
1902                                         devpriv->iobase +
1903                                         APCI1500_Z8536_CONTROL_REGISTER);
1904                         }       /* if( i_TimerCounter1Init==1) */
1905                         else {
1906                                 printk("\nCounter/Timer1 not configured\n");
1907                                 return -EINVAL;
1908                         }
1909                         break;
1910
1911                 case STOP:
1912
1913                                               /**************************/
1914                         /* Stop timer/counter 1 */
1915                                               /**************************/
1916
1917                                                 /********************************************/
1918                         /* Selects the commands and status register */
1919                                                 /********************************************/
1920                         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1921                                 devpriv->iobase +
1922                                 APCI1500_Z8536_CONTROL_REGISTER);
1923                         outb(0x00,
1924                                 devpriv->iobase +
1925                                 APCI1500_Z8536_CONTROL_REGISTER);
1926                         i_TimerCounter1Enabled = 0;
1927                         break;
1928
1929                 case TRIGGER:
1930                         if (i_TimerCounter1Init == 1) {
1931                                 if (i_TimerCounter1Enabled == 1) {
1932                                                  /************************/
1933                                         /* Set Trigger and gate */
1934                                                  /************************/
1935
1936                                         i_CommandAndStatusValue = 0x6;
1937                                 }       /* if( i_TimerCounter1Enabled==1) */
1938                                 else {
1939                                                    /***************/
1940                                         /* Set Trigger */
1941                                                    /***************/
1942
1943                                         i_CommandAndStatusValue = 0x2;
1944                                 }       /* elseif(i_TimerCounter1Enabled==1) */
1945
1946                                                 /********************************************/
1947                                 /* Selects the commands and status register */
1948                                                 /********************************************/
1949                                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1950                                         devpriv->iobase +
1951                                         APCI1500_Z8536_CONTROL_REGISTER);
1952                                 outb(i_CommandAndStatusValue,
1953                                         devpriv->iobase +
1954                                         APCI1500_Z8536_CONTROL_REGISTER);
1955                         }       /* if( i_TimerCounter1Init==1) */
1956                         else {
1957                                 printk("\nCounter/Timer1 not configured\n");
1958                                 return -EINVAL;
1959                         }
1960                         break;
1961
1962                 default:
1963                         printk("\nThe specified option for start/stop/trigger does not exist\n");
1964                         return -EINVAL;
1965                 }               /* switch(data[1]) */
1966                 break;
1967
1968         case COUNTER2:
1969                 switch (data[1]) {
1970                 case START:
1971                         if (i_TimerCounter2Init == 1) {
1972                                 if (i_TimerCounterWatchdogInterrupt == 1) {
1973                                         i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1974                                 }       /*  if(i_TimerCounterWatchdogInterrupt==1) */
1975                                 else {
1976                                         i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1977                                 }       /* elseif(i_TimerCounterWatchdogInterrupt==1) */
1978                                               /**************************/
1979                                 /* Starts timer/counter 2 */
1980                                               /**************************/
1981                                 i_TimerCounter2Enabled = 1;
1982                                                 /********************************************/
1983                                 /* Selects the commands and status register */
1984                                                 /********************************************/
1985                                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1986                                         devpriv->iobase +
1987                                         APCI1500_Z8536_CONTROL_REGISTER);
1988                                 outb(i_CommandAndStatusValue,
1989                                         devpriv->iobase +
1990                                         APCI1500_Z8536_CONTROL_REGISTER);
1991                         }       /* if( i_TimerCounter2Init==1) */
1992                         else {
1993                                 printk("\nCounter/Timer2 not configured\n");
1994                                 return -EINVAL;
1995                         }
1996                         break;
1997
1998                 case STOP:
1999
2000                                               /**************************/
2001                         /* Stop timer/counter 2 */
2002                                               /**************************/
2003
2004                                                 /********************************************/
2005                         /* Selects the commands and status register */
2006                                                 /********************************************/
2007                         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2008                                 devpriv->iobase +
2009                                 APCI1500_Z8536_CONTROL_REGISTER);
2010                         outb(0x00,
2011                                 devpriv->iobase +
2012                                 APCI1500_Z8536_CONTROL_REGISTER);
2013                         i_TimerCounter2Enabled = 0;
2014                         break;
2015                 case TRIGGER:
2016                         if (i_TimerCounter2Init == 1) {
2017                                 if (i_TimerCounter2Enabled == 1) {
2018                                                  /************************/
2019                                         /* Set Trigger and gate */
2020                                                  /************************/
2021
2022                                         i_CommandAndStatusValue = 0x6;
2023                                 }       /* if( i_TimerCounter2Enabled==1) */
2024                                 else {
2025                                                    /***************/
2026                                         /* Set Trigger */
2027                                                    /***************/
2028
2029                                         i_CommandAndStatusValue = 0x2;
2030                                 }       /* elseif(i_TimerCounter2Enabled==1) */
2031
2032                                                 /********************************************/
2033                                 /* Selects the commands and status register */
2034                                                 /********************************************/
2035                                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2036                                         devpriv->iobase +
2037                                         APCI1500_Z8536_CONTROL_REGISTER);
2038                                 outb(i_CommandAndStatusValue,
2039                                         devpriv->iobase +
2040                                         APCI1500_Z8536_CONTROL_REGISTER);
2041                         }       /* if( i_TimerCounter2Init==1) */
2042                         else {
2043                                 printk("\nCounter/Timer2 not configured\n");
2044                                 return -EINVAL;
2045                         }
2046                         break;
2047                 default:
2048                         printk("\nThe specified option for start/stop/trigger does not exist\n");
2049                         return -EINVAL;
2050                 }               /* switch(data[1]) */
2051                 break;
2052         case COUNTER3:
2053                 switch (data[1]) {
2054                 case START:
2055                         if (i_WatchdogCounter3Init == 1) {
2056
2057                                 if (i_TimerCounterWatchdogInterrupt == 1) {
2058                                         i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
2059                                 }       /*  if(i_TimerCounterWatchdogInterrupt==1) */
2060                                 else {
2061                                         i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
2062                                 }       /* elseif(i_TimerCounterWatchdogInterrupt==1) */
2063                                               /**************************/
2064                                 /* Starts Watchdog/counter 3 */
2065                                               /**************************/
2066                                 i_WatchdogCounter3Enabled = 1;
2067                                                 /********************************************/
2068                                 /* Selects the commands and status register */
2069                                                 /********************************************/
2070                                 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2071                                         devpriv->iobase +
2072                                         APCI1500_Z8536_CONTROL_REGISTER);
2073                                 outb(i_CommandAndStatusValue,
2074                                         devpriv->iobase +
2075                                         APCI1500_Z8536_CONTROL_REGISTER);
2076
2077                         }       /*  if( i_WatchdogCounter3init==1) */
2078                         else {
2079                                 printk("\nWatchdog/Counter3 not configured\n");
2080                                 return -EINVAL;
2081                         }
2082                         break;
2083
2084                 case STOP:
2085
2086                                               /**************************/
2087                         /* Stop Watchdog/counter 3 */
2088                                               /**************************/
2089
2090                                                 /********************************************/
2091                         /* Selects the commands and status register */
2092                                                 /********************************************/
2093                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2094                                 devpriv->iobase +
2095                                 APCI1500_Z8536_CONTROL_REGISTER);
2096                         outb(0x00,
2097                                 devpriv->iobase +
2098                                 APCI1500_Z8536_CONTROL_REGISTER);
2099                         i_WatchdogCounter3Enabled = 0;
2100                         break;
2101
2102                 case TRIGGER:
2103                         switch (data[2]) {
2104                         case 0: /* triggering counter 3 */
2105                                 if (i_WatchdogCounter3Init == 1) {
2106                                         if (i_WatchdogCounter3Enabled == 1) {
2107                                                                /************************/
2108                                                 /* Set Trigger and gate */
2109                                                                /************************/
2110
2111                                                 i_CommandAndStatusValue = 0x6;
2112                                         }       /* if( i_WatchdogCounter3Enabled==1) */
2113                                         else {
2114                                                            /***************/
2115                                                 /* Set Trigger */
2116                                                            /***************/
2117
2118                                                 i_CommandAndStatusValue = 0x2;
2119                                         }       /* elseif(i_WatchdogCounter3Enabled==1) */
2120
2121                                                 /********************************************/
2122                                         /* Selects the commands and status register */
2123                                                 /********************************************/
2124                                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2125                                                 devpriv->iobase +
2126                                                 APCI1500_Z8536_CONTROL_REGISTER);
2127                                         outb(i_CommandAndStatusValue,
2128                                                 devpriv->iobase +
2129                                                 APCI1500_Z8536_CONTROL_REGISTER);
2130                                 }       /* if( i_WatchdogCounter3Init==1) */
2131                                 else {
2132                                         printk("\nCounter3 not configured\n");
2133                                         return -EINVAL;
2134                                 }
2135                                 break;
2136                         case 1:
2137                                 /* triggering Watchdog 3 */
2138                                 if (i_WatchdogCounter3Init == 1) {
2139
2140                                                 /********************************************/
2141                                         /* Selects the commands and status register */
2142                                                 /********************************************/
2143                                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2144                                                 devpriv->iobase +
2145                                                 APCI1500_Z8536_CONTROL_REGISTER);
2146                                         outb(0x6,
2147                                                 devpriv->iobase +
2148                                                 APCI1500_Z8536_CONTROL_REGISTER);
2149                                 }       /* if( i_WatchdogCounter3Init==1) */
2150                                 else {
2151                                         printk("\nWatchdog 3 not configured\n");
2152                                         return -EINVAL;
2153                                 }
2154                                 break;
2155                         default:
2156                                 printk("\nWrong choice of watchdog/counter3\n");
2157                                 return -EINVAL;
2158                         }       /* switch(data[2]) */
2159                         break;
2160                 default:
2161                         printk("\nThe specified option for start/stop/trigger does not exist\n");
2162                         return -EINVAL;
2163                 }               /* switch(data[1]) */
2164                 break;
2165         default:
2166                 printk("\nThe specified choice for counter/watchdog/timer does not exist\n");
2167                 return -EINVAL;
2168         }                       /* switch(data[0]) */
2169         return insn->n;
2170 }
2171
2172 /*
2173 +----------------------------------------------------------------------------+
2174 | Function   Name   : int i_APCI1500_ReadCounterTimerWatchdog                |
2175 |                       (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
2176 |                    unsigned int *data);                                            |
2177 +----------------------------------------------------------------------------+
2178 | Task              : Read The Watchdog                                      |
2179 +----------------------------------------------------------------------------+
2180 | Input Parameters  :   struct comedi_device *dev      : Driver handle              |
2181 |                     struct comedi_subdevice *s,   :pointer to subdevice structure
2182 |                      struct comedi_insn *insn      :pointer to insn structure      |
2183 |                     unsigned int *data          : Data Pointer to read status  |
2184 |                      data[0]                : 0     Counter1/Timer1
2185 |                                               1     Counter2/Timer2
2186 |                                               2     Counter3/Watchdog
2187 |
2188 +----------------------------------------------------------------------------+
2189 | Output Parameters :   --                                                                                                       |
2190 +----------------------------------------------------------------------------+
2191 | Return Value      : TRUE  : No error occur                                 |
2192 |                           : FALSE : Error occur. Return the error          |
2193 |                                                                                |
2194 +----------------------------------------------------------------------------+
2195 */
2196 static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev,
2197                                                struct comedi_subdevice *s,
2198                                                struct comedi_insn *insn,
2199                                                unsigned int *data)
2200 {
2201         int i_CommandAndStatusValue;
2202         switch (data[0]) {
2203         case COUNTER1:
2204                 /* Read counter/timer1 */
2205                 if (i_TimerCounter1Init == 1) {
2206                         if (i_TimerCounter1Enabled == 1) {
2207                   /************************/
2208                                 /* Set RCC and gate */
2209                   /************************/
2210
2211                                 i_CommandAndStatusValue = 0xC;
2212                         }       /* if( i_TimerCounter1Init==1) */
2213                         else {
2214                     /***************/
2215                                 /* Set RCC */
2216                     /***************/
2217
2218                                 i_CommandAndStatusValue = 0x8;
2219                         }       /* elseif(i_TimerCounter1Init==1) */
2220
2221                 /********************************************/
2222                         /* Selects the commands and status register */
2223                 /********************************************/
2224                         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2225                                 devpriv->iobase +
2226                                 APCI1500_Z8536_CONTROL_REGISTER);
2227                         outb(i_CommandAndStatusValue,
2228                                 devpriv->iobase +
2229                                 APCI1500_Z8536_CONTROL_REGISTER);
2230
2231                  /***************************************/
2232                         /* Selects the counter register (high) */
2233                  /***************************************/
2234                         outb(APCI1500_R_CPT_TMR1_VALUE_HIGH,
2235                                 devpriv->iobase +
2236                                 APCI1500_Z8536_CONTROL_REGISTER);
2237                         data[0] =
2238                                 inb(devpriv->iobase +
2239                                 APCI1500_Z8536_CONTROL_REGISTER);
2240                         data[0] = data[0] << 8;
2241                         data[0] = data[0] & 0xff00;
2242                         outb(APCI1500_R_CPT_TMR1_VALUE_LOW,
2243                                 devpriv->iobase +
2244                                 APCI1500_Z8536_CONTROL_REGISTER);
2245                         data[0] =
2246                                 data[0] | inb(devpriv->iobase +
2247                                 APCI1500_Z8536_CONTROL_REGISTER);
2248                 }               /* if( i_TimerCounter1Init==1) */
2249                 else {
2250                         printk("\nTimer/Counter1 not configured\n");
2251                         return -EINVAL;
2252                 }               /* elseif( i_TimerCounter1Init==1) */
2253                 break;
2254         case COUNTER2:
2255                 /* Read counter/timer2 */
2256                 if (i_TimerCounter2Init == 1) {
2257                         if (i_TimerCounter2Enabled == 1) {
2258                   /************************/
2259                                 /* Set RCC and gate */
2260                   /************************/
2261
2262                                 i_CommandAndStatusValue = 0xC;
2263                         }       /* if( i_TimerCounter2Init==1) */
2264                         else {
2265                     /***************/
2266                                 /* Set RCC */
2267                     /***************/
2268
2269                                 i_CommandAndStatusValue = 0x8;
2270                         }       /* elseif(i_TimerCounter2Init==1) */
2271
2272                 /********************************************/
2273                         /* Selects the commands and status register */
2274                 /********************************************/
2275                         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2276                                 devpriv->iobase +
2277                                 APCI1500_Z8536_CONTROL_REGISTER);
2278                         outb(i_CommandAndStatusValue,
2279                                 devpriv->iobase +
2280                                 APCI1500_Z8536_CONTROL_REGISTER);
2281
2282                  /***************************************/
2283                         /* Selects the counter register (high) */
2284                  /***************************************/
2285                         outb(APCI1500_R_CPT_TMR2_VALUE_HIGH,
2286                                 devpriv->iobase +
2287                                 APCI1500_Z8536_CONTROL_REGISTER);
2288                         data[0] =
2289                                 inb(devpriv->iobase +
2290                                 APCI1500_Z8536_CONTROL_REGISTER);
2291                         data[0] = data[0] << 8;
2292                         data[0] = data[0] & 0xff00;
2293                         outb(APCI1500_R_CPT_TMR2_VALUE_LOW,
2294                                 devpriv->iobase +
2295                                 APCI1500_Z8536_CONTROL_REGISTER);
2296                         data[0] =
2297                                 data[0] | inb(devpriv->iobase +
2298                                 APCI1500_Z8536_CONTROL_REGISTER);
2299                 }               /* if( i_TimerCounter2Init==1) */
2300                 else {
2301                         printk("\nTimer/Counter2 not configured\n");
2302                         return -EINVAL;
2303                 }               /* elseif( i_TimerCounter2Init==1) */
2304                 break;
2305         case COUNTER3:
2306                 /* Read counter/watchdog2 */
2307                 if (i_WatchdogCounter3Init == 1) {
2308                         if (i_WatchdogCounter3Enabled == 1) {
2309                   /************************/
2310                                 /* Set RCC and gate */
2311                   /************************/
2312
2313                                 i_CommandAndStatusValue = 0xC;
2314                         }       /* if( i_TimerCounter2Init==1) */
2315                         else {
2316                     /***************/
2317                                 /* Set RCC */
2318                     /***************/
2319
2320                                 i_CommandAndStatusValue = 0x8;
2321                         }       /* elseif(i_WatchdogCounter3Init==1) */
2322
2323                 /********************************************/
2324                         /* Selects the commands and status register */
2325                 /********************************************/
2326                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2327                                 devpriv->iobase +
2328                                 APCI1500_Z8536_CONTROL_REGISTER);
2329                         outb(i_CommandAndStatusValue,
2330                                 devpriv->iobase +
2331                                 APCI1500_Z8536_CONTROL_REGISTER);
2332
2333                  /***************************************/
2334                         /* Selects the counter register (high) */
2335                  /***************************************/
2336                         outb(APCI1500_R_CPT_TMR3_VALUE_HIGH,
2337                                 devpriv->iobase +
2338                                 APCI1500_Z8536_CONTROL_REGISTER);
2339                         data[0] =
2340                                 inb(devpriv->iobase +
2341                                 APCI1500_Z8536_CONTROL_REGISTER);
2342                         data[0] = data[0] << 8;
2343                         data[0] = data[0] & 0xff00;
2344                         outb(APCI1500_R_CPT_TMR3_VALUE_LOW,
2345                                 devpriv->iobase +
2346                                 APCI1500_Z8536_CONTROL_REGISTER);
2347                         data[0] =
2348                                 data[0] | inb(devpriv->iobase +
2349                                 APCI1500_Z8536_CONTROL_REGISTER);
2350                 }               /* if( i_WatchdogCounter3Init==1) */
2351                 else {
2352                         printk("\nWatchdogCounter3 not configured\n");
2353                         return -EINVAL;
2354                 }               /* elseif( i_WatchdogCounter3Init==1) */
2355                 break;
2356         default:
2357                 printk("\nThe choice of timer/counter/watchdog does not exist\n");
2358                 return -EINVAL;
2359         }                       /* switch(data[0]) */
2360
2361         return insn->n;
2362 }
2363
2364 /*
2365 +----------------------------------------------------------------------------+
2366 | Function   Name   : int  i_APCI1500_ReadInterruptMask                      |
2367 |                       (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
2368 |                    unsigned int *data);                                            |
2369 +----------------------------------------------------------------------------+
2370 | Task              : Read the interrupt mask                                |
2371 +----------------------------------------------------------------------------+
2372 | Input Parameters  :   struct comedi_device *dev      : Driver handle              |
2373 |                     struct comedi_subdevice *s,   :pointer to subdevice structure
2374 |                      struct comedi_insn *insn      :pointer to insn structure      |
2375 |                     unsigned int *data          : Data Pointer to read status  |
2376
2377
2378 +----------------------------------------------------------------------------+
2379 | Output Parameters :   --      data[0]:The interrupt mask value                                                                                                                           data[1]:Channel no
2380 +----------------------------------------------------------------------------+
2381 | Return Value      : TRUE  : No error occur                                 |
2382 |                           : FALSE : Error occur. Return the error          |
2383 |                                                                                |
2384 +----------------------------------------------------------------------------+
2385 */
2386 static int i_APCI1500_ReadInterruptMask(struct comedi_device *dev,
2387                                         struct comedi_subdevice *s,
2388                                         struct comedi_insn *insn,
2389                                         unsigned int *data)
2390 {
2391         data[0] = i_InterruptMask;
2392         data[1] = i_InputChannel;
2393         i_InterruptMask = 0;
2394         return insn->n;
2395 }
2396
2397 /*
2398 +----------------------------------------------------------------------------+
2399 | Function   Name   : int  i_APCI1500_ConfigureInterrupt                     |
2400 |                       (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
2401 |                    unsigned int *data);                                            |
2402 +----------------------------------------------------------------------------+
2403 | Task              : Configures the interrupt registers                     |
2404 +----------------------------------------------------------------------------+
2405 | Input Parameters  :   struct comedi_device *dev      : Driver handle              |
2406 |                     struct comedi_subdevice *s,   :pointer to subdevice structure
2407 |                      struct comedi_insn *insn      :pointer to insn structure      |
2408 |                     unsigned int *data          : Data Pointer                 |
2409 |
2410
2411 +----------------------------------------------------------------------------+
2412 | Output Parameters :   --
2413 +----------------------------------------------------------------------------+
2414 | Return Value      : TRUE  : No error occur                                 |
2415 |                           : FALSE : Error occur. Return the error          |
2416 |                                                                                |
2417 +----------------------------------------------------------------------------+
2418 */
2419 static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev,
2420                                          struct comedi_subdevice *s,
2421                                          struct comedi_insn *insn,
2422                                          unsigned int *data)
2423 {
2424         unsigned int ui_Status;
2425         int i_RegValue;
2426         int i_Constant;
2427         devpriv->tsk_Current = current;
2428         outl(0x0, devpriv->i_IobaseAmcc + 0x38);
2429         if (data[0] == 1) {
2430                 i_Constant = 0xC0;
2431         }                       /* if(data[0]==1) */
2432         else {
2433                 if (data[0] == 0) {
2434                         i_Constant = 0x00;
2435                 }               /* if{data[0]==0) */
2436                 else {
2437                         printk("\nThe parameter passed to driver is in error for enabling the voltage interrupt\n");
2438                         return -EINVAL;
2439                 }               /* else if(data[0]==0) */
2440         }                       /* elseif(data[0]==1) */
2441
2442          /*****************************************************/
2443         /* Selects the mode specification register of port B */
2444          /*****************************************************/
2445         outb(APCI1500_RW_PORT_B_SPECIFICATION,
2446                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2447         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2448         outb(APCI1500_RW_PORT_B_SPECIFICATION,
2449                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2450       /*********************************************/
2451         /* Writes the new configuration (APCI1500_OR) */
2452       /*********************************************/
2453         i_RegValue = (i_RegValue & 0xF9) | APCI1500_OR;
2454
2455         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2456        /*****************************************************/
2457         /* Selects the command and status register of port B */
2458        /*****************************************************/
2459         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2460                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2461         /*****************************************/
2462         /* Authorises the interrupt on the board */
2463         /*****************************************/
2464         outb(0xC0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2465         /***************************************************/
2466         /* Selects the pattern polarity register of port B */
2467         /***************************************************/
2468         outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
2469                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2470         outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2471         /*****************************************************/
2472         /* Selects the pattern transition register of port B */
2473         /*****************************************************/
2474         outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
2475                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2476         outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2477         /***********************************************/
2478         /* Selects the pattern mask register of port B */
2479         /***********************************************/
2480         outb(APCI1500_RW_PORT_B_PATTERN_MASK,
2481                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2482         outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2483
2484         /*****************************************************/
2485         /* Selects the command and status register of port A */
2486         /*****************************************************/
2487         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2488                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2489         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2490         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2491                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2492          /***********************************/
2493         /* Deletes the interrupt of port A */
2494          /***********************************/
2495
2496         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2497         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2498         /*****************************************************/
2499         /* Selects the command and status register of port  B */
2500         /*****************************************************/
2501         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2502                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2503         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2504         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2505                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2506          /***********************************/
2507         /* Deletes the interrupt of port B */
2508          /***********************************/
2509
2510         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2511         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2512
2513         /*****************************************************/
2514         /* Selects the command and status register of timer 1 */
2515         /*****************************************************/
2516         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2517                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2518         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2519         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2520                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2521          /***********************************/
2522         /* Deletes the interrupt of timer 1 */
2523          /***********************************/
2524
2525         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2526         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2527
2528          /*****************************************************/
2529         /* Selects the command and status register of timer 2 */
2530         /*****************************************************/
2531         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2532                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2533         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2534         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2535                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2536          /***********************************/
2537         /* Deletes the interrupt of timer 2 */
2538          /***********************************/
2539
2540         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2541         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2542
2543         /*****************************************************/
2544         /* Selects the command and status register of timer 3 */
2545         /*****************************************************/
2546         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2547                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2548         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2549         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2550                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2551          /***********************************/
2552         /* Deletes the interrupt of timer 3 */
2553          /***********************************/
2554
2555         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2556         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2557
2558          /*************************************************/
2559         /* Selects the master interrupt control register */
2560          /*************************************************/
2561         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2562                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2563         /**********************************************/
2564         /* Authorizes the main interrupt on the board */
2565         /**********************************************/
2566         outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2567
2568       /***************************/
2569         /* Enables the PCI interrupt */
2570       /*****************************/
2571         outl(0x3000, devpriv->i_IobaseAmcc + 0x38);
2572         ui_Status = inl(devpriv->i_IobaseAmcc + 0x10);
2573         ui_Status = inl(devpriv->i_IobaseAmcc + 0x38);
2574         outl(0x23000, devpriv->i_IobaseAmcc + 0x38);
2575
2576         return insn->n;
2577 }
2578
2579 /*
2580 +----------------------------------------------------------------------------+
2581 | Function   Name   : static void v_APCI1500_Interrupt                                       |
2582 |                                         (int irq , void *d)      |
2583 +----------------------------------------------------------------------------+
2584 | Task              : Interrupt handler                                      |
2585 +----------------------------------------------------------------------------+
2586 | Input Parameters  : int irq                 : irq number                   |
2587 |                     void *d                 : void pointer                 |
2588 +----------------------------------------------------------------------------+
2589 | Output Parameters :   --                                                                                                       |
2590 +----------------------------------------------------------------------------+
2591 | Return Value      : TRUE  : No error occur                                 |
2592 |                           : FALSE : Error occur. Return the error          |
2593 |                                                                                |
2594 +----------------------------------------------------------------------------+
2595 */
2596 static void v_APCI1500_Interrupt(int irq, void *d)
2597 {
2598
2599         struct comedi_device *dev = d;
2600         unsigned int ui_InterruptStatus = 0;
2601         int i_RegValue = 0;
2602         i_InterruptMask = 0;
2603
2604  /***********************************/
2605         /* Read the board interrupt status */
2606  /***********************************/
2607         ui_InterruptStatus = inl(devpriv->i_IobaseAmcc + 0x38);
2608
2609   /***************************************/
2610         /* Test if board generated a interrupt */
2611   /***************************************/
2612         if ((ui_InterruptStatus & 0x800000) == 0x800000) {
2613       /************************/
2614                 /* Disable all Interrupt */
2615       /************************/
2616       /*************************************************/
2617                 /* Selects the master interrupt control register */
2618       /*************************************************/
2619                 /* outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER); */
2620         /**********************************************/
2621                 /* Disables  the main interrupt on the board */
2622         /**********************************************/
2623                 /* outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER); */
2624
2625    /*****************************************************/
2626                 /* Selects the command and status register of port A */
2627    /*****************************************************/
2628                 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2629                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2630                 i_RegValue =
2631                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2632                 if ((i_RegValue & 0x60) == 0x60) {
2633            /*****************************************************/
2634                         /* Selects the command and status register of port A */
2635            /*****************************************************/
2636                         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2637                                 devpriv->iobase +
2638                                 APCI1500_Z8536_CONTROL_REGISTER);
2639             /***********************************/
2640                         /* Deletes the interrupt of port A */
2641             /***********************************/
2642                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2643                         outb(i_RegValue,
2644                                 devpriv->iobase +
2645                                 APCI1500_Z8536_CONTROL_REGISTER);
2646                         i_InterruptMask = i_InterruptMask | 1;
2647                         if (i_Logic == APCI1500_OR_PRIORITY) {
2648                                 outb(APCI1500_RW_PORT_A_SPECIFICATION,
2649                                         devpriv->iobase +
2650                                         APCI1500_Z8536_CONTROL_REGISTER);
2651                                 i_RegValue =
2652                                         inb(devpriv->iobase +
2653                                         APCI1500_Z8536_CONTROL_REGISTER);
2654
2655               /***************************************************/
2656                                 /* Selects the interrupt vector register of port A */
2657               /***************************************************/
2658                                 outb(APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
2659                                         devpriv->iobase +
2660                                         APCI1500_Z8536_CONTROL_REGISTER);
2661                                 i_RegValue =
2662                                         inb(devpriv->iobase +
2663                                         APCI1500_Z8536_CONTROL_REGISTER);
2664
2665                                 i_InputChannel = 1 + (i_RegValue >> 1);
2666
2667                         }       /*  if(i_Logic==APCI1500_OR_PRIORITY) */
2668                         else {
2669                                 i_InputChannel = 0;
2670                         }       /* elseif(i_Logic==APCI1500_OR_PRIORITY) */
2671                 }               /*  if ((i_RegValue & 0x60) == 0x60) */
2672
2673            /*****************************************************/
2674                 /* Selects the command and status register of port B */
2675            /*****************************************************/
2676                 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2677                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2678                 i_RegValue =
2679                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2680                 if ((i_RegValue & 0x60) == 0x60) {
2681              /*****************************************************/
2682                         /* Selects the command and status register of port B */
2683              /*****************************************************/
2684                         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2685                                 devpriv->iobase +
2686                                 APCI1500_Z8536_CONTROL_REGISTER);
2687              /***********************************/
2688                         /* Deletes the interrupt of port B */
2689              /***********************************/
2690                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2691                         outb(i_RegValue,
2692                                 devpriv->iobase +
2693                                 APCI1500_Z8536_CONTROL_REGISTER);
2694                         printk("\n\n\n");
2695              /****************/
2696                         /* Reads port B */
2697              /****************/
2698                         i_RegValue =
2699                                 inb((unsigned int) devpriv->iobase +
2700                                 APCI1500_Z8536_PORT_B);
2701
2702                         i_RegValue = i_RegValue & 0xC0;
2703               /**************************************/
2704                         /* Tests if this is an external error */
2705               /**************************************/
2706
2707                         if (i_RegValue) {
2708                                 /* Disable the interrupt */
2709                      /*****************************************************/
2710                                 /* Selects the command and status register of port B */
2711                      /*****************************************************/
2712                                 outl(0x0, devpriv->i_IobaseAmcc + 0x38);
2713
2714                                 if (i_RegValue & 0x80) {
2715                                         i_InterruptMask =
2716                                                 i_InterruptMask | 0x40;
2717                                 }       /* if (i_RegValue & 0x80) */
2718
2719                                 if (i_RegValue & 0x40) {
2720                                         i_InterruptMask =
2721                                                 i_InterruptMask | 0x80;
2722                                 }       /* if (i_RegValue & 0x40) */
2723                         }       /*  if (i_RegValue) */
2724                         else {
2725                                 i_InterruptMask = i_InterruptMask | 2;
2726                         }       /*  if (i_RegValue) */
2727                 }               /* if ((i_RegValue & 0x60) == 0x60) */
2728
2729                 /*****************************************************/
2730                 /* Selects the command and status register of timer 1 */
2731                 /*****************************************************/
2732                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2733                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2734                 i_RegValue =
2735                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2736                 if ((i_RegValue & 0x60) == 0x60) {
2737                    /*****************************************************/
2738                         /* Selects the command and status register of timer 1 */
2739                    /*****************************************************/
2740                         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2741                                 devpriv->iobase +
2742                                 APCI1500_Z8536_CONTROL_REGISTER);
2743                    /***********************************/
2744                         /* Deletes the interrupt of timer 1 */
2745                    /***********************************/
2746                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2747                         outb(i_RegValue,
2748                                 devpriv->iobase +
2749                                 APCI1500_Z8536_CONTROL_REGISTER);
2750                         i_InterruptMask = i_InterruptMask | 4;
2751                 }               /*  if ((i_RegValue & 0x60) == 0x60) */
2752                 /*****************************************************/
2753                 /* Selects the command and status register of timer 2 */
2754                 /*****************************************************/
2755                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2756                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2757                 i_RegValue =
2758                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2759                 if ((i_RegValue & 0x60) == 0x60) {
2760                    /*****************************************************/
2761                         /* Selects the command and status register of timer 2 */
2762                    /*****************************************************/
2763                         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2764                                 devpriv->iobase +
2765                                 APCI1500_Z8536_CONTROL_REGISTER);
2766                    /***********************************/
2767                         /* Deletes the interrupt of timer 2 */
2768                    /***********************************/
2769                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2770                         outb(i_RegValue,
2771                                 devpriv->iobase +
2772                                 APCI1500_Z8536_CONTROL_REGISTER);
2773                         i_InterruptMask = i_InterruptMask | 8;
2774                 }               /*  if ((i_RegValue & 0x60) == 0x60) */
2775
2776                 /*****************************************************/
2777                 /* Selects the command and status register of timer 3 */
2778                 /*****************************************************/
2779                 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2780                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2781                 i_RegValue =
2782                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2783                 if ((i_RegValue & 0x60) == 0x60) {
2784                    /*****************************************************/
2785                         /* Selects the command and status register of timer 3 */
2786                    /*****************************************************/
2787                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2788                                 devpriv->iobase +
2789                                 APCI1500_Z8536_CONTROL_REGISTER);
2790                    /***********************************/
2791                         /* Deletes the interrupt of timer 3 */
2792                    /***********************************/
2793                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2794                         outb(i_RegValue,
2795                                 devpriv->iobase +
2796                                 APCI1500_Z8536_CONTROL_REGISTER);
2797                         if (i_CounterLogic == APCI1500_COUNTER) {
2798                                 i_InterruptMask = i_InterruptMask | 0x10;
2799                         }       /* if(i_CounterLogic==APCI1500_COUNTER) */
2800                         else {
2801                                 i_InterruptMask = i_InterruptMask | 0x20;
2802                         }
2803                 }               /*  if ((i_RegValue & 0x60) == 0x60) */
2804
2805                 send_sig(SIGIO, devpriv->tsk_Current, 0);       /*  send signal to the sample */
2806                /***********************/
2807                 /* Enable all Interrupts */
2808                /***********************/
2809
2810                /*************************************************/
2811                 /* Selects the master interrupt control register */
2812                /*************************************************/
2813                 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2814                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2815                /**********************************************/
2816                 /* Authorizes the main interrupt on the board */
2817                /**********************************************/
2818                 outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2819         }                       /*   if ((ui_InterruptStatus & 0x800000) == 0x800000) */
2820         else {
2821                 printk("\nInterrupt from unknown source\n");
2822
2823         }                       /* else if ((ui_InterruptStatus & 0x800000) == 0x800000) */
2824         return;
2825 }
2826
2827 /*
2828 +----------------------------------------------------------------------------+
2829 | Function   Name   : int i_APCI1500_Reset(struct comedi_device *dev)               |                                                       |
2830 +----------------------------------------------------------------------------+
2831 | Task              :resets all the registers                                |
2832 +----------------------------------------------------------------------------+
2833 | Input Parameters  : struct comedi_device *dev
2834 +----------------------------------------------------------------------------+
2835 | Output Parameters :   --                                                                                                       |
2836 +----------------------------------------------------------------------------+
2837 | Return Value      :                                                        |
2838 |                                                                                |
2839 +----------------------------------------------------------------------------+
2840 */
2841 static int i_APCI1500_Reset(struct comedi_device *dev)
2842 {
2843         int i_DummyRead = 0;
2844         i_TimerCounter1Init = 0;
2845         i_TimerCounter2Init = 0;
2846         i_WatchdogCounter3Init = 0;
2847         i_Event1Status = 0;
2848         i_Event2Status = 0;
2849         i_TimerCounterWatchdogInterrupt = 0;
2850         i_Logic = 0;
2851         i_CounterLogic = 0;
2852         i_InterruptMask = 0;
2853         i_InputChannel = 0;
2854         i_TimerCounter1Enabled = 0;
2855         i_TimerCounter2Enabled = 0;
2856         i_WatchdogCounter3Enabled = 0;
2857
2858     /******************/
2859         /* Software reset */
2860     /******************/
2861         i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2862         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2863         i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2864         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2865         outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2866         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2867
2868  /*****************************************************/
2869         /* Selects the master configuration control register */
2870  /*****************************************************/
2871         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
2872                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2873         outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2874
2875         /*****************************************************/
2876         /* Selects the mode specification register of port A */
2877         /*****************************************************/
2878         outb(APCI1500_RW_PORT_A_SPECIFICATION,
2879                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2880         outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2881
2882         /* Selects the data path polarity register of port A */
2883         outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
2884                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2885         /* High level of port A means 1 */
2886         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2887
2888         /* Selects the data direction register of port A */
2889         outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
2890                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2891         /* All bits used as inputs */
2892         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2893         /* Selects the command and status register of port A */
2894         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2895                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2896         /* Deletes IP and IUS */
2897         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2898         /*  Selects the command and status register of port A */
2899         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2900                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2901         /* Deactivates the interrupt management of port A:  */
2902         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2903         /* Selects the handshake specification register of port A */
2904         outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
2905                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2906         /* Deletes the register */
2907         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2908
2909          /*****************************************************/
2910         /* Selects the mode specification register of port B */
2911          /*****************************************************/
2912         outb(APCI1500_RW_PORT_B_SPECIFICATION,
2913                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2914         outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2915         /* Selects the data path polarity register of port B */
2916         outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
2917                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2918         /* A high level of port B means 1 */
2919         outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2920         /* Selects the data direction register of port B */
2921         outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
2922                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2923         /* All bits used as inputs */
2924         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2925         /* Selects the command and status register of port B */
2926         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2927                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2928         /* Deletes IP and IUS */
2929         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2930         /* Selects the command and status register of port B */
2931         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2932                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2933         /* Deactivates the interrupt management of port B:         */
2934         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2935         /* Selects the handshake specification register of port B */
2936         outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
2937                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2938         /* Deletes the register */
2939         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2940
2941            /*****************************************************/
2942         /* Selects the data path polarity register of port C */
2943            /*****************************************************/
2944         outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
2945                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2946         /* High level of port C means 1 */
2947         outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2948         /* Selects the data direction register of port C */
2949         outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
2950                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2951         /* All bits used as inputs except channel 1 */
2952         outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2953         /* Selects the special IO register of port C */
2954         outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
2955                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2956         /* Deletes it */
2957         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2958            /******************************************************/
2959         /* Selects the command and status register of timer 1 */
2960            /******************************************************/
2961         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2962                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2963         /* Deletes IP and IUS */
2964         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2965         /* Selects the command and status register of timer 1 */
2966         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2967                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2968         /* Deactivates the interrupt management of timer 1         */
2969         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2970            /******************************************************/
2971         /* Selects the command and status register of timer 2 */
2972            /******************************************************/
2973         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2974                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2975         /* Deletes IP and IUS */
2976         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2977         /* Selects the command and status register of timer 2 */
2978         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2979                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2980         /* Deactivates Timer 2 interrupt management:               */
2981         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2982           /******************************************************/
2983         /* Selects the command and status register of timer 3 */
2984           /******************************************************/
2985         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2986                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2987         /* Deletes IP and IUS */
2988         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2989         /* Selects the command and status register of Timer 3 */
2990         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2991                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2992         /* Deactivates interrupt management of timer 3:            */
2993         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2994          /*************************************************/
2995         /* Selects the master interrupt control register */
2996          /*************************************************/
2997         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2998                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2999         /* Deletes all interrupts */
3000         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3001         /* reset all the digital outputs */
3002         outw(0x0, devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
3003 /*******************************/
3004 /* Disable the board interrupt */
3005 /*******************************/
3006  /*************************************************/
3007         /* Selects the master interrupt control register */
3008  /*************************************************/
3009         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
3010                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3011 /****************************/
3012 /* Deactivates all interrupts */
3013 /******************************/
3014         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3015  /*****************************************************/
3016         /* Selects the command and status register of port A */
3017  /*****************************************************/
3018         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
3019                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3020 /****************************/
3021 /* Deactivates all interrupts */
3022 /******************************/
3023         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3024 /*****************************************************/
3025         /* Selects the command and status register of port B */
3026  /*****************************************************/
3027         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
3028                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3029 /****************************/
3030 /* Deactivates all interrupts */
3031 /******************************/
3032         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3033 /*****************************************************/
3034         /* Selects the command and status register of timer 1 */
3035  /*****************************************************/
3036         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
3037                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3038 /****************************/
3039 /* Deactivates all interrupts */
3040 /******************************/
3041         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3042 /*****************************************************/
3043         /* Selects the command and status register of timer 2 */
3044  /*****************************************************/
3045         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
3046                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3047 /****************************/
3048 /* Deactivates all interrupts */
3049 /******************************/
3050         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3051 /*****************************************************/
3052 /* Selects the command and status register of timer 3*/
3053 /*****************************************************/
3054         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
3055                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3056 /****************************/
3057 /* Deactivates all interrupts */
3058 /******************************/
3059         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
3060         return 0;
3061 }