Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
APCI1710_Ssi.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 : API APCI1710 | Compiler : gcc |
33  | Module name : SSI.C | Version : 2.96 |
34  +-------------------------------+---------------------------------------+
35  | Project manager: Eric Stolz | Date : 02/12/2002 |
36  +-----------------------------------------------------------------------+
37  | Description : APCI-1710 SSI counter module |
38  +-----------------------------------------------------------------------+
39  | several changes done by S. Weber in 1998 and C. Guinot in 2000 |
40  +-----------------------------------------------------------------------+
41 */
42 
43 /*
44 +----------------------------------------------------------------------------+
45 | Included files |
46 +----------------------------------------------------------------------------+
47 */
48 
49 #include "APCI1710_Ssi.h"
50 
51 /*
52 +----------------------------------------------------------------------------+
53 | Function Name : _INT_ i_APCI1710_InitSSI |
54 | (unsigned char_ b_BoardHandle, |
55 | unsigned char_ b_ModulNbr, |
56 | unsigned char_ b_SSIProfile, |
57 | unsigned char_ b_PositionTurnLength, |
58 | unsigned char_ b_TurnCptLength, |
59 | unsigned char_ b_PCIInputClock, |
60 | ULONG_ ul_SSIOutputClock, |
61 | unsigned char_ b_SSICountingMode) |
62 +----------------------------------------------------------------------------+
63 | Task : Configure the SSI operating mode from selected module |
64 | (b_ModulNbr). You must calling this function be for you|
65 | call any other function witch access of SSI. |
66 +----------------------------------------------------------------------------+
67 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
68 | unsigned char_ b_ModulNbr : Module number to |
69 | configure (0 to 3) |
70 | unsigned char_ b_SSIProfile : Selection from SSI |
71 | profile length (2 to 32).|
72 | unsigned char_ b_PositionTurnLength : Selection from SSI |
73 | position data length |
74 | (1 to 31). |
75 | unsigned char_ b_TurnCptLength : Selection from SSI turn |
76 | counter data length |
77 | (1 to 31). |
78 | unsigned char b_PCIInputClock : Selection from PCI bus |
79 | clock |
80 | - APCI1710_30MHZ : |
81 | The PC have a PCI bus |
82 | clock from 30 MHz |
83 | - APCI1710_33MHZ : |
84 | The PC have a PCI bus |
85 | clock from 33 MHz |
86 | ULONG_ ul_SSIOutputClock : Selection from SSI output|
87 | clock. |
88 | From 229 to 5 000 000 Hz|
89 | for 30 MHz selection. |
90 | From 252 to 5 000 000 Hz|
91 | for 33 MHz selection. |
92 | unsigned char b_SSICountingMode : SSI counting mode |
93 | selection |
94 | - APCI1710_BINARY_MODE : |
95 | Binary counting mode. |
96 | - APCI1710_GRAY_MODE : |
97 | Gray counting mode.
98 
99  b_ModulNbr = CR_AREF(insn->chanspec);
100  b_SSIProfile = (unsigned char) data[0];
101  b_PositionTurnLength= (unsigned char) data[1];
102  b_TurnCptLength = (unsigned char) data[2];
103  b_PCIInputClock = (unsigned char) data[3];
104  ul_SSIOutputClock = (unsigned int) data[4];
105  b_SSICountingMode = (unsigned char) data[5]; |
106 +----------------------------------------------------------------------------+
107 | Output Parameters : - |
108 +----------------------------------------------------------------------------+
109 | Return Value : 0: No error |
110 | -1: The handle parameter of the board is wrong |
111 | -2: The module parameter is wrong |
112 | -3: The module is not a SSI module |
113 | -4: The selected SSI profile length is wrong |
114 | -5: The selected SSI position data length is wrong |
115 | -6: The selected SSI turn counter data length is wrong |
116 | -7: The selected PCI input clock is wrong |
117 | -8: The selected SSI output clock is wrong |
118 | -9: The selected SSI counting mode parameter is wrong |
119 +----------------------------------------------------------------------------+
120 */
121 
123  struct comedi_insn *insn, unsigned int *data)
124 {
125  int i_ReturnValue = 0;
126  unsigned int ui_TimerValue;
127  unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
128  b_PCIInputClock, b_SSICountingMode;
129  unsigned int ul_SSIOutputClock;
130 
131  b_ModulNbr = CR_AREF(insn->chanspec);
132  b_SSIProfile = (unsigned char) data[0];
133  b_PositionTurnLength = (unsigned char) data[1];
134  b_TurnCptLength = (unsigned char) data[2];
135  b_PCIInputClock = (unsigned char) data[3];
136  ul_SSIOutputClock = (unsigned int) data[4];
137  b_SSICountingMode = (unsigned char) data[5];
138 
139  i_ReturnValue = insn->n;
140  /**************************/
141  /* Test the module number */
142  /**************************/
143 
144  if (b_ModulNbr < 4) {
145  /***********************/
146  /* Test if SSI counter */
147  /***********************/
148 
149  if ((devpriv->s_BoardInfos.
150  dw_MolduleConfiguration[b_ModulNbr] &
151  0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
152  /*******************************/
153  /* Test the SSI profile length */
154  /*******************************/
155 
156  /* CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2 */
157  if (b_SSIProfile >= 2 && b_SSIProfile < 33) {
158  /*************************************/
159  /* Test the SSI position data length */
160  /*************************************/
161 
162  if (b_PositionTurnLength > 0
163  && b_PositionTurnLength < 32) {
164  /*****************************************/
165  /* Test the SSI turn counter data length */
166  /*****************************************/
167 
168  if (b_TurnCptLength > 0
169  && b_TurnCptLength < 32) {
170  /***************************/
171  /* Test the profile length */
172  /***************************/
173 
174  if ((b_TurnCptLength +
175  b_PositionTurnLength)
176  <= b_SSIProfile) {
177  /****************************/
178  /* Test the PCI input clock */
179  /****************************/
180 
181  if (b_PCIInputClock ==
183  ||
184  b_PCIInputClock
185  ==
187  {
188  /*************************/
189  /* Test the output clock */
190  /*************************/
191 
192  if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) {
193  if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) {
194  /**********************/
195  /* Save configuration */
196  /**********************/
197  devpriv->
198  s_ModuleInfo
199  [b_ModulNbr].
200  s_SSICounterInfo.
201  b_SSIProfile
202  =
203  b_SSIProfile;
204 
205  devpriv->
206  s_ModuleInfo
207  [b_ModulNbr].
208  s_SSICounterInfo.
209  b_PositionTurnLength
210  =
211  b_PositionTurnLength;
212 
213  devpriv->
214  s_ModuleInfo
215  [b_ModulNbr].
216  s_SSICounterInfo.
217  b_TurnCptLength
218  =
219  b_TurnCptLength;
220 
221  /*********************************/
222  /* Initialise the profile length */
223  /*********************************/
224 
225  if (b_SSICountingMode == APCI1710_BINARY_MODE) {
226 
227  outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
228  } else {
229 
230  outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
231  }
232 
233  /******************************/
234  /* Calculate the output clock */
235  /******************************/
236 
237  ui_TimerValue
238  =
239  (unsigned int)
240  (
241  ((unsigned int) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);
242 
243  /************************/
244  /* Initialise the timer */
245  /************************/
246 
247  outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
248 
249  /********************************/
250  /* Initialise the counting mode */
251  /********************************/
252 
253  outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
254 
255  devpriv->
256  s_ModuleInfo
257  [b_ModulNbr].
258  s_SSICounterInfo.
259  b_SSIInit
260  =
261  1;
262  } else {
263  /*****************************************************/
264  /* The selected SSI counting mode parameter is wrong */
265  /*****************************************************/
266 
267  DPRINTK("The selected SSI counting mode parameter is wrong\n");
268  i_ReturnValue
269  =
270  -9;
271  }
272  } else {
273  /******************************************/
274  /* The selected SSI output clock is wrong */
275  /******************************************/
276 
277  DPRINTK("The selected SSI output clock is wrong\n");
278  i_ReturnValue
279  =
280  -8;
281  }
282  } else {
283  /*****************************************/
284  /* The selected PCI input clock is wrong */
285  /*****************************************/
286 
287  DPRINTK("The selected PCI input clock is wrong\n");
288  i_ReturnValue =
289  -7;
290  }
291  } else {
292  /********************************************/
293  /* The selected SSI profile length is wrong */
294  /********************************************/
295 
296  DPRINTK("The selected SSI profile length is wrong\n");
297  i_ReturnValue = -4;
298  }
299  } else {
300  /******************************************************/
301  /* The selected SSI turn counter data length is wrong */
302  /******************************************************/
303 
304  DPRINTK("The selected SSI turn counter data length is wrong\n");
305  i_ReturnValue = -6;
306  }
307  } else {
308  /**************************************************/
309  /* The selected SSI position data length is wrong */
310  /**************************************************/
311 
312  DPRINTK("The selected SSI position data length is wrong\n");
313  i_ReturnValue = -5;
314  }
315  } else {
316  /********************************************/
317  /* The selected SSI profile length is wrong */
318  /********************************************/
319 
320  DPRINTK("The selected SSI profile length is wrong\n");
321  i_ReturnValue = -4;
322  }
323  } else {
324  /**********************************/
325  /* The module is not a SSI module */
326  /**********************************/
327 
328  DPRINTK("The module is not a SSI module\n");
329  i_ReturnValue = -3;
330  }
331  } else {
332  /***********************/
333  /* Module number error */
334  /***********************/
335 
336  DPRINTK("Module number error\n");
337  i_ReturnValue = -2;
338  }
339 
340  return i_ReturnValue;
341 }
342 
343 /*
344 +----------------------------------------------------------------------------+
345 | Function Name : _INT_ i_APCI1710_Read1SSIValue |
346 | (unsigned char_ b_BoardHandle, |
347 | unsigned char_ b_ModulNbr, |
348 | unsigned char_ b_SelectedSSI, |
349 | PULONG_ pul_Position, |
350 | PULONG_ pul_TurnCpt)
351  int i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
352  struct comedi_insn *insn,unsigned int *data) |
353 +----------------------------------------------------------------------------+
354 | Task :
355 
356 
357  Read the selected SSI counter (b_SelectedSSI) from |
358 | selected module (b_ModulNbr).
359  or Read all SSI counter (b_SelectedSSI) from |
360 | selected module (b_ModulNbr). |
361 +----------------------------------------------------------------------------+
362 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
363 | unsigned char_ b_ModulNbr : Module number to |
364 | configure (0 to 3) |
365 | unsigned char_ b_SelectedSSI : Selection from SSI |
366 | counter (0 to 2)
367 
368  b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
369  b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec); (in case of single ssi)
370  b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);
371 |
372 +----------------------------------------------------------------------------+
373 | Output Parameters : PULONG_ pul_Position : SSI position in the turn |
374 | PULONG_ pul_TurnCpt : Number of turns
375 
376 pul_Position = (unsigned int *) &data[0];
377  pul_TurnCpt = (unsigned int *) &data[1]; |
378 +----------------------------------------------------------------------------+
379 | Return Value : 0: No error |
380 | -1: The handle parameter of the board is wrong |
381 | -2: The module parameter is wrong |
382 | -3: The module is not a SSI module |
383 | -4: SSI not initialised see function |
384 | "i_APCI1710_InitSSI" |
385 | -5: The selected SSI is wrong |
386 +----------------------------------------------------------------------------+
387 */
388 
390  struct comedi_insn *insn, unsigned int *data)
391 {
392  int i_ReturnValue = 0;
393  unsigned char b_Cpt;
394  unsigned char b_Length;
395  unsigned char b_Schift;
396  unsigned char b_SSICpt;
397  unsigned int dw_And;
398  unsigned int dw_And1;
399  unsigned int dw_And2;
400  unsigned int dw_StatusReg;
401  unsigned int dw_CounterValue;
402  unsigned char b_ModulNbr;
403  unsigned char b_SelectedSSI;
404  unsigned char b_ReadType;
405  unsigned int *pul_Position;
406  unsigned int *pul_TurnCpt;
407  unsigned int *pul_Position1;
408  unsigned int *pul_TurnCpt1;
409 
410  i_ReturnValue = insn->n;
411  pul_Position1 = (unsigned int *) &data[0];
412 /* For Read1 */
413  pul_TurnCpt1 = (unsigned int *) &data[1];
414 /* For Read all */
415  pul_Position = (unsigned int *) &data[0]; /* 0-2 */
416  pul_TurnCpt = (unsigned int *) &data[3]; /* 3-5 */
417  b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
418  b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec);
419  b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);
420 
421  /**************************/
422  /* Test the module number */
423  /**************************/
424 
425  if (b_ModulNbr < 4) {
426  /***********************/
427  /* Test if SSI counter */
428  /***********************/
429 
430  if ((devpriv->s_BoardInfos.
431  dw_MolduleConfiguration[b_ModulNbr] &
432  0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
433  /***************************/
434  /* Test if SSI initialised */
435  /***************************/
436 
437  if (devpriv->s_ModuleInfo[b_ModulNbr].
438  s_SSICounterInfo.b_SSIInit == 1) {
439 
440  switch (b_ReadType) {
441 
443  /****************************************/
444  /* Test the selected SSI counter number */
445  /****************************************/
446 
447  if (b_SelectedSSI < 3) {
448  /************************/
449  /* Start the conversion */
450  /************************/
451 
452  outl(0, devpriv->s_BoardInfos.
453  ui_Address + 8 +
454  (64 * b_ModulNbr));
455 
456  do {
457  /*******************/
458  /* Read the status */
459  /*******************/
460 
461  dw_StatusReg =
462  inl(devpriv->
463  s_BoardInfos.
464  ui_Address +
465  (64 * b_ModulNbr));
466  } while ((dw_StatusReg & 0x1)
467  != 0);
468 
469  /******************************/
470  /* Read the SSI counter value */
471  /******************************/
472 
473  dw_CounterValue =
474  inl(devpriv->
475  s_BoardInfos.
476  ui_Address + 4 +
477  (b_SelectedSSI * 4) +
478  (64 * b_ModulNbr));
479 
480  b_Length =
481  devpriv->
482  s_ModuleInfo
483  [b_ModulNbr].
484  s_SSICounterInfo.
485  b_SSIProfile / 2;
486 
487  if ((b_Length * 2) !=
488  devpriv->
489  s_ModuleInfo
490  [b_ModulNbr].
491  s_SSICounterInfo.
492  b_SSIProfile) {
493  b_Length++;
494  }
495 
496  b_Schift =
497  b_Length -
498  devpriv->
499  s_ModuleInfo
500  [b_ModulNbr].
501  s_SSICounterInfo.
502  b_PositionTurnLength;
503 
504  *pul_Position1 =
505  dw_CounterValue >>
506  b_Schift;
507 
508  dw_And = 1;
509 
510  for (b_Cpt = 0;
511  b_Cpt <
512  devpriv->
513  s_ModuleInfo
514  [b_ModulNbr].
515  s_SSICounterInfo.
516  b_PositionTurnLength;
517  b_Cpt++) {
518  dw_And = dw_And * 2;
519  }
520 
521  *pul_Position1 =
522  *pul_Position1 &
523  ((dw_And) - 1);
524 
525  *pul_TurnCpt1 =
526  dw_CounterValue >>
527  b_Length;
528 
529  dw_And = 1;
530 
531  for (b_Cpt = 0;
532  b_Cpt <
533  devpriv->
534  s_ModuleInfo
535  [b_ModulNbr].
536  s_SSICounterInfo.
537  b_TurnCptLength;
538  b_Cpt++) {
539  dw_And = dw_And * 2;
540  }
541 
542  *pul_TurnCpt1 =
543  *pul_TurnCpt1 &
544  ((dw_And) - 1);
545  } else {
546  /*****************************/
547  /* The selected SSI is wrong */
548  /*****************************/
549 
550  DPRINTK("The selected SSI is wrong\n");
551  i_ReturnValue = -5;
552  }
553  break;
554 
556  dw_And1 = 1;
557 
558  for (b_Cpt = 0;
559  b_Cpt <
560  devpriv->
561  s_ModuleInfo[b_ModulNbr].
562  s_SSICounterInfo.
563  b_PositionTurnLength; b_Cpt++) {
564  dw_And1 = dw_And1 * 2;
565  }
566 
567  dw_And2 = 1;
568 
569  for (b_Cpt = 0;
570  b_Cpt <
571  devpriv->
572  s_ModuleInfo[b_ModulNbr].
573  s_SSICounterInfo.
574  b_TurnCptLength; b_Cpt++) {
575  dw_And2 = dw_And2 * 2;
576  }
577 
578  /************************/
579  /* Start the conversion */
580  /************************/
581 
582  outl(0, devpriv->s_BoardInfos.
583  ui_Address + 8 +
584  (64 * b_ModulNbr));
585 
586  do {
587  /*******************/
588  /* Read the status */
589  /*******************/
590 
591  dw_StatusReg =
592  inl(devpriv->
593  s_BoardInfos.
594  ui_Address +
595  (64 * b_ModulNbr));
596  } while ((dw_StatusReg & 0x1) != 0);
597 
598  for (b_SSICpt = 0; b_SSICpt < 3;
599  b_SSICpt++) {
600  /******************************/
601  /* Read the SSI counter value */
602  /******************************/
603 
604  dw_CounterValue =
605  inl(devpriv->
606  s_BoardInfos.
607  ui_Address + 4 +
608  (b_SSICpt * 4) +
609  (64 * b_ModulNbr));
610 
611  b_Length =
612  devpriv->
613  s_ModuleInfo
614  [b_ModulNbr].
615  s_SSICounterInfo.
616  b_SSIProfile / 2;
617 
618  if ((b_Length * 2) !=
619  devpriv->
620  s_ModuleInfo
621  [b_ModulNbr].
622  s_SSICounterInfo.
623  b_SSIProfile) {
624  b_Length++;
625  }
626 
627  b_Schift =
628  b_Length -
629  devpriv->
630  s_ModuleInfo
631  [b_ModulNbr].
632  s_SSICounterInfo.
633  b_PositionTurnLength;
634 
635  pul_Position[b_SSICpt] =
636  dw_CounterValue >>
637  b_Schift;
638  pul_Position[b_SSICpt] =
639  pul_Position[b_SSICpt] &
640  ((dw_And1) - 1);
641 
642  pul_TurnCpt[b_SSICpt] =
643  dw_CounterValue >>
644  b_Length;
645  pul_TurnCpt[b_SSICpt] =
646  pul_TurnCpt[b_SSICpt] &
647  ((dw_And2) - 1);
648  }
649  break;
650 
651  default:
652  printk("Read Type Inputs Wrong\n");
653 
654  } /* switch ending */
655 
656  } else {
657  /***********************/
658  /* SSI not initialised */
659  /***********************/
660 
661  DPRINTK("SSI not initialised\n");
662  i_ReturnValue = -4;
663  }
664  } else {
665  /**********************************/
666  /* The module is not a SSI module */
667  /**********************************/
668 
669  DPRINTK("The module is not a SSI module\n");
670  i_ReturnValue = -3;
671 
672  }
673  } else {
674  /***********************/
675  /* Module number error */
676  /***********************/
677 
678  DPRINTK("Module number error\n");
679  i_ReturnValue = -2;
680  }
681 
682  return i_ReturnValue;
683 }
684 
685 /*
686 +----------------------------------------------------------------------------+
687 | Function Name : _INT_ i_APCI1710_ReadSSI1DigitalInput |
688 | (unsigned char_ b_BoardHandle, |
689 | unsigned char_ b_ModulNbr, |
690 | unsigned char_ b_InputChannel, |
691 | unsigned char *_ pb_ChannelStatus) |
692 +----------------------------------------------------------------------------+
693 | Task :
694  (0) Set the digital output from selected SSI moule |
695 | (b_ModuleNbr) ON
696  (1) Set the digital output from selected SSI moule |
697 | (b_ModuleNbr) OFF
698  (2)Read the status from selected SSI digital input |
699 | (b_InputChannel)
700  (3)Read the status from all SSI digital inputs from |
701 | selected SSI module (b_ModulNbr) |
702 +----------------------------------------------------------------------------+
703 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
704 | unsigned char_ b_ModulNbr CR_AREF : Module number to |
705 | configure (0 to 3) |
706 | unsigned char_ b_InputChannel CR_CHAN : Selection from digital |
707 | data[0] which IOTYPE input ( 0 to 2) |
708 +----------------------------------------------------------------------------+
709 | Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel |
710 | data[0] status |
711 | 0 : Channle is not active|
712 | 1 : Channle is active |
713 +----------------------------------------------------------------------------+
714 | Return Value : 0: No error |
715 | -1: The handle parameter of the board is wrong |
716 | -2: The module parameter is wrong |
717 | -3: The module is not a SSI module |
718 | -4: The selected SSI digital input is wrong |
719 +----------------------------------------------------------------------------+
720 */
721 
723  struct comedi_insn *insn, unsigned int *data)
724 {
725  int i_ReturnValue = 0;
726  unsigned int dw_StatusReg;
727  unsigned char b_ModulNbr;
728  unsigned char b_InputChannel;
729  unsigned char *pb_ChannelStatus;
730  unsigned char *pb_InputStatus;
731  unsigned char b_IOType;
732  i_ReturnValue = insn->n;
733  b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
734  b_IOType = (unsigned char) data[0];
735 
736  /**************************/
737  /* Test the module number */
738  /**************************/
739 
740  if (b_ModulNbr < 4) {
741  /***********************/
742  /* Test if SSI counter */
743  /***********************/
744 
745  if ((devpriv->s_BoardInfos.
746  dw_MolduleConfiguration[b_ModulNbr] &
747  0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
748  switch (b_IOType) {
750  /*****************************/
751  /* Set the digital output ON */
752  /*****************************/
753 
754  outl(1, devpriv->s_BoardInfos.ui_Address + 16 +
755  (64 * b_ModulNbr));
756  break;
757 
759  /******************************/
760  /* Set the digital output OFF */
761  /******************************/
762 
763  outl(0, devpriv->s_BoardInfos.ui_Address + 16 +
764  (64 * b_ModulNbr));
765  break;
766 
768  /******************************************/
769  /* Test the digital imnput channel number */
770  /******************************************/
771 
772  b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec);
773  pb_ChannelStatus = (unsigned char *) &data[0];
774 
775  if (b_InputChannel <= 2) {
776  /**************************/
777  /* Read all digital input */
778  /**************************/
779 
780  dw_StatusReg =
781  inl(devpriv->s_BoardInfos.
782  ui_Address + (64 * b_ModulNbr));
783  *pb_ChannelStatus =
784  (unsigned char) (((~dw_StatusReg) >> (4 +
785  b_InputChannel))
786  & 1);
787  } else {
788  /********************************/
789  /* Selected digital input error */
790  /********************************/
791 
792  DPRINTK("Selected digital input error\n");
793  i_ReturnValue = -4;
794  }
795  break;
796 
798  /**************************/
799  /* Read all digital input */
800  /**************************/
801  pb_InputStatus = (unsigned char *) &data[0];
802 
803  dw_StatusReg =
804  inl(devpriv->s_BoardInfos.ui_Address +
805  (64 * b_ModulNbr));
806  *pb_InputStatus =
807  (unsigned char) (((~dw_StatusReg) >> 4) & 7);
808  break;
809 
810  default:
811  printk("IO type wrong\n");
812 
813  } /* switch end */
814  } else {
815  /**********************************/
816  /* The module is not a SSI module */
817  /**********************************/
818 
819  DPRINTK("The module is not a SSI module\n");
820  i_ReturnValue = -3;
821  }
822  } else {
823  /***********************/
824  /* Module number error */
825  /***********************/
826 
827  DPRINTK("Module number error\n");
828  i_ReturnValue = -2;
829  }
830 
831  return i_ReturnValue;
832 }