2 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
7 * Tel: +19(0)7223/9493-0
8 * Fax: +49(0)7223/9493-92
9 * http://www.addi-data.com
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
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
24 /* Card Specific information */
25 #define APCI1500_ADDRESS_RANGE 4
27 /* DIGITAL INPUT-OUTPUT DEFINE */
29 #define APCI1500_DIGITAL_OP 2
30 #define APCI1500_DIGITAL_IP 0
31 #define APCI1500_AND 2
33 #define APCI1500_OR_PRIORITY 6
34 #define APCI1500_CLK_SELECT 0
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
54 * Z8536 CIO Internal Address
57 APCI1500_RW_MASTER_INTERRUPT_CONTROL,
58 APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
59 APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
60 APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
61 APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
62 APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
63 APCI1500_RW_PORT_C_DATA_DIRECTION,
64 APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
66 APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
67 APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
68 APCI1500_RW_CPT_TMR1_CMD_STATUS,
69 APCI1500_RW_CPT_TMR2_CMD_STATUS,
70 APCI1500_RW_CPT_TMR3_CMD_STATUS,
71 APCI1500_RW_PORT_A_DATA,
72 APCI1500_RW_PORT_B_DATA,
73 APCI1500_RW_PORT_C_DATA,
75 APCI1500_R_CPT_TMR1_VALUE_HIGH,
76 APCI1500_R_CPT_TMR1_VALUE_LOW,
77 APCI1500_R_CPT_TMR2_VALUE_HIGH,
78 APCI1500_R_CPT_TMR2_VALUE_LOW,
79 APCI1500_R_CPT_TMR3_VALUE_HIGH,
80 APCI1500_R_CPT_TMR3_VALUE_LOW,
81 APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
82 APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
83 APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
84 APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
85 APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
86 APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
87 APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
88 APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
89 APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
90 APCI1500_R_CURRENT_VECTOR,
92 APCI1500_RW_PORT_A_SPECIFICATION,
93 APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
94 APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
95 APCI1500_RW_PORT_A_DATA_DIRECTION,
96 APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
97 APCI1500_RW_PORT_A_PATTERN_POLARITY,
98 APCI1500_RW_PORT_A_PATTERN_TRANSITION,
99 APCI1500_RW_PORT_A_PATTERN_MASK,
101 APCI1500_RW_PORT_B_SPECIFICATION,
102 APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
103 APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
104 APCI1500_RW_PORT_B_DATA_DIRECTION,
105 APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
106 APCI1500_RW_PORT_B_PATTERN_POLARITY,
107 APCI1500_RW_PORT_B_PATTERN_TRANSITION,
108 APCI1500_RW_PORT_B_PATTERN_MASK
111 static int i_TimerCounter1Init;
112 static int i_TimerCounter2Init;
113 static int i_WatchdogCounter3Init;
114 static int i_Event1Status, i_Event2Status;
115 static int i_TimerCounterWatchdogInterrupt;
116 static int i_Logic, i_CounterLogic;
117 static int i_InterruptMask;
118 static int i_InputChannel;
119 static int i_TimerCounter1Enabled, i_TimerCounter2Enabled,
120 i_WatchdogCounter3Enabled;
122 static unsigned int z8536_read(struct comedi_device *dev, unsigned int reg)
124 struct apci1500_private *devpriv = dev->private;
128 spin_lock_irqsave(&dev->spinlock, flags);
129 outb(reg, devpriv->iobase + APCI1500_Z8536_CTRL_REG);
130 val = inb(devpriv->iobase + APCI1500_Z8536_CTRL_REG);
131 spin_unlock_irqrestore(&dev->spinlock, flags);
136 static void z8536_write(struct comedi_device *dev,
137 unsigned int val, unsigned int reg)
139 struct apci1500_private *devpriv = dev->private;
142 spin_lock_irqsave(&dev->spinlock, flags);
143 outb(reg, devpriv->iobase + APCI1500_Z8536_CTRL_REG);
144 outb(val, devpriv->iobase + APCI1500_Z8536_CTRL_REG);
145 spin_unlock_irqrestore(&dev->spinlock, flags);
148 static void z8536_reset(struct comedi_device *dev)
150 struct apci1500_private *devpriv = dev->private;
154 * Even if the state of the Z8536 is not known, the following
155 * sequence will reset it and put it in State 0.
157 spin_lock_irqsave(&dev->spinlock, flags);
158 inb(devpriv->iobase + APCI1500_Z8536_CTRL_REG);
159 outb(0, devpriv->iobase + APCI1500_Z8536_CTRL_REG);
160 inb(devpriv->iobase + APCI1500_Z8536_CTRL_REG);
161 outb(0, devpriv->iobase + APCI1500_Z8536_CTRL_REG);
162 outb(1, devpriv->iobase + APCI1500_Z8536_CTRL_REG);
163 outb(0, devpriv->iobase + APCI1500_Z8536_CTRL_REG);
164 spin_unlock_irqrestore(&dev->spinlock, flags);
166 z8536_write(dev, 0xf4, APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
168 z8536_write(dev, 0x10, APCI1500_RW_PORT_A_SPECIFICATION);
169 /* High level of port A means 1 */
170 z8536_write(dev, 0xff, APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY);
171 /* All bits used as inputs */
172 z8536_write(dev, 0xff, APCI1500_RW_PORT_A_DATA_DIRECTION);
173 /* Deletes IP and IUS */
174 z8536_write(dev, 0x20, APCI1500_RW_PORT_A_COMMAND_AND_STATUS);
175 /* Deactivates the interrupt management of port A */
176 z8536_write(dev, 0xe0, APCI1500_RW_PORT_A_COMMAND_AND_STATUS);
177 /* Deletes the register */
178 z8536_write(dev, 0x00, APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION);
180 z8536_write(dev, 0x10, APCI1500_RW_PORT_B_SPECIFICATION);
181 /* A high level of port B means 1 */
182 z8536_write(dev, 0x7f, APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY);
183 /* All bits used as inputs */
184 z8536_write(dev, 0xff, APCI1500_RW_PORT_B_DATA_DIRECTION);
185 /* Deletes IP and IUS */
186 z8536_write(dev, 0x20, APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
187 /* Deactivates the interrupt management of port B */
188 z8536_write(dev, 0xe0, APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
189 /* Deletes the register */
190 z8536_write(dev, 0x00, APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION);
192 /* High level of port C means 1 */
193 z8536_write(dev, 0x09, APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY);
194 /* All bits used as inputs except channel 1 */
195 z8536_write(dev, 0x0e, APCI1500_RW_PORT_C_DATA_DIRECTION);
197 z8536_write(dev, 0x00, APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL);
199 /* Deletes IP and IUS */
200 z8536_write(dev, 0x20, APCI1500_RW_CPT_TMR1_CMD_STATUS);
201 /* Deactivates the interrupt management of timer 1 */
202 z8536_write(dev, 0xe0, APCI1500_RW_CPT_TMR1_CMD_STATUS);
204 /* Deletes IP and IUS */
205 z8536_write(dev, 0x20, APCI1500_RW_CPT_TMR2_CMD_STATUS);
206 /* Deactivates Timer 2 interrupt management */
207 z8536_write(dev, 0xe0, APCI1500_RW_CPT_TMR2_CMD_STATUS);
209 /* Deletes IP and IUS */
210 z8536_write(dev, 0x20, APCI1500_RW_CPT_TMR3_CMD_STATUS);
211 /* Deactivates interrupt management of timer 3 */
212 z8536_write(dev, 0xe0, APCI1500_RW_CPT_TMR3_CMD_STATUS);
214 /* Deletes all interrupts */
215 z8536_write(dev, 0x00, APCI1500_RW_MASTER_INTERRUPT_CONTROL);
219 * An event can be generated for each port. The first event is related to the
220 * first 8 channels (port 1) and the second to the following 6 channels (port 2)
221 * An interrupt is generated when one or both events have occurred.
223 * data[0] Number of the input port on which the event will take place (1 or 2)
224 * data[1] The event logic for port 1 has three possibilities:
225 * APCI1500_AND This logic links the inputs with an AND logic.
226 * APCI1500_OR This logic links the inputs with a OR logic.
227 * APCI1500_OR_PRIORITY This logic links the inputs with a priority OR
228 * logic. Input 1 has the highest priority level
229 * and input 8 the smallest.
230 * For the second port the user has 1 possibility:
231 * APCI1500_OR This logic links the inputs with a polarity OR logic
232 * data[2] These 8-character word for port1 and 6-character word for port 2
233 * give the mask of the event. Each place gives the state of the input
234 * channels and can have one of these six characters
235 * 0 This input must be on 0
236 * 1 This input must be on 1
237 * 2 This input reacts to a falling edge
238 * 3 This input reacts to a rising edge
239 * 4 This input reacts to both edges
240 * 5 This input is not used for event
242 static int apci1500_di_config(struct comedi_device *dev,
243 struct comedi_subdevice *s,
244 struct comedi_insn *insn,
247 int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0;
248 int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0;
249 int i_PatternTransitionCount = 0, i_RegValue;
252 /* Disables the main interrupt on the board */
253 z8536_write(dev, 0x00, APCI1500_RW_MASTER_INTERRUPT_CONTROL);
261 dev_warn(dev->class_dev,
262 "The specified port event does not exist\n");
268 data[1] = APCI1500_AND;
271 data[1] = APCI1500_OR;
274 data[1] = APCI1500_OR_PRIORITY;
277 dev_warn(dev->class_dev,
278 "The specified interrupt logic does not exist\n");
283 for (i_Count = i_MaxChannel, i = 0; i_Count > 0; i_Count--, i++) {
284 i_EventMask = data[2 + i];
285 switch (i_EventMask) {
288 i_PatternMask | (1 << (i_MaxChannel - i_Count));
292 i_PatternMask | (1 << (i_MaxChannel - i_Count));
294 i_PatternPolarity | (1 << (i_MaxChannel -
299 i_PatternMask | (1 << (i_MaxChannel - i_Count));
300 i_PatternTransition =
301 i_PatternTransition | (1 << (i_MaxChannel -
306 i_PatternMask | (1 << (i_MaxChannel - i_Count));
308 i_PatternPolarity | (1 << (i_MaxChannel -
310 i_PatternTransition =
311 i_PatternTransition | (1 << (i_MaxChannel -
315 i_PatternTransition =
316 i_PatternTransition | (1 << (i_MaxChannel -
322 dev_warn(dev->class_dev,
323 "The option indicated in the event mask does not exist\n");
329 /* Test the interrupt logic */
331 if (data[1] == APCI1500_AND ||
332 data[1] == APCI1500_OR ||
333 data[1] == APCI1500_OR_PRIORITY) {
334 /* Tests if a transition was declared */
335 /* for a OR PRIORITY logic */
337 if (data[1] == APCI1500_OR_PRIORITY
338 && i_PatternTransition != 0) {
339 dev_warn(dev->class_dev,
340 "Transition error on an OR PRIORITY logic\n");
344 /* Tests if more than one transition */
345 /* was declared for an AND logic */
347 if (data[1] == APCI1500_AND) {
348 for (i_Count = 0; i_Count < 8; i_Count++) {
349 i_PatternTransitionCount =
350 i_PatternTransitionCount +
351 ((i_PatternTransition >>
356 if (i_PatternTransitionCount > 1) {
357 dev_warn(dev->class_dev,
358 "Transition error on an AND logic\n");
364 z8536_write(dev, 0xf0,
365 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
367 z8536_write(dev, i_PatternPolarity,
368 APCI1500_RW_PORT_A_PATTERN_POLARITY);
369 z8536_write(dev, i_PatternMask,
370 APCI1500_RW_PORT_A_PATTERN_MASK);
371 z8536_write(dev, i_PatternTransition,
372 APCI1500_RW_PORT_A_PATTERN_TRANSITION);
374 /* Port A new mode */
375 i_RegValue = z8536_read(dev,
376 APCI1500_RW_PORT_A_SPECIFICATION);
377 i_RegValue = (i_RegValue & 0xF9) | data[1] | 0x9;
378 z8536_write(dev, i_RegValue,
379 APCI1500_RW_PORT_A_SPECIFICATION);
384 z8536_write(dev, 0xf4,
385 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
387 dev_warn(dev->class_dev,
388 "The choice for interrupt logic does not exist\n");
393 /* Test if event setting for port 2 */
396 /* Test the event logic */
398 if (data[1] == APCI1500_OR) {
400 z8536_write(dev, 0x74,
401 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
403 i_RegValue = z8536_read(dev,
404 APCI1500_RW_PORT_B_SPECIFICATION);
405 i_RegValue = i_RegValue & 0xF9;
406 z8536_write(dev, i_RegValue,
407 APCI1500_RW_PORT_B_SPECIFICATION);
409 /* Selects error channels 1 and 2 */
410 i_PatternMask = (i_PatternMask | 0xC0);
411 i_PatternPolarity = (i_PatternPolarity | 0xC0);
412 i_PatternTransition = (i_PatternTransition | 0xC0);
414 z8536_write(dev, i_PatternPolarity,
415 APCI1500_RW_PORT_B_PATTERN_POLARITY);
416 z8536_write(dev, i_PatternTransition,
417 APCI1500_RW_PORT_B_PATTERN_TRANSITION);
418 z8536_write(dev, i_PatternMask,
419 APCI1500_RW_PORT_B_PATTERN_MASK);
421 i_RegValue = z8536_read(dev,
422 APCI1500_RW_PORT_B_SPECIFICATION);
423 i_RegValue = (i_RegValue & 0xF9) | 4;
424 z8536_write(dev, i_RegValue,
425 APCI1500_RW_PORT_B_SPECIFICATION);
430 z8536_write(dev, 0xf4,
431 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
433 dev_warn(dev->class_dev,
434 "The choice for interrupt logic does not exist\n");
443 * Allows or disallows a port event
445 * data[0] 0 = Start input event, 1 = Stop input event
446 * data[1] Number of port (1 or 2)
448 static int apci1500_di_write(struct comedi_device *dev,
449 struct comedi_subdevice *s,
450 struct comedi_insn *insn,
453 int i_Event1InterruptStatus = 0, i_Event2InterruptStatus =
458 /* Tests the port number */
460 if (data[1] == 1 || data[1] == 2) {
461 /* Test if port 1 selected */
464 /* Test if event initialised */
465 if (i_Event1Status == 1) {
467 z8536_write(dev, 0xf0,
468 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
469 /* Allows the pattern interrupt */
470 z8536_write(dev, 0xc0,
471 APCI1500_RW_PORT_A_COMMAND_AND_STATUS);
473 z8536_write(dev, 0xf4,
474 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
476 i_Event1InterruptStatus = 1;
478 i_RegValue = z8536_read(dev,
479 APCI1500_RW_PORT_A_SPECIFICATION);
481 /* Authorizes the main interrupt on the board */
482 z8536_write(dev, 0xd0,
483 APCI1500_RW_MASTER_INTERRUPT_CONTROL);
485 dev_warn(dev->class_dev,
486 "Event 1 not initialised\n");
492 if (i_Event2Status == 1) {
494 z8536_write(dev, 0x74,
495 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
496 /* Allows the pattern interrupt */
497 z8536_write(dev, 0xc0,
498 APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
500 z8536_write(dev, 0xf4,
501 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
503 /* Authorizes the main interrupt on the board */
504 z8536_write(dev, 0xd0,
505 APCI1500_RW_MASTER_INTERRUPT_CONTROL);
507 i_Event2InterruptStatus = 1;
509 dev_warn(dev->class_dev,
510 "Event 2 not initialised\n");
515 dev_warn(dev->class_dev,
516 "The port parameter is in error\n");
523 /* Tests the port number */
525 if (data[1] == 1 || data[1] == 2) {
526 /* Test if port 1 selected */
529 /* Test if event initialised */
530 if (i_Event1Status == 1) {
532 z8536_write(dev, 0xf0,
533 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
534 /* Inhibits the pattern interrupt */
535 z8536_write(dev, 0xe0,
536 APCI1500_RW_PORT_A_COMMAND_AND_STATUS);
538 z8536_write(dev, 0xf4,
539 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
541 i_Event1InterruptStatus = 0;
543 dev_warn(dev->class_dev,
544 "Event 1 not initialised\n");
549 /* Test if event initialised */
550 if (i_Event2Status == 1) {
552 z8536_write(dev, 0x74,
553 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
554 /* Inhibits the pattern interrupt */
555 z8536_write(dev, 0xe0,
556 APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
558 z8536_write(dev, 0xf4,
559 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
561 i_Event2InterruptStatus = 0;
564 dev_warn(dev->class_dev,
565 "Event 2 not initialised\n");
571 dev_warn(dev->class_dev,
572 "The port parameter is in error\n");
577 dev_warn(dev->class_dev,
578 "The option of START/STOP logic does not exist\n");
586 * Return the status of the digital input
588 static int apci1500_di_read(struct comedi_device *dev,
589 struct comedi_subdevice *s,
590 struct comedi_insn *insn,
599 static int apci1500_di_insn_bits(struct comedi_device *dev,
600 struct comedi_subdevice *s,
601 struct comedi_insn *insn,
604 struct apci1500_private *devpriv = dev->private;
606 data[1] = inw(devpriv->i_IobaseAddon + APCI1500_DIGITAL_IP);
612 * Configures the digital output memory and the digital output error interrupt
614 * data[1] 1 = Enable the voltage error interrupt
615 * 2 = Disable the voltage error interrupt
617 static int apci1500_do_config(struct comedi_device *dev,
618 struct comedi_subdevice *s,
619 struct comedi_insn *insn,
622 struct apci1500_private *devpriv = dev->private;
624 devpriv->b_OutputMemoryStatus = data[0];
629 * Writes port value to the selected port
631 static int apci1500_do_write(struct comedi_device *dev,
632 struct comedi_subdevice *s,
633 struct comedi_insn *insn,
636 struct apci1500_private *devpriv = dev->private;
637 static unsigned int ui_Temp;
638 unsigned int ui_Temp1;
639 unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
641 if (!devpriv->b_OutputMemoryStatus)
646 data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
648 devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
651 switch (ui_NoOfChannel) {
672 data[0] = data[0] | ui_Temp;
676 dev_err(dev->class_dev,
677 "chan spec wrong\n");
678 return -EINVAL; /* "sorry channel spec wrong " */
683 devpriv->i_IobaseAddon +
684 APCI1500_DIGITAL_OP);
686 dev_warn(dev->class_dev,
687 "Specified channel not supported\n");
694 data[0] = ~data[0] & 0x1;
696 ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
697 ui_Temp = ui_Temp | ui_Temp1;
699 (data[0] << ui_NoOfChannel) ^
701 data[0] = data[0] & ui_Temp;
703 devpriv->i_IobaseAddon +
704 APCI1500_DIGITAL_OP);
707 switch (ui_NoOfChannel) {
710 data[0] = ~data[0] & 0x3;
713 ui_Temp1 << 2 * data[2];
714 ui_Temp = ui_Temp | ui_Temp1;
719 0xffffffff) & ui_Temp;
723 data[0] = ~data[0] & 0xf;
726 ui_Temp1 << 4 * data[2];
727 ui_Temp = ui_Temp | ui_Temp1;
732 0xffffffff) & ui_Temp;
736 data[0] = ~data[0] & 0xff;
739 ui_Temp1 << 8 * data[2];
740 ui_Temp = ui_Temp | ui_Temp1;
745 0xffffffff) & ui_Temp;
752 dev_err(dev->class_dev,
753 "chan spec wrong\n");
754 return -EINVAL; /* "sorry channel spec wrong " */
759 devpriv->i_IobaseAddon +
760 APCI1500_DIGITAL_OP);
762 dev_warn(dev->class_dev,
763 "Specified channel not supported\n");
768 dev_warn(dev->class_dev,
769 "Specified functionality does not exist\n");
778 * Configures The Watchdog
780 * data[0] 0 = APCI1500_115_KHZ, 1 = APCI1500_3_6_KHZ, 2 = APCI1500_1_8_KHZ
781 * data[1] 0 = Counter1/Timer1, 1 = Counter2/Timer2, 2 = Counter3/Watchdog
782 * data[2] 0 = Counter, 1 = Timer/Watchdog
783 * data[3] This parameter has two meanings. If the counter/timer is used as
784 * a counter the limit value of the counter is given. If the counter/timer
785 * is used as a timer, the divider factor for the output is given.
786 * data[4] 0 = APCI1500_CONTINUOUS, 1 = APCI1500_SINGLE
787 * data[5] 0 = Software Trigger, 1 = Hardware Trigger
788 * data[6] 0 = Software gate, 1 = Hardware gate
789 * data[7] 0 = Interrupt Disable, 1 = Interrupt Enable
791 static int apci1500_timer_config(struct comedi_device *dev,
792 struct comedi_subdevice *s,
793 struct comedi_insn *insn,
796 struct apci1500_private *devpriv = dev->private;
797 int i_TimerCounterMode, i_MasterConfiguration;
799 devpriv->tsk_Current = current;
801 /* Selection of the input clock */
802 if (data[0] == 0 || data[0] == 1 || data[0] == 2) {
803 outw(data[0], devpriv->i_IobaseAddon + APCI1500_CLK_SELECT);
806 dev_warn(dev->class_dev,
807 "The option for input clock selection does not exist\n");
811 /* Select the counter/timer */
814 /* selecting counter or timer */
817 data[2] = APCI1500_COUNTER;
820 data[2] = APCI1500_TIMER;
823 dev_warn(dev->class_dev,
824 "This choice is not a timer nor a counter\n");
828 /* Selecting single or continuous mode */
831 data[4] = APCI1500_CONTINUOUS;
834 data[4] = APCI1500_SINGLE;
837 dev_warn(dev->class_dev,
838 "This option for single/continuous mode does not exist\n");
842 i_TimerCounterMode = data[2] | data[4] | 7;
843 /* Test the reload value */
845 if ((data[3] >= 0) && (data[3] <= 65535)) {
846 if (data[7] == APCI1500_ENABLE ||
847 data[7] == APCI1500_DISABLE) {
848 /* Writes the new mode */
849 z8536_write(dev, i_TimerCounterMode,
850 APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION);
852 /* Writes the low value */
853 z8536_write(dev, data[3],
854 APCI1500_RW_CPT_TMR1_TIME_CST_LOW);
855 /* Writes the high value */
856 data[3] = data[3] >> 8;
857 z8536_write(dev, data[3],
858 APCI1500_RW_CPT_TMR1_TIME_CST_HIGH);
860 /* Enables timer/counter 1 and triggers timer/counter 1 */
861 i_MasterConfiguration = z8536_read(dev,
862 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
863 i_MasterConfiguration =
864 i_MasterConfiguration | 0x40;
865 z8536_write(dev, i_MasterConfiguration,
866 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
868 /* Disable timer/counter 1 */
869 z8536_write(dev, 0x00,
870 APCI1500_RW_CPT_TMR1_CMD_STATUS);
871 /* Trigger timer/counter 1 */
872 z8536_write(dev, 0x02,
873 APCI1500_RW_CPT_TMR1_CMD_STATUS);
875 dev_warn(dev->class_dev,
876 "Error in selection of interrupt enable or disable\n");
880 dev_warn(dev->class_dev,
881 "Error in selection of reload value\n");
884 i_TimerCounterWatchdogInterrupt = data[7];
885 i_TimerCounter1Init = 1;
888 case COUNTER2: /* selecting counter or timer */
891 data[2] = APCI1500_COUNTER;
894 data[2] = APCI1500_TIMER;
897 dev_warn(dev->class_dev,
898 "This choice is not a timer nor a counter\n");
902 /* Selecting single or continuous mode */
905 data[4] = APCI1500_CONTINUOUS;
908 data[4] = APCI1500_SINGLE;
911 dev_warn(dev->class_dev,
912 "This option for single/continuous mode does not exist\n");
916 /* Selecting software or hardware trigger */
919 data[5] = APCI1500_SOFTWARE_TRIGGER;
922 data[5] = APCI1500_HARDWARE_TRIGGER;
925 dev_warn(dev->class_dev,
926 "This choice for software or hardware trigger does not exist\n");
930 /* Selecting software or hardware gate */
933 data[6] = APCI1500_SOFTWARE_GATE;
936 data[6] = APCI1500_HARDWARE_GATE;
939 dev_warn(dev->class_dev,
940 "This choice for software or hardware gate does not exist\n");
944 i_TimerCounterMode = data[2] | data[4] | data[5] | data[6] | 7;
946 /* Test the reload value */
948 if ((data[3] >= 0) && (data[3] <= 65535)) {
949 if (data[7] == APCI1500_ENABLE ||
950 data[7] == APCI1500_DISABLE) {
951 /* Writes the new mode */
952 z8536_write(dev, i_TimerCounterMode,
953 APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION);
955 /* Writes the low value */
956 z8536_write(dev, data[3],
957 APCI1500_RW_CPT_TMR2_TIME_CST_LOW);
958 /* Writes the high value */
959 data[3] = data[3] >> 8;
960 z8536_write(dev, data[3],
961 APCI1500_RW_CPT_TMR2_TIME_CST_HIGH);
963 /* Enables timer/counter 2 and triggers timer/counter 2 */
964 i_MasterConfiguration = z8536_read(dev,
965 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
966 i_MasterConfiguration =
967 i_MasterConfiguration | 0x20;
968 z8536_write(dev, i_MasterConfiguration,
969 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
971 /* Disable timer/counter 2 */
972 z8536_write(dev, 0x00,
973 APCI1500_RW_CPT_TMR2_CMD_STATUS);
974 /* Trigger timer/counter 1 */
975 z8536_write(dev, 0x02,
976 APCI1500_RW_CPT_TMR2_CMD_STATUS);
978 dev_warn(dev->class_dev,
979 "Error in selection of interrupt enable or disable\n");
983 dev_warn(dev->class_dev,
984 "Error in selection of reload value\n");
987 i_TimerCounterWatchdogInterrupt = data[7];
988 i_TimerCounter2Init = 1;
991 case COUNTER3: /* selecting counter or watchdog */
994 data[2] = APCI1500_COUNTER;
997 data[2] = APCI1500_WATCHDOG;
1000 dev_warn(dev->class_dev,
1001 "This choice is not a watchdog nor a counter\n");
1005 /* Selecting single or continuous mode */
1008 data[4] = APCI1500_CONTINUOUS;
1011 data[4] = APCI1500_SINGLE;
1014 dev_warn(dev->class_dev,
1015 "This option for single/continuous mode does not exist\n");
1019 /* Selecting software or hardware gate */
1022 data[6] = APCI1500_SOFTWARE_GATE;
1025 data[6] = APCI1500_HARDWARE_GATE;
1028 dev_warn(dev->class_dev,
1029 "This choice for software or hardware gate does not exist\n");
1033 /* Test if used for watchdog */
1035 if (data[2] == APCI1500_WATCHDOG) {
1036 /* - Enables the output line */
1037 /* - Enables retrigger */
1038 /* - Pulses output */
1039 i_TimerCounterMode = data[2] | data[4] | 0x54;
1041 i_TimerCounterMode = data[2] | data[4] | data[6] | 7;
1043 /* Test the reload value */
1045 if ((data[3] >= 0) && (data[3] <= 65535)) {
1046 if (data[7] == APCI1500_ENABLE ||
1047 data[7] == APCI1500_DISABLE) {
1048 /* Writes the new mode */
1049 z8536_write(dev, i_TimerCounterMode,
1050 APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION);
1052 /* Writes the low value */
1053 z8536_write(dev, data[3],
1054 APCI1500_RW_CPT_TMR3_TIME_CST_LOW);
1055 /* Writes the high value */
1056 data[3] = data[3] >> 8;
1057 z8536_write(dev, data[3],
1058 APCI1500_RW_CPT_TMR3_TIME_CST_HIGH);
1060 /* Enables watchdog/counter 3 and triggers watchdog/counter 3 */
1061 i_MasterConfiguration = z8536_read(dev,
1062 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
1063 i_MasterConfiguration =
1064 i_MasterConfiguration | 0x10;
1065 z8536_write(dev, i_MasterConfiguration,
1066 APCI1500_RW_MASTER_CONFIGURATION_CONTROL);
1068 /* Test if COUNTER */
1069 if (data[2] == APCI1500_COUNTER) {
1070 /* Disable the watchdog/counter 3 and starts it */
1071 z8536_write(dev, 0x00,
1072 APCI1500_RW_CPT_TMR3_CMD_STATUS);
1073 /* Trigger the watchdog/counter 3 and starts it */
1074 z8536_write(dev, 0x02,
1075 APCI1500_RW_CPT_TMR3_CMD_STATUS);
1080 dev_warn(dev->class_dev,
1081 "Error in selection of interrupt enable or disable\n");
1085 dev_warn(dev->class_dev,
1086 "Error in selection of reload value\n");
1089 i_TimerCounterWatchdogInterrupt = data[7];
1090 i_WatchdogCounter3Init = 1;
1094 dev_warn(dev->class_dev,
1095 "The specified counter/timer option does not exist\n");
1098 i_CounterLogic = data[2];
1103 * Start / Stop or trigger the timer counter or Watchdog
1105 * data[0] 0 = Counter1/Timer1, 1 = Counter2/Timer2, 2 = Counter3/Watchdog
1106 * data[1] 0 = Start, 1 = Stop, 2 = Trigger
1107 * data[2] 0 = Counter, 1 = Timer/Watchdog
1109 static int apci1500_timer_write(struct comedi_device *dev,
1110 struct comedi_subdevice *s,
1111 struct comedi_insn *insn,
1114 int i_CommandAndStatusValue;
1120 if (i_TimerCounter1Init == 1) {
1121 if (i_TimerCounterWatchdogInterrupt == 1)
1122 i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1124 i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1126 /* Starts timer/counter 1 */
1127 i_TimerCounter1Enabled = 1;
1128 z8536_write(dev, i_CommandAndStatusValue,
1129 APCI1500_RW_CPT_TMR1_CMD_STATUS);
1131 dev_warn(dev->class_dev,
1132 "Counter/Timer1 not configured\n");
1138 /* Stop timer/counter 1 */
1139 z8536_write(dev, 0x00, APCI1500_RW_CPT_TMR1_CMD_STATUS);
1140 i_TimerCounter1Enabled = 0;
1144 if (i_TimerCounter1Init == 1) {
1145 if (i_TimerCounter1Enabled == 1) {
1146 /* Set Trigger and gate */
1148 i_CommandAndStatusValue = 0x6;
1152 i_CommandAndStatusValue = 0x2;
1154 z8536_write(dev, i_CommandAndStatusValue,
1155 APCI1500_RW_CPT_TMR1_CMD_STATUS);
1157 dev_warn(dev->class_dev,
1158 "Counter/Timer1 not configured\n");
1164 dev_warn(dev->class_dev,
1165 "The specified option for start/stop/trigger does not exist\n");
1173 if (i_TimerCounter2Init == 1) {
1174 if (i_TimerCounterWatchdogInterrupt == 1)
1175 i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1177 i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1179 /* Starts timer/counter 2 */
1180 i_TimerCounter2Enabled = 1;
1181 z8536_write(dev, i_CommandAndStatusValue,
1182 APCI1500_RW_CPT_TMR2_CMD_STATUS);
1184 dev_warn(dev->class_dev,
1185 "Counter/Timer2 not configured\n");
1191 /* Stop timer/counter 2 */
1192 z8536_write(dev, 0x00, APCI1500_RW_CPT_TMR2_CMD_STATUS);
1193 i_TimerCounter2Enabled = 0;
1196 if (i_TimerCounter2Init == 1) {
1197 if (i_TimerCounter2Enabled == 1) {
1198 /* Set Trigger and gate */
1200 i_CommandAndStatusValue = 0x6;
1204 i_CommandAndStatusValue = 0x2;
1206 z8536_write(dev, i_CommandAndStatusValue,
1207 APCI1500_RW_CPT_TMR2_CMD_STATUS);
1209 dev_warn(dev->class_dev,
1210 "Counter/Timer2 not configured\n");
1215 dev_warn(dev->class_dev,
1216 "The specified option for start/stop/trigger does not exist\n");
1223 if (i_WatchdogCounter3Init == 1) {
1225 if (i_TimerCounterWatchdogInterrupt == 1)
1226 i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */
1228 i_CommandAndStatusValue = 0xE4; /* disable the interrupt */
1230 /* Starts Watchdog/counter 3 */
1231 i_WatchdogCounter3Enabled = 1;
1232 z8536_write(dev, i_CommandAndStatusValue,
1233 APCI1500_RW_CPT_TMR3_CMD_STATUS);
1235 dev_warn(dev->class_dev,
1236 "Watchdog/Counter3 not configured\n");
1242 /* Stop Watchdog/counter 3 */
1243 z8536_write(dev, 0x00, APCI1500_RW_CPT_TMR3_CMD_STATUS);
1244 i_WatchdogCounter3Enabled = 0;
1249 case 0: /* triggering counter 3 */
1250 if (i_WatchdogCounter3Init == 1) {
1251 if (i_WatchdogCounter3Enabled == 1) {
1252 /* Set Trigger and gate */
1254 i_CommandAndStatusValue = 0x6;
1258 i_CommandAndStatusValue = 0x2;
1260 z8536_write(dev, i_CommandAndStatusValue,
1261 APCI1500_RW_CPT_TMR3_CMD_STATUS);
1263 dev_warn(dev->class_dev,
1264 "Counter3 not configured\n");
1269 /* triggering Watchdog 3 */
1270 if (i_WatchdogCounter3Init == 1) {
1271 z8536_write(dev, 0x06,
1272 APCI1500_RW_CPT_TMR3_CMD_STATUS);
1274 dev_warn(dev->class_dev,
1275 "Watchdog 3 not configured\n");
1280 dev_warn(dev->class_dev,
1281 "Wrong choice of watchdog/counter3\n");
1286 dev_warn(dev->class_dev,
1287 "The specified option for start/stop/trigger does not exist\n");
1292 dev_warn(dev->class_dev,
1293 "The specified choice for counter/watchdog/timer does not exist\n");
1302 * data[0] 0 = Counter1/Timer1, 1 = Counter2/Timer2, 2 = Counter3/Watchdog
1304 static int apci1500_timer_bits(struct comedi_device *dev,
1305 struct comedi_subdevice *s,
1306 struct comedi_insn *insn,
1309 int i_CommandAndStatusValue;
1313 /* Read counter/timer1 */
1314 if (i_TimerCounter1Init == 1) {
1315 if (i_TimerCounter1Enabled == 1) {
1316 /* Set RCC and gate */
1318 i_CommandAndStatusValue = 0xC;
1322 i_CommandAndStatusValue = 0x8;
1324 z8536_write(dev, i_CommandAndStatusValue,
1325 APCI1500_RW_CPT_TMR1_CMD_STATUS);
1327 data[0] = z8536_read(dev,
1328 APCI1500_R_CPT_TMR1_VALUE_HIGH);
1329 data[0] = data[0] << 8;
1330 data[0] = data[0] & 0xff00;
1331 data[0] |= z8536_read(dev,
1332 APCI1500_R_CPT_TMR1_VALUE_LOW);
1334 dev_warn(dev->class_dev,
1335 "Timer/Counter1 not configured\n");
1340 /* Read counter/timer2 */
1341 if (i_TimerCounter2Init == 1) {
1342 if (i_TimerCounter2Enabled == 1) {
1343 /* Set RCC and gate */
1345 i_CommandAndStatusValue = 0xC;
1349 i_CommandAndStatusValue = 0x8;
1351 z8536_write(dev, i_CommandAndStatusValue,
1352 APCI1500_RW_CPT_TMR2_CMD_STATUS);
1354 data[0] = z8536_read(dev,
1355 APCI1500_R_CPT_TMR2_VALUE_HIGH);
1356 data[0] = data[0] << 8;
1357 data[0] = data[0] & 0xff00;
1358 data[0] |= z8536_read(dev,
1359 APCI1500_R_CPT_TMR2_VALUE_LOW);
1361 dev_warn(dev->class_dev,
1362 "Timer/Counter2 not configured\n");
1367 /* Read counter/watchdog2 */
1368 if (i_WatchdogCounter3Init == 1) {
1369 if (i_WatchdogCounter3Enabled == 1) {
1370 /* Set RCC and gate */
1372 i_CommandAndStatusValue = 0xC;
1376 i_CommandAndStatusValue = 0x8;
1378 z8536_write(dev, i_CommandAndStatusValue,
1379 APCI1500_RW_CPT_TMR3_CMD_STATUS);
1381 data[0] = z8536_read(dev,
1382 APCI1500_R_CPT_TMR3_VALUE_HIGH);
1383 data[0] = data[0] << 8;
1384 data[0] = data[0] & 0xff00;
1385 data[0] |= z8536_read(dev,
1386 APCI1500_R_CPT_TMR3_VALUE_LOW);
1388 dev_warn(dev->class_dev,
1389 "WatchdogCounter3 not configured\n");
1394 dev_warn(dev->class_dev,
1395 "The choice of timer/counter/watchdog does not exist\n");
1403 * Read the interrupt mask
1405 * data[0] The interrupt mask value
1406 * data[1] Channel Number
1408 static int apci1500_timer_read(struct comedi_device *dev,
1409 struct comedi_subdevice *s,
1410 struct comedi_insn *insn,
1413 data[0] = i_InterruptMask;
1414 data[1] = i_InputChannel;
1415 i_InterruptMask = 0;
1420 * Configures the interrupt registers
1422 static int apci1500_do_bits(struct comedi_device *dev,
1423 struct comedi_subdevice *s,
1424 struct comedi_insn *insn,
1427 struct apci1500_private *devpriv = dev->private;
1428 unsigned int ui_Status;
1432 devpriv->tsk_Current = current;
1433 outl(0x0, devpriv->i_IobaseAmcc + 0x38);
1440 dev_warn(dev->class_dev,
1441 "The parameter passed to driver is in error for enabling the voltage interrupt\n");
1446 /* Writes the new configuration (APCI1500_OR) */
1447 i_RegValue = z8536_read(dev, APCI1500_RW_PORT_B_SPECIFICATION);
1448 i_RegValue = (i_RegValue & 0xF9) | APCI1500_OR;
1449 z8536_write(dev, i_RegValue, APCI1500_RW_PORT_B_SPECIFICATION);
1451 /* Authorises the interrupt on the board */
1452 z8536_write(dev, 0xc0, APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
1454 z8536_write(dev, i_Constant, APCI1500_RW_PORT_B_PATTERN_POLARITY);
1455 z8536_write(dev, i_Constant, APCI1500_RW_PORT_B_PATTERN_TRANSITION);
1456 z8536_write(dev, i_Constant, APCI1500_RW_PORT_B_PATTERN_MASK);
1458 /* Deletes the interrupt of port A */
1459 i_RegValue = z8536_read(dev, APCI1500_RW_PORT_A_COMMAND_AND_STATUS);
1460 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1461 z8536_write(dev, i_RegValue, APCI1500_RW_PORT_A_COMMAND_AND_STATUS);
1463 /* Deletes the interrupt of port B */
1464 i_RegValue = z8536_read(dev, APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
1465 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1466 z8536_write(dev, i_RegValue, APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
1468 /* Deletes the interrupt of timer 1 */
1469 i_RegValue = z8536_read(dev, APCI1500_RW_CPT_TMR1_CMD_STATUS);
1470 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1471 z8536_write(dev, i_RegValue, APCI1500_RW_CPT_TMR1_CMD_STATUS);
1473 /* Deletes the interrupt of timer 2 */
1474 i_RegValue = z8536_read(dev, APCI1500_RW_CPT_TMR2_CMD_STATUS);
1475 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1476 z8536_write(dev, i_RegValue, APCI1500_RW_CPT_TMR2_CMD_STATUS);
1478 /* Deletes the interrupt of timer 3 */
1479 i_RegValue = z8536_read(dev, APCI1500_RW_CPT_TMR3_CMD_STATUS);
1480 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1481 z8536_write(dev, i_RegValue, APCI1500_RW_CPT_TMR3_CMD_STATUS);
1483 /* Authorizes the main interrupt on the board */
1484 z8536_write(dev, 0xd0, APCI1500_RW_MASTER_INTERRUPT_CONTROL);
1486 /* Enables the PCI interrupt */
1487 outl(0x3000, devpriv->i_IobaseAmcc + 0x38);
1488 ui_Status = inl(devpriv->i_IobaseAmcc + 0x10);
1489 ui_Status = inl(devpriv->i_IobaseAmcc + 0x38);
1490 outl(0x23000, devpriv->i_IobaseAmcc + 0x38);
1495 static irqreturn_t apci1500_interrupt(int irq, void *d)
1498 struct comedi_device *dev = d;
1499 struct apci1500_private *devpriv = dev->private;
1500 unsigned int ui_InterruptStatus = 0;
1503 /* Clear the interrupt mask */
1504 i_InterruptMask = 0;
1506 /* Read the board interrupt status */
1507 ui_InterruptStatus = inl(devpriv->i_IobaseAmcc + 0x38);
1509 /* Test if board generated a interrupt */
1510 if ((ui_InterruptStatus & 0x800000) == 0x800000) {
1511 /* Disable all Interrupt */
1512 /* Selects the master interrupt control register */
1513 /* Disables the main interrupt on the board */
1514 i_RegValue = z8536_read(dev,
1515 APCI1500_RW_PORT_A_COMMAND_AND_STATUS);
1516 if ((i_RegValue & 0x60) == 0x60) {
1517 /* Deletes the interrupt of port A */
1518 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1519 z8536_write(dev, i_RegValue,
1520 APCI1500_RW_PORT_A_COMMAND_AND_STATUS);
1521 i_InterruptMask = i_InterruptMask | 1;
1522 if (i_Logic == APCI1500_OR_PRIORITY) {
1523 i_RegValue = z8536_read(dev,
1524 APCI1500_RW_PORT_A_SPECIFICATION);
1526 i_RegValue = z8536_read(dev,
1527 APCI1500_RW_PORT_A_INTERRUPT_CONTROL);
1529 i_InputChannel = 1 + (i_RegValue >> 1);
1536 i_RegValue = z8536_read(dev,
1537 APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
1538 if ((i_RegValue & 0x60) == 0x60) {
1539 /* Deletes the interrupt of port B */
1540 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1541 z8536_write(dev, i_RegValue,
1542 APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
1544 i_RegValue = inb(devpriv->iobase +
1545 APCI1500_Z8536_PORTB_REG);
1547 i_RegValue = i_RegValue & 0xC0;
1548 /* Tests if this is an external error */
1551 /* Disable the interrupt */
1552 /* Selects the command and status register of port B */
1553 outl(0x0, devpriv->i_IobaseAmcc + 0x38);
1555 if (i_RegValue & 0x80) {
1557 i_InterruptMask | 0x40;
1560 if (i_RegValue & 0x40) {
1562 i_InterruptMask | 0x80;
1565 i_InterruptMask = i_InterruptMask | 2;
1569 i_RegValue = z8536_read(dev, APCI1500_RW_CPT_TMR1_CMD_STATUS);
1570 if ((i_RegValue & 0x60) == 0x60) {
1571 /* Deletes the interrupt of timer 1 */
1572 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1573 z8536_write(dev, i_RegValue,
1574 APCI1500_RW_CPT_TMR1_CMD_STATUS);
1575 i_InterruptMask = i_InterruptMask | 4;
1578 i_RegValue = z8536_read(dev, APCI1500_RW_CPT_TMR2_CMD_STATUS);
1579 if ((i_RegValue & 0x60) == 0x60) {
1580 /* Deletes the interrupt of timer 2 */
1581 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1582 z8536_write(dev, i_RegValue,
1583 APCI1500_RW_CPT_TMR2_CMD_STATUS);
1584 i_InterruptMask = i_InterruptMask | 8;
1587 i_RegValue = z8536_read(dev, APCI1500_RW_CPT_TMR3_CMD_STATUS);
1588 if ((i_RegValue & 0x60) == 0x60) {
1589 /* Deletes the interrupt of timer 3 */
1590 i_RegValue = (i_RegValue & 0x0F) | 0x20;
1591 z8536_write(dev, i_RegValue,
1592 APCI1500_RW_CPT_TMR3_CMD_STATUS);
1593 if (i_CounterLogic == APCI1500_COUNTER)
1594 i_InterruptMask = i_InterruptMask | 0x10;
1596 i_InterruptMask = i_InterruptMask | 0x20;
1599 send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
1601 /* Authorizes the main interrupt on the board */
1602 z8536_write(dev, 0xd0, APCI1500_RW_MASTER_INTERRUPT_CONTROL);
1604 dev_warn(dev->class_dev,
1605 "Interrupt from unknown source\n");
1612 static int apci1500_reset(struct comedi_device *dev)
1614 struct apci1500_private *devpriv = dev->private;
1616 i_TimerCounter1Init = 0;
1617 i_TimerCounter2Init = 0;
1618 i_WatchdogCounter3Init = 0;
1621 i_TimerCounterWatchdogInterrupt = 0;
1624 i_InterruptMask = 0;
1626 i_TimerCounter1Enabled = 0;
1627 i_TimerCounter2Enabled = 0;
1628 i_WatchdogCounter3Enabled = 0;
1630 /* Software reset */
1633 /* reset all the digital outputs */
1634 outw(0x0, devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
1636 /* Deactivates all interrupts */
1637 z8536_write(dev, 0x00, APCI1500_RW_MASTER_INTERRUPT_CONTROL);
1638 z8536_write(dev, 0x00, APCI1500_RW_PORT_A_COMMAND_AND_STATUS);
1639 z8536_write(dev, 0x00, APCI1500_RW_PORT_B_COMMAND_AND_STATUS);
1640 z8536_write(dev, 0x00, APCI1500_RW_CPT_TMR1_CMD_STATUS);
1641 z8536_write(dev, 0x00, APCI1500_RW_CPT_TMR2_CMD_STATUS);
1642 z8536_write(dev, 0x00, APCI1500_RW_CPT_TMR3_CMD_STATUS);