Linux 3.18-rc3
[cascardo/linux.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci1500.c
1 /*
2  * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
3  *
4  *      ADDI-DATA GmbH
5  *      Dieselstrasse 3
6  *      D-77833 Ottersweier
7  *      Tel: +19(0)7223/9493-0
8  *      Fax: +49(0)7223/9493-92
9  *      http://www.addi-data.com
10  *      info@addi-data.com
11  *
12  * This program is free software; you can redistribute it and/or modify it under
13  * the terms of the GNU General Public License as published by the Free Software
14  * Foundation; either version 2 of the License, or (at your option) any later
15  * version.
16  *
17  * This program is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
20  * details.
21  *
22  */
23
24 /* Card Specific information */
25 #define APCI1500_ADDRESS_RANGE          4
26
27 /* DIGITAL INPUT-OUTPUT DEFINE */
28
29 #define APCI1500_DIGITAL_OP             2
30 #define APCI1500_DIGITAL_IP             0
31 #define APCI1500_AND                    2
32 #define APCI1500_OR                     4
33 #define APCI1500_OR_PRIORITY            6
34 #define APCI1500_CLK_SELECT             0
35 #define COUNTER1                        0
36 #define COUNTER2                        1
37 #define COUNTER3                        2
38 #define APCI1500_COUNTER                0x20
39 #define APCI1500_TIMER                  0
40 #define APCI1500_WATCHDOG               0
41 #define APCI1500_SINGLE                 0
42 #define APCI1500_CONTINUOUS             0x80
43 #define APCI1500_DISABLE                0
44 #define APCI1500_ENABLE                 1
45 #define APCI1500_SOFTWARE_TRIGGER       0x4
46 #define APCI1500_HARDWARE_TRIGGER       0x10
47 #define APCI1500_SOFTWARE_GATE          0
48 #define APCI1500_HARDWARE_GATE          0x8
49 #define START                           0
50 #define STOP                            1
51 #define TRIGGER                         2
52
53 /*
54  * Zillog I/O enumeration
55  */
56 enum {
57         APCI1500_Z8536_PORT_C,
58         APCI1500_Z8536_PORT_B,
59         APCI1500_Z8536_PORT_A,
60         APCI1500_Z8536_CONTROL_REGISTER
61 };
62
63 /*
64  * Z8536 CIO Internal Address
65  */
66 enum {
67         APCI1500_RW_MASTER_INTERRUPT_CONTROL,
68         APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
69         APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
70         APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
71         APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
72         APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
73         APCI1500_RW_PORT_C_DATA_DIRECTION,
74         APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
75
76         APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
77         APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
78         APCI1500_RW_CPT_TMR1_CMD_STATUS,
79         APCI1500_RW_CPT_TMR2_CMD_STATUS,
80         APCI1500_RW_CPT_TMR3_CMD_STATUS,
81         APCI1500_RW_PORT_A_DATA,
82         APCI1500_RW_PORT_B_DATA,
83         APCI1500_RW_PORT_C_DATA,
84
85         APCI1500_R_CPT_TMR1_VALUE_HIGH,
86         APCI1500_R_CPT_TMR1_VALUE_LOW,
87         APCI1500_R_CPT_TMR2_VALUE_HIGH,
88         APCI1500_R_CPT_TMR2_VALUE_LOW,
89         APCI1500_R_CPT_TMR3_VALUE_HIGH,
90         APCI1500_R_CPT_TMR3_VALUE_LOW,
91         APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
92         APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
93         APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
94         APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
95         APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
96         APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
97         APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
98         APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
99         APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
100         APCI1500_R_CURRENT_VECTOR,
101
102         APCI1500_RW_PORT_A_SPECIFICATION,
103         APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
104         APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
105         APCI1500_RW_PORT_A_DATA_DIRECTION,
106         APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
107         APCI1500_RW_PORT_A_PATTERN_POLARITY,
108         APCI1500_RW_PORT_A_PATTERN_TRANSITION,
109         APCI1500_RW_PORT_A_PATTERN_MASK,
110
111         APCI1500_RW_PORT_B_SPECIFICATION,
112         APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
113         APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
114         APCI1500_RW_PORT_B_DATA_DIRECTION,
115         APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
116         APCI1500_RW_PORT_B_PATTERN_POLARITY,
117         APCI1500_RW_PORT_B_PATTERN_TRANSITION,
118         APCI1500_RW_PORT_B_PATTERN_MASK
119 };
120
121 static int i_TimerCounter1Init;
122 static int i_TimerCounter2Init;
123 static int i_WatchdogCounter3Init;
124 static int i_Event1Status, i_Event2Status;
125 static int i_TimerCounterWatchdogInterrupt;
126 static int i_Logic, i_CounterLogic;
127 static int i_InterruptMask;
128 static int i_InputChannel;
129 static int i_TimerCounter1Enabled, i_TimerCounter2Enabled,
130            i_WatchdogCounter3Enabled;
131
132 /*
133  * An event can be generated for each port. The first event is related to the
134  * first 8 channels (port 1) and the second to the following 6 channels (port 2)
135  * An interrupt is generated when one or both events have occurred.
136  *
137  * data[0] Number of the input port on which the event will take place (1 or 2)
138  * data[1] The event logic for port 1 has three possibilities:
139  *      APCI1500_AND            This logic links the inputs with an AND logic.
140  *      APCI1500_OR             This logic links the inputs with a OR logic.
141  *      APCI1500_OR_PRIORITY    This logic links the inputs with a priority OR
142  *                              logic. Input 1 has the highest priority level
143  *                              and input 8 the smallest.
144  *      For the second port the user has 1 possibility:
145  *      APCI1500_OR     This logic links the inputs with a polarity OR logic
146  * data[2] These 8-character word for port1 and 6-character word for port 2
147  *         give the mask of the event. Each place gives the state of the input
148  *         channels and can have one of these six characters
149  *      0 This input must be on 0
150  *      1 This input must be on 1
151  *      2 This input reacts to a falling edge
152  *      3 This input reacts to a rising edge
153  *      4 This input reacts to both edges
154  *      5 This input is not used for event
155  */
156 static int apci1500_di_config(struct comedi_device *dev,
157                               struct comedi_subdevice *s,
158                               struct comedi_insn *insn,
159                               unsigned int *data)
160 {
161         struct addi_private *devpriv = dev->private;
162         int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0;
163         int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0;
164         int i_PatternTransitionCount = 0, i_RegValue;
165         int i;
166
167         /* Selects the master interrupt control register */
168         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
169                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
170         /* Disables  the main interrupt on the board */
171         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
172
173         if (data[0] == 1) {
174                 i_MaxChannel = 8;
175         } else {
176                 if (data[0] == 2) {
177                         i_MaxChannel = 6;
178                 } else {
179                         dev_warn(dev->class_dev,
180                                 "The specified port event does not exist\n");
181                         return -EINVAL;
182                 }
183         }
184         switch (data[1]) {
185         case 0:
186                 data[1] = APCI1500_AND;
187                 break;
188         case 1:
189                 data[1] = APCI1500_OR;
190                 break;
191         case 2:
192                 data[1] = APCI1500_OR_PRIORITY;
193                 break;
194         default:
195                 dev_warn(dev->class_dev,
196                         "The specified interrupt logic does not exist\n");
197                 return -EINVAL;
198         }
199
200         i_Logic = data[1];
201         for (i_Count = i_MaxChannel, i = 0; i_Count > 0; i_Count--, i++) {
202                 i_EventMask = data[2 + i];
203                 switch (i_EventMask) {
204                 case 0:
205                         i_PatternMask =
206                                 i_PatternMask | (1 << (i_MaxChannel - i_Count));
207                         break;
208                 case 1:
209                         i_PatternMask =
210                                 i_PatternMask | (1 << (i_MaxChannel - i_Count));
211                         i_PatternPolarity =
212                                 i_PatternPolarity | (1 << (i_MaxChannel -
213                                         i_Count));
214                         break;
215                 case 2:
216                         i_PatternMask =
217                                 i_PatternMask | (1 << (i_MaxChannel - i_Count));
218                         i_PatternTransition =
219                                 i_PatternTransition | (1 << (i_MaxChannel -
220                                         i_Count));
221                         break;
222                 case 3:
223                         i_PatternMask =
224                                 i_PatternMask | (1 << (i_MaxChannel - i_Count));
225                         i_PatternPolarity =
226                                 i_PatternPolarity | (1 << (i_MaxChannel -
227                                         i_Count));
228                         i_PatternTransition =
229                                 i_PatternTransition | (1 << (i_MaxChannel -
230                                         i_Count));
231                         break;
232                 case 4:
233                         i_PatternTransition =
234                                 i_PatternTransition | (1 << (i_MaxChannel -
235                                         i_Count));
236                         break;
237                 case 5:
238                         break;
239                 default:
240                         dev_warn(dev->class_dev,
241                                 "The option indicated in the event mask does not exist\n");
242                         return -EINVAL;
243                 }
244         }
245
246         if (data[0] == 1) {
247                 /* Test the interrupt logic */
248
249                 if (data[1] == APCI1500_AND ||
250                         data[1] == APCI1500_OR ||
251                         data[1] == APCI1500_OR_PRIORITY) {
252                         /* Tests if a transition was declared */
253                         /* for a OR PRIORITY logic            */
254
255                         if (data[1] == APCI1500_OR_PRIORITY
256                                 && i_PatternTransition != 0) {
257                                 dev_warn(dev->class_dev,
258                                         "Transition error on an OR PRIORITY logic\n");
259                                 return -EINVAL;
260                         }
261
262                         /* Tests if more than one transition */
263                         /* was declared for an AND logic     */
264
265                         if (data[1] == APCI1500_AND) {
266                                 for (i_Count = 0; i_Count < 8; i_Count++) {
267                                         i_PatternTransitionCount =
268                                                 i_PatternTransitionCount +
269                                                 ((i_PatternTransition >>
270                                                         i_Count) & 0x1);
271
272                                 }
273
274                                 if (i_PatternTransitionCount > 1) {
275                                         dev_warn(dev->class_dev,
276                                                 "Transition error on an AND logic\n");
277                                         return -EINVAL;
278                                 }
279                         }
280
281                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
282                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
283                                 devpriv->iobase +
284                                 APCI1500_Z8536_CONTROL_REGISTER);
285                         /* Disable Port A */
286                         outb(0xF0,
287                                 devpriv->iobase +
288                                 APCI1500_Z8536_CONTROL_REGISTER);
289                         /* Selects the polarity register of port 1    */
290                         outb(APCI1500_RW_PORT_A_PATTERN_POLARITY,
291                                 devpriv->iobase +
292                                 APCI1500_Z8536_CONTROL_REGISTER);
293                         outb(i_PatternPolarity,
294                                 devpriv->iobase +
295                                 APCI1500_Z8536_CONTROL_REGISTER);
296
297                         /* Selects the pattern mask register of      */
298                         /* port 1                                    */
299                         outb(APCI1500_RW_PORT_A_PATTERN_MASK,
300                                 devpriv->iobase +
301                                 APCI1500_Z8536_CONTROL_REGISTER);
302                         outb(i_PatternMask,
303                                 devpriv->iobase +
304                                 APCI1500_Z8536_CONTROL_REGISTER);
305                         /* Selects the pattern transition register  */
306                         /* of port 1                                */
307                         outb(APCI1500_RW_PORT_A_PATTERN_TRANSITION,
308                                 devpriv->iobase +
309                                 APCI1500_Z8536_CONTROL_REGISTER);
310                         outb(i_PatternTransition,
311                                 devpriv->iobase +
312                                 APCI1500_Z8536_CONTROL_REGISTER);
313
314                         /* Selects the mode specification mask    */
315                         /* register of port 1                     */
316                         outb(APCI1500_RW_PORT_A_SPECIFICATION,
317                                 devpriv->iobase +
318                                 APCI1500_Z8536_CONTROL_REGISTER);
319                         i_RegValue =
320                                 inb(devpriv->iobase +
321                                 APCI1500_Z8536_CONTROL_REGISTER);
322
323                         /* Selects the mode specification mask    */
324                         /* register of port 1                     */
325                         outb(APCI1500_RW_PORT_A_SPECIFICATION,
326                                 devpriv->iobase +
327                                 APCI1500_Z8536_CONTROL_REGISTER);
328
329                         /* Port A new mode    */
330
331                         i_RegValue = (i_RegValue & 0xF9) | data[1] | 0x9;
332                         outb(i_RegValue,
333                                 devpriv->iobase +
334                                 APCI1500_Z8536_CONTROL_REGISTER);
335
336                         i_Event1Status = 1;
337
338                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
339
340                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
341                                 devpriv->iobase +
342                                 APCI1500_Z8536_CONTROL_REGISTER);
343                         /* Enable Port A */
344                         outb(0xF4,
345                                 devpriv->iobase +
346                                 APCI1500_Z8536_CONTROL_REGISTER);
347
348                 } else {
349                         dev_warn(dev->class_dev,
350                                 "The choice for interrupt logic does not exist\n");
351                         return -EINVAL;
352                 }
353         }
354
355         /* Test if event setting for port 2 */
356
357         if (data[0] == 2) {
358                 /* Test the event logic */
359
360                 if (data[1] == APCI1500_OR) {
361                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
362                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
363                                 devpriv->iobase +
364                                 APCI1500_Z8536_CONTROL_REGISTER);
365                         /* Disable Port B */
366                         outb(0x74,
367                                 devpriv->iobase +
368                                 APCI1500_Z8536_CONTROL_REGISTER);
369                         /* Selects the mode specification mask  */
370                         /* register of port B                   */
371                         outb(APCI1500_RW_PORT_B_SPECIFICATION,
372                                 devpriv->iobase +
373                                 APCI1500_Z8536_CONTROL_REGISTER);
374                         i_RegValue =
375                                 inb(devpriv->iobase +
376                                 APCI1500_Z8536_CONTROL_REGISTER);
377
378                         /* Selects the mode specification mask    */
379                         /* register of port B                     */
380                         outb(APCI1500_RW_PORT_B_SPECIFICATION,
381                                 devpriv->iobase +
382                                 APCI1500_Z8536_CONTROL_REGISTER);
383                         i_RegValue = i_RegValue & 0xF9;
384                         outb(i_RegValue,
385                                 devpriv->iobase +
386                                 APCI1500_Z8536_CONTROL_REGISTER);
387
388                         /* Selects error channels 1 and 2 */
389
390                         i_PatternMask = (i_PatternMask | 0xC0);
391                         i_PatternPolarity = (i_PatternPolarity | 0xC0);
392                         i_PatternTransition = (i_PatternTransition | 0xC0);
393
394                         /* Selects the polarity register of port 2    */
395                         outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
396                                 devpriv->iobase +
397                                 APCI1500_Z8536_CONTROL_REGISTER);
398                         outb(i_PatternPolarity,
399                                 devpriv->iobase +
400                                 APCI1500_Z8536_CONTROL_REGISTER);
401                         /* Selects the pattern transition register    */
402                         /* of port 2                                  */
403                         outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
404                                 devpriv->iobase +
405                                 APCI1500_Z8536_CONTROL_REGISTER);
406                         outb(i_PatternTransition,
407                                 devpriv->iobase +
408                                 APCI1500_Z8536_CONTROL_REGISTER);
409                         /* Selects the pattern Mask register    */
410                         /* of port 2                                  */
411
412                         outb(APCI1500_RW_PORT_B_PATTERN_MASK,
413                                 devpriv->iobase +
414                                 APCI1500_Z8536_CONTROL_REGISTER);
415                         outb(i_PatternMask,
416                                 devpriv->iobase +
417                                 APCI1500_Z8536_CONTROL_REGISTER);
418
419                         /* Selects the mode specification mask    */
420                         /* register of port 2                     */
421                         outb(APCI1500_RW_PORT_B_SPECIFICATION,
422                                 devpriv->iobase +
423                                 APCI1500_Z8536_CONTROL_REGISTER);
424                         i_RegValue =
425                                 inb(devpriv->iobase +
426                                 APCI1500_Z8536_CONTROL_REGISTER);
427                         /* Selects the mode specification mask    */
428                         /* register of port 2                     */
429                         outb(APCI1500_RW_PORT_B_SPECIFICATION,
430                                 devpriv->iobase +
431                                 APCI1500_Z8536_CONTROL_REGISTER);
432                         i_RegValue = (i_RegValue & 0xF9) | 4;
433                         outb(i_RegValue,
434                                 devpriv->iobase +
435                                 APCI1500_Z8536_CONTROL_REGISTER);
436
437                         i_Event2Status = 1;
438                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
439
440                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
441                                 devpriv->iobase +
442                                 APCI1500_Z8536_CONTROL_REGISTER);
443                         /* Enable Port B */
444
445                         outb(0xF4,
446                                 devpriv->iobase +
447                                 APCI1500_Z8536_CONTROL_REGISTER);
448                 } else {
449                         dev_warn(dev->class_dev,
450                                 "The choice for interrupt logic does not exist\n");
451                         return -EINVAL;
452                 }
453         }
454
455         return insn->n;
456 }
457
458 /*
459  * Allows or disallows a port event
460  *
461  * data[0] 0 = Start input event, 1 = Stop input event
462  * data[1] Number of port (1 or 2)
463  */
464 static int apci1500_di_write(struct comedi_device *dev,
465                              struct comedi_subdevice *s,
466                              struct comedi_insn *insn,
467                              unsigned int *data)
468 {
469         struct addi_private *devpriv = dev->private;
470         int i_Event1InterruptStatus = 0, i_Event2InterruptStatus =
471                 0, i_RegValue;
472
473         switch (data[0]) {
474         case START:
475                 /* Tests the port number */
476
477                 if (data[1] == 1 || data[1] == 2) {
478                         /* Test if port 1 selected */
479
480                         if (data[1] == 1) {
481                                 /* Test if event initialised */
482                                 if (i_Event1Status == 1) {
483                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
484                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
485                                         /* Disable Port A */
486                                         outb(0xF0,
487                                                 devpriv->iobase +
488                                                 APCI1500_Z8536_CONTROL_REGISTER);
489                                         /* Selects the command and status register of      */
490                                         /* port 1                                          */
491                                         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
492                                         /* Allows the pattern interrupt      */
493                                         outb(0xC0,
494                                                 devpriv->iobase +
495                                                 APCI1500_Z8536_CONTROL_REGISTER);
496                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
497                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
498                                         /* Enable Port A */
499                                         outb(0xF4,
500                                                 devpriv->iobase +
501                                                 APCI1500_Z8536_CONTROL_REGISTER);
502                                         i_Event1InterruptStatus = 1;
503                                         outb(APCI1500_RW_PORT_A_SPECIFICATION,
504                                                 devpriv->iobase +
505                                                 APCI1500_Z8536_CONTROL_REGISTER);
506                                         i_RegValue =
507                                                 inb(devpriv->iobase +
508                                                 APCI1500_Z8536_CONTROL_REGISTER);
509
510                                         /* Selects the master interrupt control register */
511                                         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
512                                         /* Authorizes the main interrupt on the board */
513                                         outb(0xD0,
514                                                 devpriv->iobase +
515                                                 APCI1500_Z8536_CONTROL_REGISTER);
516
517                                 } else {
518                                         dev_warn(dev->class_dev,
519                                                 "Event 1 not initialised\n");
520                                         return -EINVAL;
521                                 }
522                         }
523                         if (data[1] == 2) {
524
525                                 if (i_Event2Status == 1) {
526                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
527                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
528                                         /* Disable Port B */
529                                         outb(0x74,
530                                                 devpriv->iobase +
531                                                 APCI1500_Z8536_CONTROL_REGISTER);
532                                         /* Selects the command and status register of      */
533                                         /* port 2                                          */
534                                         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
535                                         /* Allows the pattern interrupt      */
536                                         outb(0xC0,
537                                                 devpriv->iobase +
538                                                 APCI1500_Z8536_CONTROL_REGISTER);
539                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
540                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
541                                         /* Enable Port B */
542                                         outb(0xF4,
543                                                 devpriv->iobase +
544                                                 APCI1500_Z8536_CONTROL_REGISTER);
545
546                                         /* Selects the master interrupt control register */
547                                         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
548                                         /* Authorizes the main interrupt on the board */
549                                         outb(0xD0,
550                                                 devpriv->iobase +
551                                                 APCI1500_Z8536_CONTROL_REGISTER);
552                                         i_Event2InterruptStatus = 1;
553                                 } else {
554                                         dev_warn(dev->class_dev,
555                                                 "Event 2 not initialised\n");
556                                         return -EINVAL;
557                                 }
558                         }
559                 } else {
560                         dev_warn(dev->class_dev,
561                                 "The port parameter is in error\n");
562                         return -EINVAL;
563                 }
564
565                 break;
566
567         case STOP:
568                 /* Tests the port number */
569
570                 if (data[1] == 1 || data[1] == 2) {
571                         /* Test if port 1 selected */
572
573                         if (data[1] == 1) {
574                                 /* Test if event initialised */
575                                 if (i_Event1Status == 1) {
576                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
577                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
578                                         /* Disable Port A */
579                                         outb(0xF0,
580                                                 devpriv->iobase +
581                                                 APCI1500_Z8536_CONTROL_REGISTER);
582                                         /* Selects the command and status register of      */
583                                         /* port 1                                          */
584                                         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
585                                         /* Inhibits the pattern interrupt      */
586                                         outb(0xE0,
587                                                 devpriv->iobase +
588                                                 APCI1500_Z8536_CONTROL_REGISTER);
589                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
590                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
591                                         /* Enable Port A */
592                                         outb(0xF4,
593                                                 devpriv->iobase +
594                                                 APCI1500_Z8536_CONTROL_REGISTER);
595                                         i_Event1InterruptStatus = 0;
596                                 } else {
597                                         dev_warn(dev->class_dev,
598                                                 "Event 1 not initialised\n");
599                                         return -EINVAL;
600                                 }
601                         }
602                         if (data[1] == 2) {
603                                 /* Test if event initialised */
604                                 if (i_Event2Status == 1) {
605                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
606                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
607                                         /* Disable Port B */
608                                         outb(0x74,
609                                                 devpriv->iobase +
610                                                 APCI1500_Z8536_CONTROL_REGISTER);
611                                         /* Selects the command and status register of      */
612                                         /* port 2                                         */
613                                         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
614                                         /* Inhibits the pattern interrupt      */
615                                         outb(0xE0,
616                                                 devpriv->iobase +
617                                                 APCI1500_Z8536_CONTROL_REGISTER);
618                                         /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
619                                         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
620                                         /* Enable Port B */
621                                         outb(0xF4,
622                                                 devpriv->iobase +
623                                                 APCI1500_Z8536_CONTROL_REGISTER);
624                                         i_Event2InterruptStatus = 0;
625                                 } else {
626
627                                         dev_warn(dev->class_dev,
628                                                 "Event 2 not initialised\n");
629                                         return -EINVAL;
630                                 }
631                         }
632
633                 } else {
634                         dev_warn(dev->class_dev,
635                                 "The port parameter is in error\n");
636                         return -EINVAL;
637                 }
638                 break;
639         default:
640                 dev_warn(dev->class_dev,
641                         "The option of START/STOP logic does not exist\n");
642                 return -EINVAL;
643         }
644
645         return insn->n;
646 }
647
648 /*
649  * Return the status of the digital input
650  */
651 static int apci1500_di_read(struct comedi_device *dev,
652                             struct comedi_subdevice *s,
653                             struct comedi_insn *insn,
654                             unsigned int *data)
655 {
656         struct addi_private *devpriv = dev->private;
657         int i_DummyRead = 0;
658
659         /* Software reset */
660         i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
661         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
662         i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
663         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
664         outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
665         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
666
667         /* Selects the master configuration control register */
668         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
669                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
670         outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
671
672         /* Selects the mode specification register of port A */
673         outb(APCI1500_RW_PORT_A_SPECIFICATION,
674                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
675         outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
676
677         /* Selects the data path polarity register of port A */
678         outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
679                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
680         /* High level of port A means 1 */
681         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
682
683         /* Selects the data direction register of port A */
684         outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
685                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
686         /* All bits used as inputs */
687         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
688         /* Selects the command and status register of port A */
689         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
690                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
691         /* Deletes IP and IUS */
692         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
693         /*  Selects the command and status register of port A */
694         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
695                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
696         /* Deactivates the interrupt management of port A:  */
697         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
698         /* Selects the handshake specification register of port A */
699         outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
700                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
701         /* Deletes the register */
702         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
703
704         /* Selects the mode specification register of port B */
705         outb(APCI1500_RW_PORT_B_SPECIFICATION,
706                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
707         outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
708         /* Selects the data path polarity register of port B */
709         outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
710                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
711         /* A high level of port B means 1 */
712         outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
713         /* Selects the data direction register of port B */
714         outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
715                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
716         /* All bits used as inputs */
717         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
718         /* Selects the command and status register of port B */
719         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
720                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
721         /* Deletes IP and IUS */
722         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
723         /* Selects the command and status register of port B */
724         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
725                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
726         /* Deactivates the interrupt management of port B:         */
727         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
728         /* Selects the handshake specification register of port B */
729         outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
730                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
731         /* Deletes the register */
732         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
733
734         /* Selects the data path polarity register of port C */
735         outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
736                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
737         /* High level of port C means 1 */
738         outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
739         /* Selects the data direction register of port C */
740         outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
741                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
742         /* All bits used as inputs except channel 1 */
743         outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
744         /* Selects the special IO register of port C */
745         outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
746                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
747         /* Deletes it */
748         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
749         /* Selects the command and status register of timer 1 */
750         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
751                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
752         /* Deletes IP and IUS */
753         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
754         /* Selects the command and status register of timer 1 */
755         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
756                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
757         /* Deactivates the interrupt management of timer 1         */
758         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
759         /* Selects the command and status register of timer 2 */
760         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
761                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
762         /* Deletes IP and IUS */
763         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
764         /* Selects the command and status register of timer 2 */
765         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
766                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
767         /* Deactivates Timer 2 interrupt management:               */
768         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
769         /* Selects the command and status register of timer 3 */
770         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
771                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
772         /* Deletes IP and IUS */
773         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
774         /* Selects the command and status register of Timer 3 */
775         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
776                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
777         /* Deactivates interrupt management of timer 3:            */
778         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
779         /* Selects the master interrupt control register */
780         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
781                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
782         /* Deletes all interrupts */
783         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
784         return insn->n;
785 }
786
787 static int apci1500_di_insn_bits(struct comedi_device *dev,
788                                  struct comedi_subdevice *s,
789                                  struct comedi_insn *insn,
790                                  unsigned int *data)
791 {
792         struct addi_private *devpriv = dev->private;
793
794         data[1] = inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP);
795
796         return insn->n;
797 }
798
799 /*
800  * Configures the digital output memory and the digital output error interrupt
801  *
802  * data[1] 1 = Enable the voltage error interrupt
803  *         2 = Disable the voltage error interrupt
804  */
805 static int apci1500_do_config(struct comedi_device *dev,
806                               struct comedi_subdevice *s,
807                               struct comedi_insn *insn,
808                               unsigned int *data)
809 {
810         struct addi_private *devpriv = dev->private;
811
812         devpriv->b_OutputMemoryStatus = data[0];
813         return insn->n;
814 }
815
816 /*
817  * Writes port value to the selected port
818  */
819 static int apci1500_do_write(struct comedi_device *dev,
820                              struct comedi_subdevice *s,
821                              struct comedi_insn *insn,
822                              unsigned int *data)
823 {
824         struct addi_private *devpriv = dev->private;
825         static unsigned int ui_Temp;
826         unsigned int ui_Temp1;
827         unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec);  /*  get the channel */
828
829         if (!devpriv->b_OutputMemoryStatus)
830                 ui_Temp = 0;
831
832         if (data[3] == 0) {
833                 if (data[1] == 0) {
834                         data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
835                         outw(data[0],
836                                 devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
837                 } else {
838                         if (data[1] == 1) {
839                                 switch (ui_NoOfChannel) {
840
841                                 case 2:
842                                         data[0] =
843                                                 (data[0] << (2 *
844                                                         data[2])) | ui_Temp;
845                                         break;
846
847                                 case 4:
848                                         data[0] =
849                                                 (data[0] << (4 *
850                                                         data[2])) | ui_Temp;
851                                         break;
852
853                                 case 8:
854                                         data[0] =
855                                                 (data[0] << (8 *
856                                                         data[2])) | ui_Temp;
857                                         break;
858
859                                 case 15:
860                                         data[0] = data[0] | ui_Temp;
861                                         break;
862
863                                 default:
864                                         dev_err(dev->class_dev,
865                                                 "chan spec wrong\n");
866                                         return -EINVAL; /*  "sorry channel spec wrong " */
867
868                                 }
869
870                                 outw(data[0],
871                                         devpriv->i_IobaseAddon +
872                                         APCI1500_DIGITAL_OP);
873                         } else {
874                                 dev_warn(dev->class_dev,
875                                         "Specified channel not supported\n");
876                                 return -EINVAL;
877                         }
878                 }
879         } else {
880                 if (data[3] == 1) {
881                         if (data[1] == 0) {
882                                 data[0] = ~data[0] & 0x1;
883                                 ui_Temp1 = 1;
884                                 ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
885                                 ui_Temp = ui_Temp | ui_Temp1;
886                                 data[0] =
887                                         (data[0] << ui_NoOfChannel) ^
888                                         0xffffffff;
889                                 data[0] = data[0] & ui_Temp;
890                                 outw(data[0],
891                                         devpriv->i_IobaseAddon +
892                                         APCI1500_DIGITAL_OP);
893                         } else {
894                                 if (data[1] == 1) {
895                                         switch (ui_NoOfChannel) {
896
897                                         case 2:
898                                                 data[0] = ~data[0] & 0x3;
899                                                 ui_Temp1 = 3;
900                                                 ui_Temp1 =
901                                                         ui_Temp1 << 2 * data[2];
902                                                 ui_Temp = ui_Temp | ui_Temp1;
903                                                 data[0] =
904                                                         ((data[0] << (2 *
905                                                                         data
906                                                                         [2])) ^
907                                                         0xffffffff) & ui_Temp;
908                                                 break;
909
910                                         case 4:
911                                                 data[0] = ~data[0] & 0xf;
912                                                 ui_Temp1 = 15;
913                                                 ui_Temp1 =
914                                                         ui_Temp1 << 4 * data[2];
915                                                 ui_Temp = ui_Temp | ui_Temp1;
916                                                 data[0] =
917                                                         ((data[0] << (4 *
918                                                                         data
919                                                                         [2])) ^
920                                                         0xffffffff) & ui_Temp;
921                                                 break;
922
923                                         case 8:
924                                                 data[0] = ~data[0] & 0xff;
925                                                 ui_Temp1 = 255;
926                                                 ui_Temp1 =
927                                                         ui_Temp1 << 8 * data[2];
928                                                 ui_Temp = ui_Temp | ui_Temp1;
929                                                 data[0] =
930                                                         ((data[0] << (8 *
931                                                                         data
932                                                                         [2])) ^
933                                                         0xffffffff) & ui_Temp;
934                                                 break;
935
936                                         case 15:
937                                                 break;
938
939                                         default:
940                                                 dev_err(dev->class_dev,
941                                                         "chan spec wrong\n");
942                                                 return -EINVAL; /*  "sorry channel spec wrong " */
943
944                                         }
945
946                                         outw(data[0],
947                                                 devpriv->i_IobaseAddon +
948                                                 APCI1500_DIGITAL_OP);
949                                 } else {
950                                         dev_warn(dev->class_dev,
951                                                 "Specified channel not supported\n");
952                                         return -EINVAL;
953                                 }
954                         }
955                 } else {
956                         dev_warn(dev->class_dev,
957                                 "Specified functionality does not exist\n");
958                         return -EINVAL;
959                 }
960         }
961         ui_Temp = data[0];
962         return insn->n;
963 }
964
965 /*
966  * Configures The Watchdog
967  *
968  * data[0] 0 = APCI1500_115_KHZ, 1 = APCI1500_3_6_KHZ, 2 = APCI1500_1_8_KHZ
969  * data[1] 0 = Counter1/Timer1, 1 =  Counter2/Timer2, 2 = Counter3/Watchdog
970  * data[2] 0 = Counter, 1 = Timer/Watchdog
971  * data[3] This parameter has two meanings. If the counter/timer is used as
972  *      a counter the limit value of the counter is given. If the counter/timer
973  *      is used as a timer, the divider factor for the output is given.
974  * data[4] 0 = APCI1500_CONTINUOUS, 1 = APCI1500_SINGLE
975  * data[5] 0 = Software Trigger, 1 = Hardware Trigger
976  * data[6] 0 = Software gate, 1 = Hardware gate
977  * data[7] 0 = Interrupt Disable, 1 = Interrupt Enable
978  */
979 static int apci1500_timer_config(struct comedi_device *dev,
980                                  struct comedi_subdevice *s,
981                                  struct comedi_insn *insn,
982                                  unsigned int *data)
983 {
984         struct addi_private *devpriv = dev->private;
985         int i_TimerCounterMode, i_MasterConfiguration;
986
987         devpriv->tsk_Current = current;
988
989         /* Selection of the input clock */
990         if (data[0] == 0 || data[0] == 1 || data[0] == 2) {
991                 outw(data[0], devpriv->i_IobaseAddon + APCI1500_CLK_SELECT);
992         } else {
993                 if (data[0] != 3) {
994                         dev_warn(dev->class_dev,
995                                 "The option for input clock selection does not exist\n");
996                         return -EINVAL;
997                 }
998         }
999         /* Select the counter/timer */
1000         switch (data[1]) {
1001         case COUNTER1:
1002                 /* selecting counter or timer */
1003                 switch (data[2]) {
1004                 case 0:
1005                         data[2] = APCI1500_COUNTER;
1006                         break;
1007                 case 1:
1008                         data[2] = APCI1500_TIMER;
1009                         break;
1010                 default:
1011                         dev_warn(dev->class_dev,
1012                                 "This choice is not a timer nor a counter\n");
1013                         return -EINVAL;
1014                 }
1015
1016                 /* Selecting  single or continuous mode */
1017                 switch (data[4]) {
1018                 case 0:
1019                         data[4] = APCI1500_CONTINUOUS;
1020                         break;
1021                 case 1:
1022                         data[4] = APCI1500_SINGLE;
1023                         break;
1024                 default:
1025                         dev_warn(dev->class_dev,
1026                                 "This option for single/continuous mode does not exist\n");
1027                         return -EINVAL;
1028                 }
1029
1030                 i_TimerCounterMode = data[2] | data[4] | 7;
1031                 /* Test the reload value */
1032
1033                 if ((data[3] >= 0) && (data[3] <= 65535)) {
1034                         if (data[7] == APCI1500_ENABLE
1035                                 || data[7] == APCI1500_DISABLE) {
1036
1037                                 /* Selects the mode register of timer/counter 1 */
1038                                 outb(APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
1039                                         devpriv->iobase +
1040                                         APCI1500_Z8536_CONTROL_REGISTER);
1041                                 /* Writes the new mode */
1042                                 outb(i_TimerCounterMode,
1043                                         devpriv->iobase +
1044                                         APCI1500_Z8536_CONTROL_REGISTER);
1045
1046                                 /* Selects the constant register of timer/counter 1 */
1047
1048                                 outb(APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
1049                                         devpriv->iobase +
1050                                         APCI1500_Z8536_CONTROL_REGISTER);
1051
1052                                 /* Writes the low value  */
1053
1054                                 outb(data[3],
1055                                         devpriv->iobase +
1056                                         APCI1500_Z8536_CONTROL_REGISTER);
1057
1058                                 /* Selects the constant register of timer/counter 1 */
1059
1060                                 outb(APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
1061                                         devpriv->iobase +
1062                                         APCI1500_Z8536_CONTROL_REGISTER);
1063
1064                                 /* Writes the high value  */
1065
1066                                 data[3] = data[3] >> 8;
1067                                 outb(data[3],
1068                                         devpriv->iobase +
1069                                         APCI1500_Z8536_CONTROL_REGISTER);
1070
1071                                 /* Selects the master configuration register */
1072
1073                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1074                                         devpriv->iobase +
1075                                         APCI1500_Z8536_CONTROL_REGISTER);
1076
1077                                 /* Reads the register */
1078
1079                                 i_MasterConfiguration =
1080                                         inb(devpriv->iobase +
1081                                         APCI1500_Z8536_CONTROL_REGISTER);
1082
1083                                 /* Enables timer/counter 1 and triggers timer/counter 1 */
1084
1085                                 i_MasterConfiguration =
1086                                         i_MasterConfiguration | 0x40;
1087
1088                                 /* Selects the master configuration register */
1089                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1090                                         devpriv->iobase +
1091                                         APCI1500_Z8536_CONTROL_REGISTER);
1092
1093                                 /* Writes the new configuration */
1094                                 outb(i_MasterConfiguration,
1095                                         devpriv->iobase +
1096                                         APCI1500_Z8536_CONTROL_REGISTER);
1097                                 /* Selects the commands register of     */
1098                                 /* timer/counter 1                      */
1099
1100                                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1101                                         devpriv->iobase +
1102                                         APCI1500_Z8536_CONTROL_REGISTER);
1103
1104                                 /* Disable timer/counter 1 */
1105
1106                                 outb(0x0,
1107                                         devpriv->iobase +
1108                                         APCI1500_Z8536_CONTROL_REGISTER);
1109                                 /* Selects the commands register of     */
1110                                 /* timer/counter 1                      */
1111                                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1112                                         devpriv->iobase +
1113                                         APCI1500_Z8536_CONTROL_REGISTER);
1114
1115                                 /* Trigger timer/counter 1 */
1116                                 outb(0x2,
1117                                         devpriv->iobase +
1118                                         APCI1500_Z8536_CONTROL_REGISTER);
1119                         } else {
1120                                 dev_warn(dev->class_dev,
1121                                         "Error in selection of interrupt enable or disable\n");
1122                                 return -EINVAL;
1123                         }
1124                 } else {
1125                         dev_warn(dev->class_dev,
1126                                 "Error in selection of reload value\n");
1127                         return -EINVAL;
1128                 }
1129                 i_TimerCounterWatchdogInterrupt = data[7];
1130                 i_TimerCounter1Init = 1;
1131                 break;
1132
1133         case COUNTER2:          /* selecting counter or timer */
1134                 switch (data[2]) {
1135                 case 0:
1136                         data[2] = APCI1500_COUNTER;
1137                         break;
1138                 case 1:
1139                         data[2] = APCI1500_TIMER;
1140                         break;
1141                 default:
1142                         dev_warn(dev->class_dev,
1143                                 "This choice is not a timer nor a counter\n");
1144                         return -EINVAL;
1145                 }
1146
1147                 /* Selecting  single or continuous mode */
1148                 switch (data[4]) {
1149                 case 0:
1150                         data[4] = APCI1500_CONTINUOUS;
1151                         break;
1152                 case 1:
1153                         data[4] = APCI1500_SINGLE;
1154                         break;
1155                 default:
1156                         dev_warn(dev->class_dev,
1157                                 "This option for single/continuous mode does not exist\n");
1158                         return -EINVAL;
1159                 }
1160
1161                 /* Selecting  software or hardware trigger */
1162                 switch (data[5]) {
1163                 case 0:
1164                         data[5] = APCI1500_SOFTWARE_TRIGGER;
1165                         break;
1166                 case 1:
1167                         data[5] = APCI1500_HARDWARE_TRIGGER;
1168                         break;
1169                 default:
1170                         dev_warn(dev->class_dev,
1171                                 "This choice for software or hardware trigger does not exist\n");
1172                         return -EINVAL;
1173                 }
1174
1175                 /* Selecting  software or hardware gate */
1176                 switch (data[6]) {
1177                 case 0:
1178                         data[6] = APCI1500_SOFTWARE_GATE;
1179                         break;
1180                 case 1:
1181                         data[6] = APCI1500_HARDWARE_GATE;
1182                         break;
1183                 default:
1184                         dev_warn(dev->class_dev,
1185                                 "This choice for software or hardware gate does not exist\n");
1186                         return -EINVAL;
1187                 }
1188
1189                 i_TimerCounterMode = data[2] | data[4] | data[5] | data[6] | 7;
1190
1191                 /* Test the reload value */
1192
1193                 if ((data[3] >= 0) && (data[3] <= 65535)) {
1194                         if (data[7] == APCI1500_ENABLE
1195                                 || data[7] == APCI1500_DISABLE) {
1196
1197                                 /* Selects the mode register of timer/counter 2 */
1198                                 outb(APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
1199                                         devpriv->iobase +
1200                                         APCI1500_Z8536_CONTROL_REGISTER);
1201                                 /* Writes the new mode */
1202                                 outb(i_TimerCounterMode,
1203                                         devpriv->iobase +
1204                                         APCI1500_Z8536_CONTROL_REGISTER);
1205
1206                                 /* Selects the constant register of timer/counter 2 */
1207
1208                                 outb(APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
1209                                         devpriv->iobase +
1210                                         APCI1500_Z8536_CONTROL_REGISTER);
1211
1212                                 /* Writes the low value  */
1213
1214                                 outb(data[3],
1215                                         devpriv->iobase +
1216                                         APCI1500_Z8536_CONTROL_REGISTER);
1217
1218                                 /* Selects the constant register of timer/counter 2 */
1219
1220                                 outb(APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
1221                                         devpriv->iobase +
1222                                         APCI1500_Z8536_CONTROL_REGISTER);
1223
1224                                 /* Writes the high value  */
1225
1226                                 data[3] = data[3] >> 8;
1227                                 outb(data[3],
1228                                         devpriv->iobase +
1229                                         APCI1500_Z8536_CONTROL_REGISTER);
1230
1231                                 /* Selects the master configuration register */
1232
1233                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1234                                         devpriv->iobase +
1235                                         APCI1500_Z8536_CONTROL_REGISTER);
1236
1237                                 /* Reads the register */
1238
1239                                 i_MasterConfiguration =
1240                                         inb(devpriv->iobase +
1241                                         APCI1500_Z8536_CONTROL_REGISTER);
1242
1243                                 /* Enables timer/counter 2 and triggers timer/counter 2 */
1244
1245                                 i_MasterConfiguration =
1246                                         i_MasterConfiguration | 0x20;
1247
1248                                 /* Selects the master configuration register */
1249                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1250                                         devpriv->iobase +
1251                                         APCI1500_Z8536_CONTROL_REGISTER);
1252
1253                                 /* Writes the new configuration */
1254                                 outb(i_MasterConfiguration,
1255                                         devpriv->iobase +
1256                                         APCI1500_Z8536_CONTROL_REGISTER);
1257                                 /* Selects the commands register of     */
1258                                 /* timer/counter 2                      */
1259
1260                                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1261                                         devpriv->iobase +
1262                                         APCI1500_Z8536_CONTROL_REGISTER);
1263
1264                                 /* Disable timer/counter 2 */
1265
1266                                 outb(0x0,
1267                                         devpriv->iobase +
1268                                         APCI1500_Z8536_CONTROL_REGISTER);
1269                                 /* Selects the commands register of     */
1270                                 /* timer/counter 2                      */
1271                                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1272                                         devpriv->iobase +
1273                                         APCI1500_Z8536_CONTROL_REGISTER);
1274
1275                                 /* Trigger timer/counter 1 */
1276                                 outb(0x2,
1277                                         devpriv->iobase +
1278                                         APCI1500_Z8536_CONTROL_REGISTER);
1279                         } else {
1280                                 dev_warn(dev->class_dev,
1281                                         "Error in selection of interrupt enable or disable\n");
1282                                 return -EINVAL;
1283                         }
1284                 } else {
1285                         dev_warn(dev->class_dev,
1286                                 "Error in selection of reload value\n");
1287                         return -EINVAL;
1288                 }
1289                 i_TimerCounterWatchdogInterrupt = data[7];
1290                 i_TimerCounter2Init = 1;
1291                 break;
1292
1293         case COUNTER3:          /* selecting counter or watchdog */
1294                 switch (data[2]) {
1295                 case 0:
1296                         data[2] = APCI1500_COUNTER;
1297                         break;
1298                 case 1:
1299                         data[2] = APCI1500_WATCHDOG;
1300                         break;
1301                 default:
1302                         dev_warn(dev->class_dev,
1303                                 "This choice is not a watchdog nor a counter\n");
1304                         return -EINVAL;
1305                 }
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                         dev_warn(dev->class_dev,
1317                                 "This option for single/continuous mode does not exist\n");
1318                         return -EINVAL;
1319                 }
1320
1321                 /* Selecting  software or hardware gate */
1322                 switch (data[6]) {
1323                 case 0:
1324                         data[6] = APCI1500_SOFTWARE_GATE;
1325                         break;
1326                 case 1:
1327                         data[6] = APCI1500_HARDWARE_GATE;
1328                         break;
1329                 default:
1330                         dev_warn(dev->class_dev,
1331                                 "This choice for software or hardware gate does not exist\n");
1332                         return -EINVAL;
1333                 }
1334
1335                 /* Test if used for watchdog */
1336
1337                 if (data[2] == APCI1500_WATCHDOG) {
1338                         /* - Enables the output line */
1339                         /* - Enables retrigger       */
1340                         /* - Pulses output           */
1341                         i_TimerCounterMode = data[2] | data[4] | 0x54;
1342                 } else {
1343                         i_TimerCounterMode = data[2] | data[4] | data[6] | 7;
1344                 }
1345                 /* Test the reload value */
1346
1347                 if ((data[3] >= 0) && (data[3] <= 65535)) {
1348                         if (data[7] == APCI1500_ENABLE
1349                                 || data[7] == APCI1500_DISABLE) {
1350
1351                                 /* Selects the mode register of watchdog/counter 3 */
1352                                 outb(APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
1353                                         devpriv->iobase +
1354                                         APCI1500_Z8536_CONTROL_REGISTER);
1355                                 /* Writes the new mode */
1356                                 outb(i_TimerCounterMode,
1357                                         devpriv->iobase +
1358                                         APCI1500_Z8536_CONTROL_REGISTER);
1359
1360                                 /* Selects the constant register of watchdog/counter 3 */
1361
1362                                 outb(APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
1363                                         devpriv->iobase +
1364                                         APCI1500_Z8536_CONTROL_REGISTER);
1365
1366                                 /* Writes the low value  */
1367
1368                                 outb(data[3],
1369                                         devpriv->iobase +
1370                                         APCI1500_Z8536_CONTROL_REGISTER);
1371
1372                                 /* Selects the constant register of watchdog/counter 3 */
1373
1374                                 outb(APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
1375                                         devpriv->iobase +
1376                                         APCI1500_Z8536_CONTROL_REGISTER);
1377
1378                                 /* Writes the high value  */
1379
1380                                 data[3] = data[3] >> 8;
1381                                 outb(data[3],
1382                                         devpriv->iobase +
1383                                         APCI1500_Z8536_CONTROL_REGISTER);
1384
1385                                 /* Selects the master configuration register */
1386
1387                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1388                                         devpriv->iobase +
1389                                         APCI1500_Z8536_CONTROL_REGISTER);
1390
1391                                 /* Reads the register */
1392
1393                                 i_MasterConfiguration =
1394                                         inb(devpriv->iobase +
1395                                         APCI1500_Z8536_CONTROL_REGISTER);
1396
1397                                 /* Enables watchdog/counter 3 and triggers watchdog/counter 3 */
1398
1399                                 i_MasterConfiguration =
1400                                         i_MasterConfiguration | 0x10;
1401
1402                                 /* Selects the master configuration register */
1403                                 outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
1404                                         devpriv->iobase +
1405                                         APCI1500_Z8536_CONTROL_REGISTER);
1406
1407                                 /* Writes the new configuration */
1408                                 outb(i_MasterConfiguration,
1409                                         devpriv->iobase +
1410                                         APCI1500_Z8536_CONTROL_REGISTER);
1411
1412                                 /* Test if COUNTER */
1413                                 if (data[2] == APCI1500_COUNTER) {
1414
1415                                         /* Selects the command register of   */
1416                                         /* watchdog/counter 3                */
1417                                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1418                                                 devpriv->iobase +
1419                                                 APCI1500_Z8536_CONTROL_REGISTER);
1420                                         /* Disable the  watchdog/counter 3 and starts it */
1421                                         outb(0x0,
1422                                                 devpriv->iobase +
1423                                                 APCI1500_Z8536_CONTROL_REGISTER);
1424
1425                                         /* Selects the command register of   */
1426                                         /* watchdog/counter 3                */
1427
1428                                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1429                                                 devpriv->iobase +
1430                                                 APCI1500_Z8536_CONTROL_REGISTER);
1431                                         /* Trigger the  watchdog/counter 3 and starts it */
1432                                         outb(0x2,
1433                                                 devpriv->iobase +
1434                                                 APCI1500_Z8536_CONTROL_REGISTER);
1435
1436                                 }
1437
1438                         } else {
1439
1440                                 dev_warn(dev->class_dev,
1441                                         "Error in selection of interrupt enable or disable\n");
1442                                 return -EINVAL;
1443                         }
1444                 } else {
1445                         dev_warn(dev->class_dev,
1446                                 "Error in selection of reload value\n");
1447                         return -EINVAL;
1448                 }
1449                 i_TimerCounterWatchdogInterrupt = data[7];
1450                 i_WatchdogCounter3Init = 1;
1451                 break;
1452
1453         default:
1454                 dev_warn(dev->class_dev,
1455                         "The specified counter/timer option does not exist\n");
1456                 return -EINVAL;
1457         }
1458         i_CounterLogic = data[2];
1459         return insn->n;
1460 }
1461
1462 /*
1463  * Start / Stop or trigger the timer counter or Watchdog
1464  *
1465  * data[0] 0 = Counter1/Timer1, 1 =  Counter2/Timer2, 2 = Counter3/Watchdog
1466  * data[1] 0 = Start, 1 = Stop, 2 = Trigger
1467  * data[2] 0 = Counter, 1 = Timer/Watchdog
1468  */
1469 static int apci1500_timer_write(struct comedi_device *dev,
1470                                 struct comedi_subdevice *s,
1471                                 struct comedi_insn *insn,
1472                                 unsigned int *data)
1473 {
1474         struct addi_private *devpriv = dev->private;
1475         int i_CommandAndStatusValue;
1476
1477         switch (data[0]) {
1478         case COUNTER1:
1479                 switch (data[1]) {
1480                 case START:
1481                         if (i_TimerCounter1Init == 1) {
1482                                 if (i_TimerCounterWatchdogInterrupt == 1)
1483                                         i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1484                                 else
1485                                         i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1486
1487                                 /* Starts timer/counter 1 */
1488                                 i_TimerCounter1Enabled = 1;
1489                                 /* Selects the commands and status register */
1490                                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1491                                         devpriv->iobase +
1492                                         APCI1500_Z8536_CONTROL_REGISTER);
1493                                 outb(i_CommandAndStatusValue,
1494                                         devpriv->iobase +
1495                                         APCI1500_Z8536_CONTROL_REGISTER);
1496                         } else {
1497                                 dev_warn(dev->class_dev,
1498                                         "Counter/Timer1 not configured\n");
1499                                 return -EINVAL;
1500                         }
1501                         break;
1502
1503                 case STOP:
1504
1505                         /* Stop timer/counter 1 */
1506
1507                         /* Selects the commands and status register */
1508                         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1509                                 devpriv->iobase +
1510                                 APCI1500_Z8536_CONTROL_REGISTER);
1511                         outb(0x00,
1512                                 devpriv->iobase +
1513                                 APCI1500_Z8536_CONTROL_REGISTER);
1514                         i_TimerCounter1Enabled = 0;
1515                         break;
1516
1517                 case TRIGGER:
1518                         if (i_TimerCounter1Init == 1) {
1519                                 if (i_TimerCounter1Enabled == 1) {
1520                                         /* Set Trigger and gate */
1521
1522                                         i_CommandAndStatusValue = 0x6;
1523                                 } else {
1524                                         /* Set Trigger */
1525
1526                                         i_CommandAndStatusValue = 0x2;
1527                                 }
1528
1529                                 /* Selects the commands and status register */
1530                                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1531                                         devpriv->iobase +
1532                                         APCI1500_Z8536_CONTROL_REGISTER);
1533                                 outb(i_CommandAndStatusValue,
1534                                         devpriv->iobase +
1535                                         APCI1500_Z8536_CONTROL_REGISTER);
1536                         } else {
1537                                 dev_warn(dev->class_dev,
1538                                         "Counter/Timer1 not configured\n");
1539                                 return -EINVAL;
1540                         }
1541                         break;
1542
1543                 default:
1544                         dev_warn(dev->class_dev,
1545                                 "The specified option for start/stop/trigger does not exist\n");
1546                         return -EINVAL;
1547                 }
1548                 break;
1549
1550         case COUNTER2:
1551                 switch (data[1]) {
1552                 case START:
1553                         if (i_TimerCounter2Init == 1) {
1554                                 if (i_TimerCounterWatchdogInterrupt == 1)
1555                                         i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1556                                 else
1557                                         i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1558
1559                                 /* Starts timer/counter 2 */
1560                                 i_TimerCounter2Enabled = 1;
1561                                 /* Selects the commands and status register */
1562                                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1563                                         devpriv->iobase +
1564                                         APCI1500_Z8536_CONTROL_REGISTER);
1565                                 outb(i_CommandAndStatusValue,
1566                                         devpriv->iobase +
1567                                         APCI1500_Z8536_CONTROL_REGISTER);
1568                         } else {
1569                                 dev_warn(dev->class_dev,
1570                                         "Counter/Timer2 not configured\n");
1571                                 return -EINVAL;
1572                         }
1573                         break;
1574
1575                 case STOP:
1576
1577                         /* Stop timer/counter 2 */
1578
1579                         /* Selects the commands and status register */
1580                         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1581                                 devpriv->iobase +
1582                                 APCI1500_Z8536_CONTROL_REGISTER);
1583                         outb(0x00,
1584                                 devpriv->iobase +
1585                                 APCI1500_Z8536_CONTROL_REGISTER);
1586                         i_TimerCounter2Enabled = 0;
1587                         break;
1588                 case TRIGGER:
1589                         if (i_TimerCounter2Init == 1) {
1590                                 if (i_TimerCounter2Enabled == 1) {
1591                                         /* Set Trigger and gate */
1592
1593                                         i_CommandAndStatusValue = 0x6;
1594                                 } else {
1595                                         /* Set Trigger */
1596
1597                                         i_CommandAndStatusValue = 0x2;
1598                                 }
1599
1600                                 /* Selects the commands and status register */
1601                                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1602                                         devpriv->iobase +
1603                                         APCI1500_Z8536_CONTROL_REGISTER);
1604                                 outb(i_CommandAndStatusValue,
1605                                         devpriv->iobase +
1606                                         APCI1500_Z8536_CONTROL_REGISTER);
1607                         } else {
1608                                 dev_warn(dev->class_dev,
1609                                         "Counter/Timer2 not configured\n");
1610                                 return -EINVAL;
1611                         }
1612                         break;
1613                 default:
1614                         dev_warn(dev->class_dev,
1615                                 "The specified option for start/stop/trigger does not exist\n");
1616                         return -EINVAL;
1617                 }
1618                 break;
1619         case COUNTER3:
1620                 switch (data[1]) {
1621                 case START:
1622                         if (i_WatchdogCounter3Init == 1) {
1623
1624                                 if (i_TimerCounterWatchdogInterrupt == 1)
1625                                         i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1626                                 else
1627                                         i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1628
1629                                 /* Starts Watchdog/counter 3 */
1630                                 i_WatchdogCounter3Enabled = 1;
1631                                 /* Selects the commands and status register */
1632                                 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1633                                         devpriv->iobase +
1634                                         APCI1500_Z8536_CONTROL_REGISTER);
1635                                 outb(i_CommandAndStatusValue,
1636                                         devpriv->iobase +
1637                                         APCI1500_Z8536_CONTROL_REGISTER);
1638
1639                         } else {
1640                                 dev_warn(dev->class_dev,
1641                                         "Watchdog/Counter3 not configured\n");
1642                                 return -EINVAL;
1643                         }
1644                         break;
1645
1646                 case STOP:
1647
1648                         /* Stop Watchdog/counter 3 */
1649
1650                         /* Selects the commands and status register */
1651                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1652                                 devpriv->iobase +
1653                                 APCI1500_Z8536_CONTROL_REGISTER);
1654                         outb(0x00,
1655                                 devpriv->iobase +
1656                                 APCI1500_Z8536_CONTROL_REGISTER);
1657                         i_WatchdogCounter3Enabled = 0;
1658                         break;
1659
1660                 case TRIGGER:
1661                         switch (data[2]) {
1662                         case 0: /* triggering counter 3 */
1663                                 if (i_WatchdogCounter3Init == 1) {
1664                                         if (i_WatchdogCounter3Enabled == 1) {
1665                                                 /* Set Trigger and gate */
1666
1667                                                 i_CommandAndStatusValue = 0x6;
1668                                         } else {
1669                                                 /* Set Trigger */
1670
1671                                                 i_CommandAndStatusValue = 0x2;
1672                                         }
1673
1674                                         /* Selects the commands and status register */
1675                                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1676                                                 devpriv->iobase +
1677                                                 APCI1500_Z8536_CONTROL_REGISTER);
1678                                         outb(i_CommandAndStatusValue,
1679                                                 devpriv->iobase +
1680                                                 APCI1500_Z8536_CONTROL_REGISTER);
1681                                 } else {
1682                                         dev_warn(dev->class_dev,
1683                                                 "Counter3 not configured\n");
1684                                         return -EINVAL;
1685                                 }
1686                                 break;
1687                         case 1:
1688                                 /* triggering Watchdog 3 */
1689                                 if (i_WatchdogCounter3Init == 1) {
1690
1691                                         /* Selects the commands and status register */
1692                                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1693                                                 devpriv->iobase +
1694                                                 APCI1500_Z8536_CONTROL_REGISTER);
1695                                         outb(0x6,
1696                                                 devpriv->iobase +
1697                                                 APCI1500_Z8536_CONTROL_REGISTER);
1698                                 } else {
1699                                         dev_warn(dev->class_dev,
1700                                                 "Watchdog 3 not configured\n");
1701                                         return -EINVAL;
1702                                 }
1703                                 break;
1704                         default:
1705                                 dev_warn(dev->class_dev,
1706                                         "Wrong choice of watchdog/counter3\n");
1707                                 return -EINVAL;
1708                         }
1709                         break;
1710                 default:
1711                         dev_warn(dev->class_dev,
1712                                 "The specified option for start/stop/trigger does not exist\n");
1713                         return -EINVAL;
1714                 }
1715                 break;
1716         default:
1717                 dev_warn(dev->class_dev,
1718                         "The specified choice for counter/watchdog/timer does not exist\n");
1719                 return -EINVAL;
1720         }
1721         return insn->n;
1722 }
1723
1724 /*
1725  * Read The Watchdog
1726  *
1727  * data[0] 0 = Counter1/Timer1, 1 =  Counter2/Timer2, 2 = Counter3/Watchdog
1728  */
1729 static int apci1500_timer_bits(struct comedi_device *dev,
1730                                struct comedi_subdevice *s,
1731                                struct comedi_insn *insn,
1732                                unsigned int *data)
1733 {
1734         struct addi_private *devpriv = dev->private;
1735         int i_CommandAndStatusValue;
1736
1737         switch (data[0]) {
1738         case COUNTER1:
1739                 /* Read counter/timer1 */
1740                 if (i_TimerCounter1Init == 1) {
1741                         if (i_TimerCounter1Enabled == 1) {
1742                                 /* Set RCC and gate */
1743
1744                                 i_CommandAndStatusValue = 0xC;
1745                         } else {
1746                                 /* Set RCC */
1747
1748                                 i_CommandAndStatusValue = 0x8;
1749                         }
1750
1751                         /* Selects the commands and status register */
1752                         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1753                                 devpriv->iobase +
1754                                 APCI1500_Z8536_CONTROL_REGISTER);
1755                         outb(i_CommandAndStatusValue,
1756                                 devpriv->iobase +
1757                                 APCI1500_Z8536_CONTROL_REGISTER);
1758
1759                         /* Selects the counter register (high) */
1760                         outb(APCI1500_R_CPT_TMR1_VALUE_HIGH,
1761                                 devpriv->iobase +
1762                                 APCI1500_Z8536_CONTROL_REGISTER);
1763                         data[0] =
1764                                 inb(devpriv->iobase +
1765                                 APCI1500_Z8536_CONTROL_REGISTER);
1766                         data[0] = data[0] << 8;
1767                         data[0] = data[0] & 0xff00;
1768                         outb(APCI1500_R_CPT_TMR1_VALUE_LOW,
1769                                 devpriv->iobase +
1770                                 APCI1500_Z8536_CONTROL_REGISTER);
1771                         data[0] =
1772                                 data[0] | inb(devpriv->iobase +
1773                                 APCI1500_Z8536_CONTROL_REGISTER);
1774                 } else {
1775                         dev_warn(dev->class_dev,
1776                                 "Timer/Counter1 not configured\n");
1777                         return -EINVAL;
1778                 }
1779                 break;
1780         case COUNTER2:
1781                 /* Read counter/timer2 */
1782                 if (i_TimerCounter2Init == 1) {
1783                         if (i_TimerCounter2Enabled == 1) {
1784                                 /* Set RCC and gate */
1785
1786                                 i_CommandAndStatusValue = 0xC;
1787                         } else {
1788                                 /* Set RCC */
1789
1790                                 i_CommandAndStatusValue = 0x8;
1791                         }
1792
1793                         /* Selects the commands and status register */
1794                         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1795                                 devpriv->iobase +
1796                                 APCI1500_Z8536_CONTROL_REGISTER);
1797                         outb(i_CommandAndStatusValue,
1798                                 devpriv->iobase +
1799                                 APCI1500_Z8536_CONTROL_REGISTER);
1800
1801                         /* Selects the counter register (high) */
1802                         outb(APCI1500_R_CPT_TMR2_VALUE_HIGH,
1803                                 devpriv->iobase +
1804                                 APCI1500_Z8536_CONTROL_REGISTER);
1805                         data[0] =
1806                                 inb(devpriv->iobase +
1807                                 APCI1500_Z8536_CONTROL_REGISTER);
1808                         data[0] = data[0] << 8;
1809                         data[0] = data[0] & 0xff00;
1810                         outb(APCI1500_R_CPT_TMR2_VALUE_LOW,
1811                                 devpriv->iobase +
1812                                 APCI1500_Z8536_CONTROL_REGISTER);
1813                         data[0] =
1814                                 data[0] | inb(devpriv->iobase +
1815                                 APCI1500_Z8536_CONTROL_REGISTER);
1816                 } else {
1817                         dev_warn(dev->class_dev,
1818                                 "Timer/Counter2 not configured\n");
1819                         return -EINVAL;
1820                 }
1821                 break;
1822         case COUNTER3:
1823                 /* Read counter/watchdog2 */
1824                 if (i_WatchdogCounter3Init == 1) {
1825                         if (i_WatchdogCounter3Enabled == 1) {
1826                                 /* Set RCC and gate */
1827
1828                                 i_CommandAndStatusValue = 0xC;
1829                         } else {
1830                                 /* Set RCC */
1831
1832                                 i_CommandAndStatusValue = 0x8;
1833                         }
1834
1835                         /* Selects the commands and status register */
1836                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1837                                 devpriv->iobase +
1838                                 APCI1500_Z8536_CONTROL_REGISTER);
1839                         outb(i_CommandAndStatusValue,
1840                                 devpriv->iobase +
1841                                 APCI1500_Z8536_CONTROL_REGISTER);
1842
1843                         /* Selects the counter register (high) */
1844                         outb(APCI1500_R_CPT_TMR3_VALUE_HIGH,
1845                                 devpriv->iobase +
1846                                 APCI1500_Z8536_CONTROL_REGISTER);
1847                         data[0] =
1848                                 inb(devpriv->iobase +
1849                                 APCI1500_Z8536_CONTROL_REGISTER);
1850                         data[0] = data[0] << 8;
1851                         data[0] = data[0] & 0xff00;
1852                         outb(APCI1500_R_CPT_TMR3_VALUE_LOW,
1853                                 devpriv->iobase +
1854                                 APCI1500_Z8536_CONTROL_REGISTER);
1855                         data[0] =
1856                                 data[0] | inb(devpriv->iobase +
1857                                 APCI1500_Z8536_CONTROL_REGISTER);
1858                 } else {
1859                         dev_warn(dev->class_dev,
1860                                 "WatchdogCounter3 not configured\n");
1861                         return -EINVAL;
1862                 }
1863                 break;
1864         default:
1865                 dev_warn(dev->class_dev,
1866                         "The choice of timer/counter/watchdog does not exist\n");
1867                 return -EINVAL;
1868         }
1869
1870         return insn->n;
1871 }
1872
1873 /*
1874  * Read the interrupt mask
1875  *
1876  * data[0] The interrupt mask value
1877  * data[1] Channel Number
1878  */
1879 static int apci1500_timer_read(struct comedi_device *dev,
1880                                struct comedi_subdevice *s,
1881                                struct comedi_insn *insn,
1882                                unsigned int *data)
1883 {
1884         data[0] = i_InterruptMask;
1885         data[1] = i_InputChannel;
1886         i_InterruptMask = 0;
1887         return insn->n;
1888 }
1889
1890 /*
1891  * Configures the interrupt registers
1892  */
1893 static int apci1500_do_bits(struct comedi_device *dev,
1894                             struct comedi_subdevice *s,
1895                             struct comedi_insn *insn,
1896                             unsigned int *data)
1897 {
1898         struct addi_private *devpriv = dev->private;
1899         unsigned int ui_Status;
1900         int i_RegValue;
1901         int i_Constant;
1902
1903         devpriv->tsk_Current = current;
1904         outl(0x0, devpriv->i_IobaseAmcc + 0x38);
1905         if (data[0] == 1) {
1906                 i_Constant = 0xC0;
1907         } else {
1908                 if (data[0] == 0) {
1909                         i_Constant = 0x00;
1910                 } else {
1911                         dev_warn(dev->class_dev,
1912                                 "The parameter passed to driver is in error for enabling the voltage interrupt\n");
1913                         return -EINVAL;
1914                 }
1915         }
1916
1917         /* Selects the mode specification register of port B */
1918         outb(APCI1500_RW_PORT_B_SPECIFICATION,
1919                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1920         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1921         outb(APCI1500_RW_PORT_B_SPECIFICATION,
1922                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1923         /* Writes the new configuration (APCI1500_OR) */
1924         i_RegValue = (i_RegValue & 0xF9) | APCI1500_OR;
1925
1926         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1927         /* Selects the command and status register of port B */
1928         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
1929                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1930         /* Authorises the interrupt on the board */
1931         outb(0xC0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1932         /* Selects the pattern polarity register of port B */
1933         outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
1934                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1935         outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1936         /* Selects the pattern transition register of port B */
1937         outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
1938                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1939         outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1940         /* Selects the pattern mask register of port B */
1941         outb(APCI1500_RW_PORT_B_PATTERN_MASK,
1942                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1943         outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1944
1945         /* Selects the command and status register of port A */
1946         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
1947                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1948         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1949         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
1950                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1951         /* Deletes the interrupt of port A */
1952
1953         i_RegValue = (i_RegValue & 0x0F) | 0x20;
1954         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1955         /* Selects the command and status register of port  B */
1956         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
1957                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1958         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1959         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
1960                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1961         /* Deletes the interrupt of port B */
1962
1963         i_RegValue = (i_RegValue & 0x0F) | 0x20;
1964         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1965
1966         /* Selects the command and status register of timer 1 */
1967         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1968                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1969         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1970         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
1971                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1972         /* Deletes the interrupt of timer 1 */
1973
1974         i_RegValue = (i_RegValue & 0x0F) | 0x20;
1975         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1976
1977         /* Selects the command and status register of timer 2 */
1978         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1979                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1980         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1981         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
1982                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1983         /* Deletes the interrupt of timer 2 */
1984
1985         i_RegValue = (i_RegValue & 0x0F) | 0x20;
1986         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1987
1988         /* Selects the command and status register of timer 3 */
1989         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1990                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1991         i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1992         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
1993                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1994         /* Deletes the interrupt of timer 3 */
1995
1996         i_RegValue = (i_RegValue & 0x0F) | 0x20;
1997         outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
1998
1999         /* Selects the master interrupt control register */
2000         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2001                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2002         /* Authorizes the main interrupt on the board */
2003         outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2004
2005         /* Enables the PCI interrupt */
2006         outl(0x3000, devpriv->i_IobaseAmcc + 0x38);
2007         ui_Status = inl(devpriv->i_IobaseAmcc + 0x10);
2008         ui_Status = inl(devpriv->i_IobaseAmcc + 0x38);
2009         outl(0x23000, devpriv->i_IobaseAmcc + 0x38);
2010
2011         return insn->n;
2012 }
2013
2014 static void apci1500_interrupt(int irq, void *d)
2015 {
2016
2017         struct comedi_device *dev = d;
2018         struct addi_private *devpriv = dev->private;
2019         unsigned int ui_InterruptStatus = 0;
2020         int i_RegValue = 0;
2021
2022         /* Clear the interrupt mask */
2023         i_InterruptMask = 0;
2024
2025         /* Read the board interrupt status */
2026         ui_InterruptStatus = inl(devpriv->i_IobaseAmcc + 0x38);
2027
2028         /* Test if board generated a interrupt */
2029         if ((ui_InterruptStatus & 0x800000) == 0x800000) {
2030                 /* Disable all Interrupt */
2031                 /* Selects the master interrupt control register */
2032                 /* Disables  the main interrupt on the board */
2033                 /* Selects the command and status register of port A */
2034                 outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2035                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2036                 i_RegValue =
2037                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2038                 if ((i_RegValue & 0x60) == 0x60) {
2039                         /* Selects the command and status register of port A */
2040                         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2041                                 devpriv->iobase +
2042                                 APCI1500_Z8536_CONTROL_REGISTER);
2043                         /* Deletes the interrupt of port A */
2044                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2045                         outb(i_RegValue,
2046                                 devpriv->iobase +
2047                                 APCI1500_Z8536_CONTROL_REGISTER);
2048                         i_InterruptMask = i_InterruptMask | 1;
2049                         if (i_Logic == APCI1500_OR_PRIORITY) {
2050                                 outb(APCI1500_RW_PORT_A_SPECIFICATION,
2051                                         devpriv->iobase +
2052                                         APCI1500_Z8536_CONTROL_REGISTER);
2053                                 i_RegValue =
2054                                         inb(devpriv->iobase +
2055                                         APCI1500_Z8536_CONTROL_REGISTER);
2056
2057                                 /* Selects the interrupt vector register of port A */
2058                                 outb(APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
2059                                         devpriv->iobase +
2060                                         APCI1500_Z8536_CONTROL_REGISTER);
2061                                 i_RegValue =
2062                                         inb(devpriv->iobase +
2063                                         APCI1500_Z8536_CONTROL_REGISTER);
2064
2065                                 i_InputChannel = 1 + (i_RegValue >> 1);
2066
2067                         } else {
2068                                 i_InputChannel = 0;
2069                         }
2070                 }
2071
2072                 /* Selects the command and status register of port B */
2073                 outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2074                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2075                 i_RegValue =
2076                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2077                 if ((i_RegValue & 0x60) == 0x60) {
2078                         /* Selects the command and status register of port B */
2079                         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2080                                 devpriv->iobase +
2081                                 APCI1500_Z8536_CONTROL_REGISTER);
2082                         /* Deletes the interrupt of port B */
2083                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2084                         outb(i_RegValue,
2085                                 devpriv->iobase +
2086                                 APCI1500_Z8536_CONTROL_REGISTER);
2087                         /* Reads port B */
2088                         i_RegValue =
2089                                 inb((unsigned int) devpriv->iobase +
2090                                 APCI1500_Z8536_PORT_B);
2091
2092                         i_RegValue = i_RegValue & 0xC0;
2093                         /* Tests if this is an external error */
2094
2095                         if (i_RegValue) {
2096                                 /* Disable the interrupt */
2097                                 /* Selects the command and status register of port B */
2098                                 outl(0x0, devpriv->i_IobaseAmcc + 0x38);
2099
2100                                 if (i_RegValue & 0x80) {
2101                                         i_InterruptMask =
2102                                                 i_InterruptMask | 0x40;
2103                                 }
2104
2105                                 if (i_RegValue & 0x40) {
2106                                         i_InterruptMask =
2107                                                 i_InterruptMask | 0x80;
2108                                 }
2109                         } else {
2110                                 i_InterruptMask = i_InterruptMask | 2;
2111                         }
2112                 }
2113
2114                 /* Selects the command and status register of timer 1 */
2115                 outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2116                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2117                 i_RegValue =
2118                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2119                 if ((i_RegValue & 0x60) == 0x60) {
2120                         /* Selects the command and status register of timer 1 */
2121                         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2122                                 devpriv->iobase +
2123                                 APCI1500_Z8536_CONTROL_REGISTER);
2124                         /* Deletes the interrupt of timer 1 */
2125                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2126                         outb(i_RegValue,
2127                                 devpriv->iobase +
2128                                 APCI1500_Z8536_CONTROL_REGISTER);
2129                         i_InterruptMask = i_InterruptMask | 4;
2130                 }
2131                 /* Selects the command and status register of timer 2 */
2132                 outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2133                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2134                 i_RegValue =
2135                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2136                 if ((i_RegValue & 0x60) == 0x60) {
2137                         /* Selects the command and status register of timer 2 */
2138                         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2139                                 devpriv->iobase +
2140                                 APCI1500_Z8536_CONTROL_REGISTER);
2141                         /* Deletes the interrupt of timer 2 */
2142                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2143                         outb(i_RegValue,
2144                                 devpriv->iobase +
2145                                 APCI1500_Z8536_CONTROL_REGISTER);
2146                         i_InterruptMask = i_InterruptMask | 8;
2147                 }
2148
2149                 /* Selects the command and status register of timer 3 */
2150                 outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2151                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2152                 i_RegValue =
2153                         inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2154                 if ((i_RegValue & 0x60) == 0x60) {
2155                         /* Selects the command and status register of timer 3 */
2156                         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2157                                 devpriv->iobase +
2158                                 APCI1500_Z8536_CONTROL_REGISTER);
2159                         /* Deletes the interrupt of timer 3 */
2160                         i_RegValue = (i_RegValue & 0x0F) | 0x20;
2161                         outb(i_RegValue,
2162                                 devpriv->iobase +
2163                                 APCI1500_Z8536_CONTROL_REGISTER);
2164                         if (i_CounterLogic == APCI1500_COUNTER)
2165                                 i_InterruptMask = i_InterruptMask | 0x10;
2166                         else
2167                                 i_InterruptMask = i_InterruptMask | 0x20;
2168                 }
2169
2170                 send_sig(SIGIO, devpriv->tsk_Current, 0);       /*  send signal to the sample */
2171                 /* Enable all Interrupts */
2172
2173                 /* Selects the master interrupt control register */
2174                 outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2175                         devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2176                 /* Authorizes the main interrupt on the board */
2177                 outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2178         } else {
2179                 dev_warn(dev->class_dev,
2180                         "Interrupt from unknown source\n");
2181
2182         }
2183 }
2184
2185 static int apci1500_reset(struct comedi_device *dev)
2186 {
2187         struct addi_private *devpriv = dev->private;
2188         int i_DummyRead = 0;
2189
2190         i_TimerCounter1Init = 0;
2191         i_TimerCounter2Init = 0;
2192         i_WatchdogCounter3Init = 0;
2193         i_Event1Status = 0;
2194         i_Event2Status = 0;
2195         i_TimerCounterWatchdogInterrupt = 0;
2196         i_Logic = 0;
2197         i_CounterLogic = 0;
2198         i_InterruptMask = 0;
2199         i_InputChannel = 0;
2200         i_TimerCounter1Enabled = 0;
2201         i_TimerCounter2Enabled = 0;
2202         i_WatchdogCounter3Enabled = 0;
2203
2204         /* Software reset */
2205         i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2206         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2207         i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2208         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2209         outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2210         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2211
2212         /* Selects the master configuration control register */
2213         outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
2214                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2215         outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2216
2217         /* Selects the mode specification register of port A */
2218         outb(APCI1500_RW_PORT_A_SPECIFICATION,
2219                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2220         outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2221
2222         /* Selects the data path polarity register of port A */
2223         outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
2224                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2225         /* High level of port A means 1 */
2226         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2227
2228         /* Selects the data direction register of port A */
2229         outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
2230                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2231         /* All bits used as inputs */
2232         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2233         /* Selects the command and status register of port A */
2234         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2235                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2236         /* Deletes IP and IUS */
2237         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2238         /*  Selects the command and status register of port A */
2239         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2240                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2241         /* Deactivates the interrupt management of port A:  */
2242         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2243         /* Selects the handshake specification register of port A */
2244         outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
2245                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2246         /* Deletes the register */
2247         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2248
2249         /* Selects the mode specification register of port B */
2250         outb(APCI1500_RW_PORT_B_SPECIFICATION,
2251                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2252         outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2253         /* Selects the data path polarity register of port B */
2254         outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
2255                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2256         /* A high level of port B means 1 */
2257         outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2258         /* Selects the data direction register of port B */
2259         outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
2260                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2261         /* All bits used as inputs */
2262         outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2263         /* Selects the command and status register of port B */
2264         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2265                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2266         /* Deletes IP and IUS */
2267         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2268         /* Selects the command and status register of port B */
2269         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2270                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2271         /* Deactivates the interrupt management of port B:         */
2272         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2273         /* Selects the handshake specification register of port B */
2274         outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
2275                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2276         /* Deletes the register */
2277         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2278
2279         /* Selects the data path polarity register of port C */
2280         outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
2281                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2282         /* High level of port C means 1 */
2283         outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2284         /* Selects the data direction register of port C */
2285         outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
2286                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2287         /* All bits used as inputs except channel 1 */
2288         outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2289         /* Selects the special IO register of port C */
2290         outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
2291                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2292         /* Deletes it */
2293         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2294         /* Selects the command and status register of timer 1 */
2295         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2296                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2297         /* Deletes IP and IUS */
2298         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2299         /* Selects the command and status register of timer 1 */
2300         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2301                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2302         /* Deactivates the interrupt management of timer 1         */
2303         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2304         /* Selects the command and status register of timer 2 */
2305         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2306                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2307         /* Deletes IP and IUS */
2308         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2309         /* Selects the command and status register of timer 2 */
2310         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2311                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2312         /* Deactivates Timer 2 interrupt management:               */
2313         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2314         /* Selects the command and status register of timer 3 */
2315         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2316                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2317         /* Deletes IP and IUS */
2318         outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2319         /* Selects the command and status register of Timer 3 */
2320         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2321                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2322         /* Deactivates interrupt management of timer 3:            */
2323         outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2324         /* Selects the master interrupt control register */
2325         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2326                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2327         /* Deletes all interrupts */
2328         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2329         /* reset all the digital outputs */
2330         outw(0x0, devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
2331         /* Disable the board interrupt */
2332         /* Selects the master interrupt control register */
2333         outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
2334                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2335         /* Deactivates all interrupts */
2336         outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2337         /* Selects the command and status register of port A */
2338         outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
2339                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2340         /* Deactivates all interrupts */
2341         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2342         /* Selects the command and status register of port B */
2343         outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
2344                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2345         /* Deactivates all interrupts */
2346         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2347         /* Selects the command and status register of timer 1 */
2348         outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
2349                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2350         /* Deactivates all interrupts */
2351         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2352         /* Selects the command and status register of timer 2 */
2353         outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
2354                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2355         /* Deactivates all interrupts */
2356         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2357         /* Selects the command and status register of timer 3*/
2358         outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
2359                 devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2360         /* Deactivates all interrupts */
2361         outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
2362         return 0;
2363 }