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