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