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