Staging: comedi: Remove C99 comments
[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 |
1783fbfe
BP
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, |
c995fe94 74| ULONG_ ul_SSIOutputClock, |
1783fbfe 75| unsigned char_ b_SSICountingMode) |
c995fe94
ADG
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+----------------------------------------------------------------------------+
1783fbfe
BP
81| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
82| unsigned char_ b_ModulNbr : Module number to |
c995fe94 83| configure (0 to 3) |
1783fbfe 84| unsigned char_ b_SSIProfile : Selection from SSI |
c995fe94 85| profile length (2 to 32).|
1783fbfe 86| unsigned char_ b_PositionTurnLength : Selection from SSI |
c995fe94
ADG
87| position data length |
88| (1 to 31). |
1783fbfe 89| unsigned char_ b_TurnCptLength : Selection from SSI turn |
c995fe94
ADG
90| counter data length |
91| (1 to 31). |
1783fbfe 92| unsigned char b_PCIInputClock : Selection from PCI bus |
c995fe94
ADG
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. |
1783fbfe 106| unsigned char b_SSICountingMode : SSI counting mode |
c995fe94
ADG
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);
1783fbfe
BP
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];
82a6e2e7 118 ul_SSIOutputClock = (unsigned int) data[4];
1783fbfe 119 b_SSICountingMode = (unsigned char) data[5]; |
c995fe94
ADG
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
74b894e5 136int i_APCI1710_InsnConfigInitSSI(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 137 struct comedi_insn * insn, unsigned int * data)
c995fe94 138{
74b894e5 139 int i_ReturnValue = 0;
117102b0 140 unsigned int ui_TimerValue;
1783fbfe 141 unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
c995fe94 142 b_PCIInputClock, b_SSICountingMode;
82a6e2e7 143 unsigned int ul_SSIOutputClock;
c995fe94
ADG
144
145 b_ModulNbr = CR_AREF(insn->chanspec);
1783fbfe
BP
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];
82a6e2e7 150 ul_SSIOutputClock = (unsigned int) data[4];
1783fbfe 151 b_SSICountingMode = (unsigned char) data[5];
c995fe94
ADG
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
2696fb57 170 /* CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2 */
c995fe94
ADG
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 =
117102b0 253 (unsigned int)
c995fe94 254 (
82a6e2e7 255 ((unsigned int) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);
c995fe94
ADG
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 |
1783fbfe
BP
360| (unsigned char_ b_BoardHandle, |
361| unsigned char_ b_ModulNbr, |
362| unsigned char_ b_SelectedSSI, |
c995fe94
ADG
363| PULONG_ pul_Position, |
364| PULONG_ pul_TurnCpt)
74b894e5 365 int i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
90035c08 366 struct 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+----------------------------------------------------------------------------+
1783fbfe
BP
376| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
377| unsigned char_ b_ModulNbr : Module number to |
c995fe94 378| configure (0 to 3) |
1783fbfe 379| unsigned char_ b_SelectedSSI : Selection from SSI |
c995fe94
ADG
380| counter (0 to 2)
381
1783fbfe
BP
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);
c995fe94
ADG
385|
386+----------------------------------------------------------------------------+
387| Output Parameters : PULONG_ pul_Position : SSI position in the turn |
388| PULONG_ pul_TurnCpt : Number of turns
389
82a6e2e7
BP
390pul_Position = (unsigned int *) &data[0];
391 pul_TurnCpt = (unsigned int *) &data[1]; |
c995fe94
ADG
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
74b894e5 403int i_APCI1710_InsnReadSSIValue(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 404 struct comedi_insn * insn, unsigned int * data)
c995fe94 405{
74b894e5 406 int i_ReturnValue = 0;
1783fbfe
BP
407 unsigned char b_Cpt;
408 unsigned char b_Length;
409 unsigned char b_Schift;
410 unsigned char b_SSICpt;
756e9d7c
BP
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;
1783fbfe
BP
416 unsigned char b_ModulNbr;
417 unsigned char b_SelectedSSI;
418 unsigned char b_ReadType;
82a6e2e7
BP
419 unsigned int * pul_Position;
420 unsigned int * pul_TurnCpt;
421 unsigned int * pul_Position1;
422 unsigned int * pul_TurnCpt1;
c995fe94
ADG
423
424 i_ReturnValue = insn->n;
82a6e2e7 425 pul_Position1 = (unsigned int *) & data[0];
2696fb57 426/* For Read1 */
82a6e2e7 427 pul_TurnCpt1 = (unsigned int *) & data[1];
2696fb57
BP
428/* For Read all */
429 pul_Position = (unsigned int *) & data[0]; /* 0-2 */
430 pul_TurnCpt = (unsigned int *) & data[3]; /* 3-5 */
1783fbfe
BP
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);
c995fe94
ADG
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
2696fb57 670 } /* switch ending */
c995fe94
ADG
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 |
1783fbfe
BP
704| (unsigned char_ b_BoardHandle, |
705| unsigned char_ b_ModulNbr, |
706| unsigned char_ b_InputChannel, |
707| unsigned char *_ pb_ChannelStatus) |
c995fe94
ADG
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+----------------------------------------------------------------------------+
1783fbfe
BP
719| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710|
720| unsigned char_ b_ModulNbr CR_AREF : Module number to |
c995fe94 721| configure (0 to 3) |
1783fbfe 722| unsigned char_ b_InputChannel CR_CHAN : Selection from digital |
c995fe94
ADG
723| data[0] which IOTYPE input ( 0 to 2) |
724+----------------------------------------------------------------------------+
1783fbfe 725| Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel |
c995fe94
ADG
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
74b894e5 738int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 739 struct comedi_insn * insn, unsigned int * data)
c995fe94 740{
74b894e5 741 int i_ReturnValue = 0;
756e9d7c 742 unsigned int dw_StatusReg;
1783fbfe
BP
743 unsigned char b_ModulNbr;
744 unsigned char b_InputChannel;
745 unsigned char * pb_ChannelStatus;
746 unsigned char * pb_InputStatus;
747 unsigned char b_IOType;
c995fe94 748 i_ReturnValue = insn->n;
1783fbfe
BP
749 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
750 b_IOType = (unsigned char) data[0];
c995fe94
ADG
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
1783fbfe
BP
788 b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec);
789 pb_ChannelStatus = (unsigned char *) & data[0];
c995fe94
ADG
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 =
1783fbfe 800 (unsigned char) (((~dw_StatusReg) >> (4 +
c995fe94
ADG
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 /**************************/
1783fbfe 817 pb_InputStatus = (unsigned char *) & data[0];
c995fe94
ADG
818
819 dw_StatusReg =
820 inl(devpriv->s_BoardInfos.ui_Address +
821 (64 * b_ModulNbr));
822 *pb_InputStatus =
1783fbfe 823 (unsigned char) (((~dw_StatusReg) >> 4) & 7);
c995fe94
ADG
824 break;
825
826 default:
827 printk("IO type wrong\n");
828
2696fb57 829 } /* switch end */
c995fe94
ADG
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}