4 Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data.com
14 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 You should also find the complete GPL in the COPYING file accompanying this source code.
26 +-----------------------------------------------------------------------+
27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28 +-----------------------------------------------------------------------+
29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31 +-------------------------------+---------------------------------------+
32 | Project : APCI-1564 | Compiler : GCC |
33 | Module name : hwdrv_apci1564.c| Version : 2.96 |
34 +-------------------------------+---------------------------------------+
35 | Project manager: Eric Stolz | Date : 02/12/2002 |
36 +-------------------------------+---------------------------------------+
37 | Description : Hardware Layer Access For APCI-1564 |
38 +-----------------------------------------------------------------------+
40 +----------+-----------+------------------------------------------------+
41 | Date | Author | Description of updates |
42 +----------+-----------+------------------------------------------------+
46 +----------+-----------+------------------------------------------------+
49 /********* Definitions for APCI-1564 card *****/
51 #define APCI1564_ADDRESS_RANGE 128
53 /* DIGITAL INPUT-OUTPUT DEFINE */
55 #define APCI1564_DIGITAL_IP 0x04
56 #define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4
57 #define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8
58 #define APCI1564_DIGITAL_IP_IRQ 16
61 #define APCI1564_DIGITAL_OP 0x18
62 #define APCI1564_DIGITAL_OP_RW 0
63 #define APCI1564_DIGITAL_OP_INTERRUPT 4
64 #define APCI1564_DIGITAL_OP_IRQ 12
66 /* Digital Input IRQ Function Selection */
68 #define ADDIDATA_AND 1
70 /* Digital Input Interrupt Status */
71 #define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12
73 /* Digital Output Interrupt Status */
74 #define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8
76 /* Digital Input Interrupt Enable Disable. */
77 #define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4
78 #define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xfffffffb
80 /* Digital Output Interrupt Enable Disable. */
81 #define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
82 #define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xfffffffe
83 #define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
84 #define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xfffffffd
86 /* TIMER COUNTER WATCHDOG DEFINES */
88 #define ADDIDATA_TIMER 0
89 #define ADDIDATA_COUNTER 1
90 #define ADDIDATA_WATCHDOG 2
91 #define APCI1564_DIGITAL_OP_WATCHDOG 0x28
92 #define APCI1564_TIMER 0x48
93 #define APCI1564_COUNTER1 0x0
94 #define APCI1564_COUNTER2 0x20
95 #define APCI1564_COUNTER3 0x40
96 #define APCI1564_COUNTER4 0x60
97 #define APCI1564_TCW_SYNC_ENABLEDISABLE 0
98 #define APCI1564_TCW_RELOAD_VALUE 4
99 #define APCI1564_TCW_TIMEBASE 8
100 #define APCI1564_TCW_PROG 12
101 #define APCI1564_TCW_TRIG_STATUS 16
102 #define APCI1564_TCW_IRQ 20
103 #define APCI1564_TCW_WARN_TIMEVAL 24
104 #define APCI1564_TCW_WARN_TIMEBASE 28
106 /* Global variables */
107 static unsigned int ui_InterruptStatus_1564 = 0;
108 static unsigned int ui_InterruptData, ui_Type;
111 +----------------------------------------------------------------------------+
112 | Function Name : int i_APCI1564_ConfigDigitalInput |
113 | (struct comedi_device *dev,struct comedi_subdevice *s, |
114 | struct comedi_insn *insn,unsigned int *data) |
115 +----------------------------------------------------------------------------+
116 | Task : Configures the digital input Subdevice |
117 +----------------------------------------------------------------------------+
118 | Input Parameters : struct comedi_device *dev : Driver handle |
119 | unsigned int *data : Data Pointer contains |
120 | configuration parameters as below |
122 | data[0] : 1 Enable Digital Input Interrupt |
123 | 0 Disable Digital Input Interrupt |
124 | data[1] : 0 ADDIDATA Interrupt OR LOGIC |
125 | : 1 ADDIDATA Interrupt AND LOGIC |
126 | data[2] : Interrupt mask for the mode 1 |
127 | data[3] : Interrupt mask for the mode 2 |
129 +----------------------------------------------------------------------------+
130 | Output Parameters : -- |
131 +----------------------------------------------------------------------------+
132 | Return Value : TRUE : No error occur |
133 | : FALSE : Error occur. Return the error |
135 +----------------------------------------------------------------------------+
137 static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev,
138 struct comedi_subdevice *s,
139 struct comedi_insn *insn,
142 struct addi_private *devpriv = dev->private;
144 devpriv->tsk_Current = current;
145 /*******************************/
146 /* Set the digital input logic */
147 /*******************************/
148 if (data[0] == ADDIDATA_ENABLE) {
149 data[2] = data[2] << 4;
150 data[3] = data[3] << 4;
152 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
153 APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
155 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
156 APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
157 if (data[1] == ADDIDATA_OR) {
159 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
160 APCI1564_DIGITAL_IP_IRQ);
161 } /* if (data[1] == ADDIDATA_OR) */
164 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
165 APCI1564_DIGITAL_IP_IRQ);
166 } /* else if (data[1] == ADDIDATA_OR) */
167 } /* if (data[0] == ADDIDATA_ENABLE) */
170 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
171 APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
173 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
174 APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
176 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
177 APCI1564_DIGITAL_IP_IRQ);
178 } /* else if (data[0] == ADDIDATA_ENABLE) */
183 static int apci1564_di_insn_bits(struct comedi_device *dev,
184 struct comedi_subdevice *s,
185 struct comedi_insn *insn,
188 struct addi_private *devpriv = dev->private;
190 data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
196 +----------------------------------------------------------------------------+
197 | Function Name : int i_APCI1564_ConfigDigitalOutput |
198 | (struct comedi_device *dev,struct comedi_subdevice *s, |
199 | struct comedi_insn *insn,unsigned int *data) |
200 +----------------------------------------------------------------------------+
201 | Task : Configures The Digital Output Subdevice. |
202 +----------------------------------------------------------------------------+
203 | Input Parameters : struct comedi_device *dev : Driver handle |
204 | unsigned int *data : Data Pointer contains |
205 | configuration parameters as below |
207 | data[1] : 1 Enable VCC Interrupt |
208 | 0 Disable VCC Interrupt |
209 | data[2] : 1 Enable CC Interrupt |
210 | 0 Disable CC Interrupt |
212 +----------------------------------------------------------------------------+
213 | Output Parameters : -- |
214 +----------------------------------------------------------------------------+
215 | Return Value : TRUE : No error occur |
216 | : FALSE : Error occur. Return the error |
218 +----------------------------------------------------------------------------+
220 static int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev,
221 struct comedi_subdevice *s,
222 struct comedi_insn *insn,
225 struct addi_private *devpriv = dev->private;
226 unsigned int ul_Command = 0;
228 if ((data[0] != 0) && (data[0] != 1)) {
230 "Not a valid Data !!! ,Data should be 1 or 0\n");
232 } /* if ((data[0]!=0) && (data[0]!=1)) */
234 devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
237 devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
238 } /* else if (data[0]) */
239 if (data[1] == ADDIDATA_ENABLE) {
240 ul_Command = ul_Command | 0x1;
241 } /* if (data[1] == ADDIDATA_ENABLE) */
243 ul_Command = ul_Command & 0xFFFFFFFE;
244 } /* else if (data[1] == ADDIDATA_ENABLE) */
245 if (data[2] == ADDIDATA_ENABLE) {
246 ul_Command = ul_Command | 0x2;
247 } /* if (data[2] == ADDIDATA_ENABLE) */
249 ul_Command = ul_Command & 0xFFFFFFFD;
250 } /* else if (data[2] == ADDIDATA_ENABLE) */
252 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
253 APCI1564_DIGITAL_OP_INTERRUPT);
255 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
256 APCI1564_DIGITAL_OP_INTERRUPT);
257 devpriv->tsk_Current = current;
261 static int apci1564_do_insn_bits(struct comedi_device *dev,
262 struct comedi_subdevice *s,
263 struct comedi_insn *insn,
266 struct addi_private *devpriv = dev->private;
267 unsigned int mask = data[0];
268 unsigned int bits = data[1];
270 s->state = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
271 APCI1564_DIGITAL_OP_RW);
274 s->state |= (bits & mask);
276 outl(s->state, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
277 APCI1564_DIGITAL_OP_RW);
286 +----------------------------------------------------------------------------+
287 | Function Name : int i_APCI1564_ConfigTimerCounterWatchdog |
288 | (struct comedi_device *dev,struct comedi_subdevice *s, |
289 | struct comedi_insn *insn,unsigned int *data) |
290 +----------------------------------------------------------------------------+
291 | Task : Configures The Timer , Counter or Watchdog |
292 +----------------------------------------------------------------------------+
293 | Input Parameters : struct comedi_device *dev : Driver handle |
294 | unsigned int *data : Data Pointer contains |
295 | configuration parameters as below |
297 | data[0] : 0 Configure As Timer |
298 | 1 Configure As Counter |
299 | 2 Configure As Watchdog |
300 | data[1] : 1 Enable Interrupt |
301 | 0 Disable Interrupt |
302 | data[2] : Time Unit |
303 | data[3] : Reload Value |
304 | data[4] : Timer Mode |
305 | data[5] : Timer Counter Watchdog Number|
306 data[6] : Counter Direction
307 +----------------------------------------------------------------------------+
308 | Output Parameters : -- |
309 +----------------------------------------------------------------------------+
310 | Return Value : TRUE : No error occur |
311 | : FALSE : Error occur. Return the error |
313 +----------------------------------------------------------------------------+
315 static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
316 struct comedi_subdevice *s,
317 struct comedi_insn *insn,
320 struct addi_private *devpriv = dev->private;
321 unsigned int ul_Command1 = 0;
323 devpriv->tsk_Current = current;
324 if (data[0] == ADDIDATA_WATCHDOG) {
325 devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
327 /* Disable the watchdog */
329 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
331 /* Loading the Reload value */
333 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
334 APCI1564_TCW_RELOAD_VALUE);
335 } /* if (data[0]==ADDIDATA_WATCHDOG) */
336 else if (data[0] == ADDIDATA_TIMER) {
337 /* First Stop The Timer */
339 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
341 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
342 outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* Stop The Timer */
344 devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
346 outl(0x02, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */
348 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
349 APCI1564_DIGITAL_IP_IRQ);
351 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
352 APCI1564_DIGITAL_OP_IRQ);
354 devpriv->i_IobaseAmcc +
355 APCI1564_DIGITAL_OP_WATCHDOG +
358 devpriv->iobase + APCI1564_COUNTER1 +
361 devpriv->iobase + APCI1564_COUNTER2 +
364 devpriv->iobase + APCI1564_COUNTER3 +
367 devpriv->iobase + APCI1564_COUNTER4 +
369 } /* if (data[1]==1) */
371 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* disable Timer interrupt */
372 } /* else if (data[1]==1) */
374 /* Loading Timebase */
377 devpriv->i_IobaseAmcc + APCI1564_TIMER +
378 APCI1564_TCW_TIMEBASE);
380 /* Loading the Reload value */
382 devpriv->i_IobaseAmcc + APCI1564_TIMER +
383 APCI1564_TCW_RELOAD_VALUE);
386 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
389 (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
390 outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* mode 2 */
391 } /* else if (data[0]==ADDIDATA_TIMER) */
392 else if (data[0] == ADDIDATA_COUNTER) {
393 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
394 devpriv->b_ModeSelectRegister = data[5];
396 /* First Stop The Counter */
398 inl(devpriv->iobase + ((data[5] - 1) * 0x20) +
400 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
401 outl(ul_Command1, devpriv->iobase + ((data[5] - 1) * 0x20) + APCI1564_TCW_PROG); /* Stop The Timer */
403 /************************/
404 /* Set the reload value */
405 /************************/
407 devpriv->iobase + ((data[5] - 1) * 0x20) +
408 APCI1564_TCW_RELOAD_VALUE);
410 /******************************/
412 /* - Disable the hardware */
413 /* - Disable the counter mode */
414 /* - Disable the warning */
415 /* - Disable the reset */
416 /* - Disable the timer mode */
417 /* - Enable the counter mode */
418 /******************************/
420 (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL |
421 (unsigned int) ((unsigned int) data[4] << 16UL);
423 devpriv->iobase + ((data[5] - 1) * 0x20) +
426 /* Enable or Disable Interrupt */
427 ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
429 devpriv->iobase + ((data[5] - 1) * 0x20) +
432 /*****************************/
433 /* Set the Up/Down selection */
434 /*****************************/
435 ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
437 devpriv->iobase + ((data[5] - 1) * 0x20) +
439 } /* else if (data[0]==ADDIDATA_COUNTER) */
441 printk(" Invalid subdevice.");
442 } /* else if (data[0]==ADDIDATA_WATCHDOG) */
448 +----------------------------------------------------------------------------+
449 | Function Name : int i_APCI1564_StartStopWriteTimerCounterWatchdog |
450 | (struct comedi_device *dev,struct comedi_subdevice *s, |
451 | struct comedi_insn *insn,unsigned int *data) |
452 +----------------------------------------------------------------------------+
453 | Task : Start / Stop The Selected Timer , Counter or Watchdog |
454 +----------------------------------------------------------------------------+
455 | Input Parameters : struct comedi_device *dev : Driver handle |
456 | unsigned int *data : Data Pointer contains |
457 | configuration parameters as below |
459 | data[0] : 0 Timer |
461 | 2 Watchdog | | data[1] : 1 Start |
464 | Clear (Only Counter) |
465 +----------------------------------------------------------------------------+
466 | Output Parameters : -- |
467 +----------------------------------------------------------------------------+
468 | Return Value : TRUE : No error occur |
469 | : FALSE : Error occur. Return the error |
471 +----------------------------------------------------------------------------+
473 static int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
474 struct comedi_subdevice *s,
475 struct comedi_insn *insn,
478 struct addi_private *devpriv = dev->private;
479 unsigned int ul_Command1 = 0;
481 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
483 case 0: /* stop the watchdog */
484 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_PROG); /* disable the watchdog */
486 case 1: /* start the watchdog */
488 devpriv->i_IobaseAmcc +
489 APCI1564_DIGITAL_OP_WATCHDOG +
492 case 2: /* Software trigger */
494 devpriv->i_IobaseAmcc +
495 APCI1564_DIGITAL_OP_WATCHDOG +
499 printk("\nSpecified functionality does not exist\n");
501 } /* switch (data[1]) */
502 } /* if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG) */
503 if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
506 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
508 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
510 /* Enable the Timer */
512 devpriv->i_IobaseAmcc + APCI1564_TIMER +
514 } /* if (data[1]==1) */
515 else if (data[1] == 0) {
519 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
521 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
523 devpriv->i_IobaseAmcc + APCI1564_TIMER +
525 } /* else if(data[1]==0) */
526 } /* if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) */
527 if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
529 inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
530 1) * 0x20) + APCI1564_TCW_PROG);
532 /* Start the Counter subdevice */
533 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
534 } /* if (data[1] == 1) */
535 else if (data[1] == 0) {
536 /* Stops the Counter subdevice */
539 } /* else if (data[1] == 0) */
540 else if (data[1] == 2) {
541 /* Clears the Counter subdevice */
542 ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
543 } /* else if (data[1] == 3) */
545 devpriv->iobase + ((devpriv->b_ModeSelectRegister -
546 1) * 0x20) + APCI1564_TCW_PROG);
547 } /* if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER) */
552 +----------------------------------------------------------------------------+
553 | Function Name : int i_APCI1564_ReadTimerCounterWatchdog |
554 | (struct comedi_device *dev,struct comedi_subdevice *s, |
555 | struct comedi_insn *insn,unsigned int *data) |
556 +----------------------------------------------------------------------------+
557 | Task : Read The Selected Timer , Counter or Watchdog |
558 +----------------------------------------------------------------------------+
559 | Input Parameters : struct comedi_device *dev : Driver handle |
560 | unsigned int *data : Data Pointer contains |
561 | configuration parameters as below |
564 +----------------------------------------------------------------------------+
565 | Output Parameters : -- |
566 +----------------------------------------------------------------------------+
567 | Return Value : TRUE : No error occur |
568 | : FALSE : Error occur. Return the error |
570 +----------------------------------------------------------------------------+
572 static int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
573 struct comedi_subdevice *s,
574 struct comedi_insn *insn,
577 struct addi_private *devpriv = dev->private;
578 unsigned int ul_Command1 = 0;
580 if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
581 /* Stores the status of the Watchdog */
583 inl(devpriv->i_IobaseAmcc +
584 APCI1564_DIGITAL_OP_WATCHDOG +
585 APCI1564_TCW_TRIG_STATUS) & 0x1;
587 inl(devpriv->i_IobaseAmcc +
588 APCI1564_DIGITAL_OP_WATCHDOG);
589 } /* if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG) */
590 else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
591 /* Stores the status of the Timer */
593 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
594 APCI1564_TCW_TRIG_STATUS) & 0x1;
596 /* Stores the Actual value of the Timer */
597 data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER);
598 } /* else if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) */
599 else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
600 /* Read the Counter Actual Value. */
602 inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
604 APCI1564_TCW_SYNC_ENABLEDISABLE);
606 inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
607 1) * 0x20) + APCI1564_TCW_TRIG_STATUS);
609 /***********************************/
610 /* Get the software trigger status */
611 /***********************************/
612 data[1] = (unsigned char) ((ul_Command1 >> 1) & 1);
614 /***********************************/
615 /* Get the hardware trigger status */
616 /***********************************/
617 data[2] = (unsigned char) ((ul_Command1 >> 2) & 1);
619 /*********************************/
620 /* Get the software clear status */
621 /*********************************/
622 data[3] = (unsigned char) ((ul_Command1 >> 3) & 1);
624 /***************************/
625 /* Get the overflow status */
626 /***************************/
627 data[4] = (unsigned char) ((ul_Command1 >> 0) & 1);
628 } /* else if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER) */
629 else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
630 && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)
631 && (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) {
632 printk("\n Invalid Subdevice !!!\n");
633 } /* else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG)&& (devpriv->b_TimerSelectMode!=ADDIDATA_COUNTER)) */
638 +----------------------------------------------------------------------------+
639 | Function Name : int i_APCI1564_ReadInterruptStatus |
640 | (struct comedi_device *dev,struct comedi_subdevice *s, |
641 | struct comedi_insn *insn,unsigned int *data) |
642 +----------------------------------------------------------------------------+
643 | Task :Reads the interrupt status register |
644 +----------------------------------------------------------------------------+
645 | Input Parameters : |
646 +----------------------------------------------------------------------------+
647 | Output Parameters : -- |
648 +----------------------------------------------------------------------------+
651 +----------------------------------------------------------------------------+
654 static int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev,
655 struct comedi_subdevice *s,
656 struct comedi_insn *insn,
664 +----------------------------------------------------------------------------+
665 | Function Name : static void v_APCI1564_Interrupt |
666 | (int irq , void *d) |
667 +----------------------------------------------------------------------------+
668 | Task : Interrupt handler for the interruptible digital inputs |
669 +----------------------------------------------------------------------------+
670 | Input Parameters : int irq : irq number |
671 | void *d : void pointer |
672 +----------------------------------------------------------------------------+
673 | Output Parameters : -- |
674 +----------------------------------------------------------------------------+
675 | Return Value : TRUE : No error occur |
676 | : FALSE : Error occur. Return the error |
678 +----------------------------------------------------------------------------+
680 static void v_APCI1564_Interrupt(int irq, void *d)
682 struct comedi_device *dev = d;
683 struct addi_private *devpriv = dev->private;
684 unsigned int ui_DO, ui_DI;
685 unsigned int ui_Timer;
686 unsigned int ui_C1, ui_C2, ui_C3, ui_C4;
687 unsigned int ul_Command2 = 0;
689 ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
690 APCI1564_DIGITAL_IP_IRQ) & 0x01;
691 ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
692 APCI1564_DIGITAL_OP_IRQ) & 0x01;
694 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
695 APCI1564_TCW_IRQ) & 0x01;
696 ui_C1 = inl(devpriv->iobase + APCI1564_COUNTER1 +
697 APCI1564_TCW_IRQ) & 0x1;
698 ui_C2 = inl(devpriv->iobase + APCI1564_COUNTER2 +
699 APCI1564_TCW_IRQ) & 0x1;
700 ui_C3 = inl(devpriv->iobase + APCI1564_COUNTER3 +
701 APCI1564_TCW_IRQ) & 0x1;
702 ui_C4 = inl(devpriv->iobase + APCI1564_COUNTER4 +
703 APCI1564_TCW_IRQ) & 0x1;
704 if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
705 && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
706 printk("\nInterrupt from unknown source\n");
707 } /* if(ui_DI==0 && ui_DO==0 && ui_Timer==0 && ui_C1==0 && ui_C2==0 && ui_C3==0 && ui_C4==0) */
710 ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
711 APCI1564_DIGITAL_IP_IRQ);
713 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
714 APCI1564_DIGITAL_IP_IRQ);
715 ui_InterruptStatus_1564 =
716 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
717 APCI1564_DIGITAL_IP_INTERRUPT_STATUS);
718 ui_InterruptStatus_1564 = ui_InterruptStatus_1564 & 0X000FFFF0;
719 send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
720 outl(ui_DI, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ); /* enable the interrupt */
725 /* Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt. */
727 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
728 APCI1564_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
729 /* Disable the Interrupt */
731 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
732 APCI1564_DIGITAL_OP_INTERRUPT);
734 /* Sends signal to user space */
735 send_sig(SIGIO, devpriv->tsk_Current, 0);
740 devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
741 if (devpriv->b_TimerSelectMode) {
743 /* Disable Timer Interrupt */
745 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
748 devpriv->i_IobaseAmcc + APCI1564_TIMER +
751 /* Send a signal to from kernel to user space */
752 send_sig(SIGIO, devpriv->tsk_Current, 0);
754 /* Enable Timer Interrupt */
757 devpriv->i_IobaseAmcc + APCI1564_TIMER +
760 }/* if (ui_Timer == 1) */
764 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
765 if (devpriv->b_TimerSelectMode) {
767 /* Disable Counter Interrupt */
769 inl(devpriv->iobase + APCI1564_COUNTER1 +
772 devpriv->iobase + APCI1564_COUNTER1 +
775 /* Send a signal to from kernel to user space */
776 send_sig(SIGIO, devpriv->tsk_Current, 0);
778 /* Enable Counter Interrupt */
780 devpriv->iobase + APCI1564_COUNTER1 +
783 } /* if (ui_C1 == 1) */
786 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
787 if (devpriv->b_TimerSelectMode) {
789 /* Disable Counter Interrupt */
791 inl(devpriv->iobase + APCI1564_COUNTER2 +
794 devpriv->iobase + APCI1564_COUNTER2 +
797 /* Send a signal to from kernel to user space */
798 send_sig(SIGIO, devpriv->tsk_Current, 0);
800 /* Enable Counter Interrupt */
802 devpriv->iobase + APCI1564_COUNTER2 +
805 } /* if ((ui_C2 == 1) */
808 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
809 if (devpriv->b_TimerSelectMode) {
811 /* Disable Counter Interrupt */
813 inl(devpriv->iobase + APCI1564_COUNTER3 +
816 devpriv->iobase + APCI1564_COUNTER3 +
819 /* Send a signal to from kernel to user space */
820 send_sig(SIGIO, devpriv->tsk_Current, 0);
822 /* Enable Counter Interrupt */
824 devpriv->iobase + APCI1564_COUNTER3 +
827 } /* if ((ui_C3 == 1) */
830 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
831 if (devpriv->b_TimerSelectMode) {
833 /* Disable Counter Interrupt */
835 inl(devpriv->iobase + APCI1564_COUNTER4 +
838 devpriv->iobase + APCI1564_COUNTER4 +
841 /* Send a signal to from kernel to user space */
842 send_sig(SIGIO, devpriv->tsk_Current, 0);
844 /* Enable Counter Interrupt */
846 devpriv->iobase + APCI1564_COUNTER4 +
849 } /* if (ui_C4 == 1) */
854 +----------------------------------------------------------------------------+
855 | Function Name : int i_APCI1564_Reset(struct comedi_device *dev) | |
856 +----------------------------------------------------------------------------+
857 | Task :resets all the registers |
858 +----------------------------------------------------------------------------+
859 | Input Parameters : struct comedi_device *dev
860 +----------------------------------------------------------------------------+
861 | Output Parameters : -- |
862 +----------------------------------------------------------------------------+
865 +----------------------------------------------------------------------------+
868 static int i_APCI1564_Reset(struct comedi_device *dev)
870 struct addi_private *devpriv = dev->private;
872 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ); /* disable the interrupts */
873 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS); /* Reset the interrupt status register */
874 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */
875 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
876 devpriv->b_DigitalOutputRegister = 0;
878 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP); /* Resets the output channels */
879 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_INTERRUPT); /* Disables the interrupt. */
881 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
882 APCI1564_TCW_RELOAD_VALUE);
883 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER);
884 outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
886 outl(0x0, devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
887 outl(0x0, devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
888 outl(0x0, devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
889 outl(0x0, devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);