GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / staging / comedi / drivers / addi-data / APCI1710_Ssi.c
blob6360de59e0e98b6844046eebd2b12e172f955ac7
1 /**
2 @verbatim
4 Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
6 ADDI-DATA GmbH
7 Dieselstrasse 3
8 D-77833 Ottersweier
9 Tel: +19(0)7223/9493-0
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data-com
12 info@addi-data.com
14 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 You should also find the complete GPL in the COPYING file accompanying this source code.
22 @endverbatim
26 +-----------------------------------------------------------------------+
27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28 +-----------------------------------------------------------------------+
29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31 +-----------------------------------------------------------------------+
32 | Project : 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 | |
40 +-----------------------------------------------------------------------+
41 | UPDATES |
42 +-----------------------------------------------------------------------+
43 | Date | Author | Description of updates |
44 +----------+-----------+------------------------------------------------+
45 | 13/05/98 | S. Weber | SSI digital input / output implementation |
46 |----------|-----------|------------------------------------------------|
47 | 22/03/00 | C.Guinot | 0100/0226 -> 0200/0227 |
48 | | | Änderung in InitSSI Funktion |
49 | | | b_SSIProfile >= 2 anstatt b_SSIProfile > 2 |
50 | | | |
51 +-----------------------------------------------------------------------+
52 | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
53 | | | available |
54 +-----------------------------------------------------------------------+
58 +----------------------------------------------------------------------------+
59 | Included files |
60 +----------------------------------------------------------------------------+
63 #include "APCI1710_Ssi.h"
66 +----------------------------------------------------------------------------+
67 | Function Name : _INT_ i_APCI1710_InitSSI |
68 | (unsigned char_ b_BoardHandle, |
69 | unsigned char_ b_ModulNbr, |
70 | unsigned char_ b_SSIProfile, |
71 | unsigned char_ b_PositionTurnLength, |
72 | unsigned char_ b_TurnCptLength, |
73 | unsigned char_ b_PCIInputClock, |
74 | ULONG_ ul_SSIOutputClock, |
75 | unsigned char_ b_SSICountingMode) |
76 +----------------------------------------------------------------------------+
77 | Task : Configure the SSI operating mode from selected module |
78 | (b_ModulNbr). You must calling this function be for you|
79 | call any other function witch access of SSI. |
80 +----------------------------------------------------------------------------+
81 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
82 | unsigned char_ b_ModulNbr : Module number to |
83 | configure (0 to 3) |
84 | unsigned char_ b_SSIProfile : Selection from SSI |
85 | profile length (2 to 32).|
86 | unsigned char_ b_PositionTurnLength : Selection from SSI |
87 | position data length |
88 | (1 to 31). |
89 | unsigned char_ b_TurnCptLength : Selection from SSI turn |
90 | counter data length |
91 | (1 to 31). |
92 | unsigned char b_PCIInputClock : Selection from PCI bus |
93 | clock |
94 | - APCI1710_30MHZ : |
95 | The PC have a PCI bus |
96 | clock from 30 MHz |
97 | - APCI1710_33MHZ : |
98 | The PC have a PCI bus |
99 | clock from 33 MHz |
100 | ULONG_ ul_SSIOutputClock : Selection from SSI output|
101 | clock. |
102 | From 229 to 5 000 000 Hz|
103 | for 30 MHz selection. |
104 | From 252 to 5 000 000 Hz|
105 | for 33 MHz selection. |
106 | unsigned char b_SSICountingMode : SSI counting mode |
107 | selection |
108 | - APCI1710_BINARY_MODE : |
109 | Binary counting mode. |
110 | - APCI1710_GRAY_MODE : |
111 | Gray counting mode.
113 b_ModulNbr = CR_AREF(insn->chanspec);
114 b_SSIProfile = (unsigned char) data[0];
115 b_PositionTurnLength= (unsigned char) data[1];
116 b_TurnCptLength = (unsigned char) data[2];
117 b_PCIInputClock = (unsigned char) data[3];
118 ul_SSIOutputClock = (unsigned int) data[4];
119 b_SSICountingMode = (unsigned char) data[5]; |
120 +----------------------------------------------------------------------------+
121 | Output Parameters : - |
122 +----------------------------------------------------------------------------+
123 | Return Value : 0: No error |
124 | -1: The handle parameter of the board is wrong |
125 | -2: The module parameter is wrong |
126 | -3: The module is not a SSI module |
127 | -4: The selected SSI profile length is wrong |
128 | -5: The selected SSI position data length is wrong |
129 | -6: The selected SSI turn counter data length is wrong |
130 | -7: The selected PCI input clock is wrong |
131 | -8: The selected SSI output clock is wrong |
132 | -9: The selected SSI counting mode parameter is wrong |
133 +----------------------------------------------------------------------------+
136 int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s,
137 struct comedi_insn *insn, unsigned int *data)
139 int i_ReturnValue = 0;
140 unsigned int ui_TimerValue;
141 unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
142 b_PCIInputClock, b_SSICountingMode;
143 unsigned int ul_SSIOutputClock;
145 b_ModulNbr = CR_AREF(insn->chanspec);
146 b_SSIProfile = (unsigned char) data[0];
147 b_PositionTurnLength = (unsigned char) data[1];
148 b_TurnCptLength = (unsigned char) data[2];
149 b_PCIInputClock = (unsigned char) data[3];
150 ul_SSIOutputClock = (unsigned int) data[4];
151 b_SSICountingMode = (unsigned char) data[5];
153 i_ReturnValue = insn->n;
154 /**************************/
155 /* Test the module number */
156 /**************************/
158 if (b_ModulNbr < 4) {
159 /***********************/
160 /* Test if SSI counter */
161 /***********************/
163 if ((devpriv->s_BoardInfos.
164 dw_MolduleConfiguration[b_ModulNbr] &
165 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
166 /*******************************/
167 /* Test the SSI profile length */
168 /*******************************/
170 /* CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2 */
171 if (b_SSIProfile >= 2 && b_SSIProfile < 33) {
172 /*************************************/
173 /* Test the SSI position data length */
174 /*************************************/
176 if (b_PositionTurnLength > 0
177 && b_PositionTurnLength < 32) {
178 /*****************************************/
179 /* Test the SSI turn counter data length */
180 /*****************************************/
182 if (b_TurnCptLength > 0
183 && b_TurnCptLength < 32) {
184 /***************************/
185 /* Test the profile length */
186 /***************************/
188 if ((b_TurnCptLength +
189 b_PositionTurnLength)
190 <= b_SSIProfile) {
191 /****************************/
192 /* Test the PCI input clock */
193 /****************************/
195 if (b_PCIInputClock ==
196 APCI1710_30MHZ
198 b_PCIInputClock
200 APCI1710_33MHZ)
202 /*************************/
203 /* Test the output clock */
204 /*************************/
206 if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) {
207 if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) {
208 /**********************/
209 /* Save configuration */
210 /**********************/
211 devpriv->
212 s_ModuleInfo
213 [b_ModulNbr].
214 s_SSICounterInfo.
215 b_SSIProfile
217 b_SSIProfile;
219 devpriv->
220 s_ModuleInfo
221 [b_ModulNbr].
222 s_SSICounterInfo.
223 b_PositionTurnLength
225 b_PositionTurnLength;
227 devpriv->
228 s_ModuleInfo
229 [b_ModulNbr].
230 s_SSICounterInfo.
231 b_TurnCptLength
233 b_TurnCptLength;
235 /*********************************/
236 /* Initialise the profile length */
237 /*********************************/
239 if (b_SSICountingMode == APCI1710_BINARY_MODE) {
241 outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
242 } else {
244 outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
247 /******************************/
248 /* Calculate the output clock */
249 /******************************/
251 ui_TimerValue
253 (unsigned int)
255 ((unsigned int) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);
257 /************************/
258 /* Initialise the timer */
259 /************************/
261 outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
263 /********************************/
264 /* Initialise the counting mode */
265 /********************************/
267 outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
269 devpriv->
270 s_ModuleInfo
271 [b_ModulNbr].
272 s_SSICounterInfo.
273 b_SSIInit
276 } else {
277 /*****************************************************/
278 /* The selected SSI counting mode parameter is wrong */
279 /*****************************************************/
281 DPRINTK("The selected SSI counting mode parameter is wrong\n");
282 i_ReturnValue
286 } else {
287 /******************************************/
288 /* The selected SSI output clock is wrong */
289 /******************************************/
291 DPRINTK("The selected SSI output clock is wrong\n");
292 i_ReturnValue
296 } else {
297 /*****************************************/
298 /* The selected PCI input clock is wrong */
299 /*****************************************/
301 DPRINTK("The selected PCI input clock is wrong\n");
302 i_ReturnValue =
305 } else {
306 /********************************************/
307 /* The selected SSI profile length is wrong */
308 /********************************************/
310 DPRINTK("The selected SSI profile length is wrong\n");
311 i_ReturnValue = -4;
313 } else {
314 /******************************************************/
315 /* The selected SSI turn counter data length is wrong */
316 /******************************************************/
318 DPRINTK("The selected SSI turn counter data length is wrong\n");
319 i_ReturnValue = -6;
321 } else {
322 /**************************************************/
323 /* The selected SSI position data length is wrong */
324 /**************************************************/
326 DPRINTK("The selected SSI position data length is wrong\n");
327 i_ReturnValue = -5;
329 } else {
330 /********************************************/
331 /* The selected SSI profile length is wrong */
332 /********************************************/
334 DPRINTK("The selected SSI profile length is wrong\n");
335 i_ReturnValue = -4;
337 } else {
338 /**********************************/
339 /* The module is not a SSI module */
340 /**********************************/
342 DPRINTK("The module is not a SSI module\n");
343 i_ReturnValue = -3;
345 } else {
346 /***********************/
347 /* Module number error */
348 /***********************/
350 DPRINTK("Module number error\n");
351 i_ReturnValue = -2;
354 return i_ReturnValue;
358 +----------------------------------------------------------------------------+
359 | Function Name : _INT_ i_APCI1710_Read1SSIValue |
360 | (unsigned char_ b_BoardHandle, |
361 | unsigned char_ b_ModulNbr, |
362 | unsigned char_ b_SelectedSSI, |
363 | PULONG_ pul_Position, |
364 | PULONG_ pul_TurnCpt)
365 int i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
366 struct comedi_insn *insn,unsigned int *data) |
367 +----------------------------------------------------------------------------+
368 | Task :
371 Read the selected SSI counter (b_SelectedSSI) from |
372 | selected module (b_ModulNbr).
373 or Read all SSI counter (b_SelectedSSI) from |
374 | selected module (b_ModulNbr). |
375 +----------------------------------------------------------------------------+
376 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
377 | unsigned char_ b_ModulNbr : Module number to |
378 | configure (0 to 3) |
379 | unsigned char_ b_SelectedSSI : Selection from SSI |
380 | counter (0 to 2)
382 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
383 b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec); (in case of single ssi)
384 b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);
386 +----------------------------------------------------------------------------+
387 | Output Parameters : PULONG_ pul_Position : SSI position in the turn |
388 | PULONG_ pul_TurnCpt : Number of turns
390 pul_Position = (unsigned int *) &data[0];
391 pul_TurnCpt = (unsigned int *) &data[1]; |
392 +----------------------------------------------------------------------------+
393 | Return Value : 0: No error |
394 | -1: The handle parameter of the board is wrong |
395 | -2: The module parameter is wrong |
396 | -3: The module is not a SSI module |
397 | -4: SSI not initialised see function |
398 | "i_APCI1710_InitSSI" |
399 | -5: The selected SSI is wrong |
400 +----------------------------------------------------------------------------+
403 int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s,
404 struct comedi_insn *insn, unsigned int *data)
406 int i_ReturnValue = 0;
407 unsigned char b_Cpt;
408 unsigned char b_Length;
409 unsigned char b_Schift;
410 unsigned char b_SSICpt;
411 unsigned int dw_And;
412 unsigned int dw_And1;
413 unsigned int dw_And2;
414 unsigned int dw_StatusReg;
415 unsigned int dw_CounterValue;
416 unsigned char b_ModulNbr;
417 unsigned char b_SelectedSSI;
418 unsigned char b_ReadType;
419 unsigned int *pul_Position;
420 unsigned int *pul_TurnCpt;
421 unsigned int *pul_Position1;
422 unsigned int *pul_TurnCpt1;
424 i_ReturnValue = insn->n;
425 pul_Position1 = (unsigned int *) &data[0];
426 /* For Read1 */
427 pul_TurnCpt1 = (unsigned int *) &data[1];
428 /* For Read all */
429 pul_Position = (unsigned int *) &data[0]; /* 0-2 */
430 pul_TurnCpt = (unsigned int *) &data[3]; /* 3-5 */
431 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
432 b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec);
433 b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);
435 /**************************/
436 /* Test the module number */
437 /**************************/
439 if (b_ModulNbr < 4) {
440 /***********************/
441 /* Test if SSI counter */
442 /***********************/
444 if ((devpriv->s_BoardInfos.
445 dw_MolduleConfiguration[b_ModulNbr] &
446 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
447 /***************************/
448 /* Test if SSI initialised */
449 /***************************/
451 if (devpriv->s_ModuleInfo[b_ModulNbr].
452 s_SSICounterInfo.b_SSIInit == 1) {
454 switch (b_ReadType) {
456 case APCI1710_SSI_READ1VALUE:
457 /****************************************/
458 /* Test the selected SSI counter number */
459 /****************************************/
461 if (b_SelectedSSI < 3) {
462 /************************/
463 /* Start the conversion */
464 /************************/
466 outl(0, devpriv->s_BoardInfos.
467 ui_Address + 8 +
468 (64 * b_ModulNbr));
470 do {
471 /*******************/
472 /* Read the status */
473 /*******************/
475 dw_StatusReg =
476 inl(devpriv->
477 s_BoardInfos.
478 ui_Address +
479 (64 * b_ModulNbr));
480 } while ((dw_StatusReg & 0x1)
481 != 0);
483 /******************************/
484 /* Read the SSI counter value */
485 /******************************/
487 dw_CounterValue =
488 inl(devpriv->
489 s_BoardInfos.
490 ui_Address + 4 +
491 (b_SelectedSSI * 4) +
492 (64 * b_ModulNbr));
494 b_Length =
495 devpriv->
496 s_ModuleInfo
497 [b_ModulNbr].
498 s_SSICounterInfo.
499 b_SSIProfile / 2;
501 if ((b_Length * 2) !=
502 devpriv->
503 s_ModuleInfo
504 [b_ModulNbr].
505 s_SSICounterInfo.
506 b_SSIProfile) {
507 b_Length++;
510 b_Schift =
511 b_Length -
512 devpriv->
513 s_ModuleInfo
514 [b_ModulNbr].
515 s_SSICounterInfo.
516 b_PositionTurnLength;
518 *pul_Position1 =
519 dw_CounterValue >>
520 b_Schift;
522 dw_And = 1;
524 for (b_Cpt = 0;
525 b_Cpt <
526 devpriv->
527 s_ModuleInfo
528 [b_ModulNbr].
529 s_SSICounterInfo.
530 b_PositionTurnLength;
531 b_Cpt++) {
532 dw_And = dw_And * 2;
535 *pul_Position1 =
536 *pul_Position1 &
537 ((dw_And) - 1);
539 *pul_TurnCpt1 =
540 dw_CounterValue >>
541 b_Length;
543 dw_And = 1;
545 for (b_Cpt = 0;
546 b_Cpt <
547 devpriv->
548 s_ModuleInfo
549 [b_ModulNbr].
550 s_SSICounterInfo.
551 b_TurnCptLength;
552 b_Cpt++) {
553 dw_And = dw_And * 2;
556 *pul_TurnCpt1 =
557 *pul_TurnCpt1 &
558 ((dw_And) - 1);
559 } else {
560 /*****************************/
561 /* The selected SSI is wrong */
562 /*****************************/
564 DPRINTK("The selected SSI is wrong\n");
565 i_ReturnValue = -5;
567 break;
569 case APCI1710_SSI_READALLVALUE:
570 dw_And1 = 1;
572 for (b_Cpt = 0;
573 b_Cpt <
574 devpriv->
575 s_ModuleInfo[b_ModulNbr].
576 s_SSICounterInfo.
577 b_PositionTurnLength; b_Cpt++) {
578 dw_And1 = dw_And1 * 2;
581 dw_And2 = 1;
583 for (b_Cpt = 0;
584 b_Cpt <
585 devpriv->
586 s_ModuleInfo[b_ModulNbr].
587 s_SSICounterInfo.
588 b_TurnCptLength; b_Cpt++) {
589 dw_And2 = dw_And2 * 2;
592 /************************/
593 /* Start the conversion */
594 /************************/
596 outl(0, devpriv->s_BoardInfos.
597 ui_Address + 8 +
598 (64 * b_ModulNbr));
600 do {
601 /*******************/
602 /* Read the status */
603 /*******************/
605 dw_StatusReg =
606 inl(devpriv->
607 s_BoardInfos.
608 ui_Address +
609 (64 * b_ModulNbr));
610 } while ((dw_StatusReg & 0x1) != 0);
612 for (b_SSICpt = 0; b_SSICpt < 3;
613 b_SSICpt++) {
614 /******************************/
615 /* Read the SSI counter value */
616 /******************************/
618 dw_CounterValue =
619 inl(devpriv->
620 s_BoardInfos.
621 ui_Address + 4 +
622 (b_SSICpt * 4) +
623 (64 * b_ModulNbr));
625 b_Length =
626 devpriv->
627 s_ModuleInfo
628 [b_ModulNbr].
629 s_SSICounterInfo.
630 b_SSIProfile / 2;
632 if ((b_Length * 2) !=
633 devpriv->
634 s_ModuleInfo
635 [b_ModulNbr].
636 s_SSICounterInfo.
637 b_SSIProfile) {
638 b_Length++;
641 b_Schift =
642 b_Length -
643 devpriv->
644 s_ModuleInfo
645 [b_ModulNbr].
646 s_SSICounterInfo.
647 b_PositionTurnLength;
649 pul_Position[b_SSICpt] =
650 dw_CounterValue >>
651 b_Schift;
652 pul_Position[b_SSICpt] =
653 pul_Position[b_SSICpt] &
654 ((dw_And1) - 1);
656 pul_TurnCpt[b_SSICpt] =
657 dw_CounterValue >>
658 b_Length;
659 pul_TurnCpt[b_SSICpt] =
660 pul_TurnCpt[b_SSICpt] &
661 ((dw_And2) - 1);
663 break;
665 default:
666 printk("Read Type Inputs Wrong\n");
668 } /* switch ending */
670 } else {
671 /***********************/
672 /* SSI not initialised */
673 /***********************/
675 DPRINTK("SSI not initialised\n");
676 i_ReturnValue = -4;
678 } else {
679 /**********************************/
680 /* The module is not a SSI module */
681 /**********************************/
683 DPRINTK("The module is not a SSI module\n");
684 i_ReturnValue = -3;
687 } else {
688 /***********************/
689 /* Module number error */
690 /***********************/
692 DPRINTK("Module number error\n");
693 i_ReturnValue = -2;
696 return i_ReturnValue;
700 +----------------------------------------------------------------------------+
701 | Function Name : _INT_ i_APCI1710_ReadSSI1DigitalInput |
702 | (unsigned char_ b_BoardHandle, |
703 | unsigned char_ b_ModulNbr, |
704 | unsigned char_ b_InputChannel, |
705 | unsigned char *_ pb_ChannelStatus) |
706 +----------------------------------------------------------------------------+
707 | Task :
708 (0) Set the digital output from selected SSI moule |
709 | (b_ModuleNbr) ON
710 (1) Set the digital output from selected SSI moule |
711 | (b_ModuleNbr) OFF
712 (2)Read the status from selected SSI digital input |
713 | (b_InputChannel)
714 (3)Read the status from all SSI digital inputs from |
715 | selected SSI module (b_ModulNbr) |
716 +----------------------------------------------------------------------------+
717 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
718 | unsigned char_ b_ModulNbr CR_AREF : Module number to |
719 | configure (0 to 3) |
720 | unsigned char_ b_InputChannel CR_CHAN : Selection from digital |
721 | data[0] which IOTYPE input ( 0 to 2) |
722 +----------------------------------------------------------------------------+
723 | Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel |
724 | data[0] status |
725 | 0 : Channle is not active|
726 | 1 : Channle is active |
727 +----------------------------------------------------------------------------+
728 | Return Value : 0: No error |
729 | -1: The handle parameter of the board is wrong |
730 | -2: The module parameter is wrong |
731 | -3: The module is not a SSI module |
732 | -4: The selected SSI digital input is wrong |
733 +----------------------------------------------------------------------------+
736 int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
737 struct comedi_insn *insn, unsigned int *data)
739 int i_ReturnValue = 0;
740 unsigned int dw_StatusReg;
741 unsigned char b_ModulNbr;
742 unsigned char b_InputChannel;
743 unsigned char *pb_ChannelStatus;
744 unsigned char *pb_InputStatus;
745 unsigned char b_IOType;
746 i_ReturnValue = insn->n;
747 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
748 b_IOType = (unsigned char) data[0];
750 /**************************/
751 /* Test the module number */
752 /**************************/
754 if (b_ModulNbr < 4) {
755 /***********************/
756 /* Test if SSI counter */
757 /***********************/
759 if ((devpriv->s_BoardInfos.
760 dw_MolduleConfiguration[b_ModulNbr] &
761 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
762 switch (b_IOType) {
763 case APCI1710_SSI_SET_CHANNELON:
764 /*****************************/
765 /* Set the digital output ON */
766 /*****************************/
768 outl(1, devpriv->s_BoardInfos.ui_Address + 16 +
769 (64 * b_ModulNbr));
770 break;
772 case APCI1710_SSI_SET_CHANNELOFF:
773 /******************************/
774 /* Set the digital output OFF */
775 /******************************/
777 outl(0, devpriv->s_BoardInfos.ui_Address + 16 +
778 (64 * b_ModulNbr));
779 break;
781 case APCI1710_SSI_READ_1CHANNEL:
782 /******************************************/
783 /* Test the digital imnput channel number */
784 /******************************************/
786 b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec);
787 pb_ChannelStatus = (unsigned char *) &data[0];
789 if (b_InputChannel <= 2) {
790 /**************************/
791 /* Read all digital input */
792 /**************************/
794 dw_StatusReg =
795 inl(devpriv->s_BoardInfos.
796 ui_Address + (64 * b_ModulNbr));
797 *pb_ChannelStatus =
798 (unsigned char) (((~dw_StatusReg) >> (4 +
799 b_InputChannel))
800 & 1);
801 } else {
802 /********************************/
803 /* Selected digital input error */
804 /********************************/
806 DPRINTK("Selected digital input error\n");
807 i_ReturnValue = -4;
809 break;
811 case APCI1710_SSI_READ_ALLCHANNEL:
812 /**************************/
813 /* Read all digital input */
814 /**************************/
815 pb_InputStatus = (unsigned char *) &data[0];
817 dw_StatusReg =
818 inl(devpriv->s_BoardInfos.ui_Address +
819 (64 * b_ModulNbr));
820 *pb_InputStatus =
821 (unsigned char) (((~dw_StatusReg) >> 4) & 7);
822 break;
824 default:
825 printk("IO type wrong\n");
827 } /* switch end */
828 } else {
829 /**********************************/
830 /* The module is not a SSI module */
831 /**********************************/
833 DPRINTK("The module is not a SSI module\n");
834 i_ReturnValue = -3;
836 } else {
837 /***********************/
838 /* Module number error */
839 /***********************/
841 DPRINTK("Module number error\n");
842 i_ReturnValue = -2;
845 return i_ReturnValue;