/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
C | 832 lines | 387 code | 107 blank | 338 comment | 65 complexity | 1701c56b0426f5bfb1ca22a84320ace4 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
1/**
2@verbatim
3
4Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
5
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
13
14This 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.
15
16This 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.
17
18You 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
19
20You should also find the complete GPL in the COPYING file accompanying this source code.
21
22@endverbatim
23*/
24/*
25
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 | 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
122int i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s,
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 ==
182 APCI1710_30MHZ
183 ||
184 b_PCIInputClock
185 ==
186 APCI1710_33MHZ)
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
376pul_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
389int i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s,
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
442 case APCI1710_SSI_READ1VALUE:
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
555 case APCI1710_SSI_READALLVALUE:
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
722int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
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) {
749 case APCI1710_SSI_SET_CHANNELON:
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
758 case APCI1710_SSI_SET_CHANNELOFF:
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
767 case APCI1710_SSI_READ_1CHANNEL:
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
797 case APCI1710_SSI_READ_ALLCHANNEL:
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}