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