Staging: comedi: Remove C99 comments
[pandora-kernel.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 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 You 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 |                               (unsigned char_    b_BoardHandle,                     |
69 |                                unsigned char_    b_ModulNbr,                        |
70 |                                unsigned char_    b_SSIProfile,                      |
71 |                                unsigned char_    b_PositionTurnLength,              |
72 |                                unsigned char_    b_TurnCptLength,                   |
73 |                                unsigned char_    b_PCIInputClock,                   |
74 |                                ULONG_  ul_SSIOutputClock,                  |
75 |                                unsigned char_    b_SSICountingMode)                 |
76 +----------------------------------------------------------------------------+
77 | Task              : Configure the SSI operating mode from selected module  |
78 |                     (b_ModulNbr). You must calling this function be for you|
79 |                     call any other function witch access of SSI.           |
80 +----------------------------------------------------------------------------+
81 | Input Parameters  : unsigned char_ b_BoardHandle         : Handle of board APCI-1710|
82 |                     unsigned char_ b_ModulNbr            : Module number to         |
83 |                                                   configure (0 to 3)       |
84 |                     unsigned char_  b_SSIProfile         : Selection from SSI       |
85 |                                                   profile length (2 to 32).|
86 |                     unsigned char_  b_PositionTurnLength : Selection from SSI       |
87 |                                                   position data length     |
88 |                                                   (1 to 31).               |
89 |                     unsigned char_  b_TurnCptLength      : Selection from SSI turn  |
90 |                                                   counter data length      |
91 |                                                   (1 to 31).               |
92 |                     unsigned char   b_PCIInputClock      : Selection from PCI bus   |
93 |                                                   clock                    |
94 |                                                 - APCI1710_30MHZ :         |
95 |                                                   The PC have a PCI bus    |
96 |                                                   clock from 30 MHz        |
97 |                                                 - APCI1710_33MHZ :         |
98 |                                                   The PC have a PCI bus    |
99 |                                                   clock from 33 MHz        |
100 |                     ULONG_ ul_SSIOutputClock    : Selection from SSI output|
101 |                                                   clock.                   |
102 |                                                   From  229 to 5 000 000 Hz|
103 |                                                   for 30 MHz selection.    |
104 |                                                   From  252 to 5 000 000 Hz|
105 |                                                   for 33 MHz selection.    |
106 |                     unsigned char   b_SSICountingMode    : SSI counting mode        |
107 |                                                   selection                |
108 |                                                 - APCI1710_BINARY_MODE :   |
109 |                                                    Binary counting mode.   |
110 |                                                 - APCI1710_GRAY_MODE :     |
111 |                                                    Gray counting mode.
112
113         b_ModulNbr                      = CR_AREF(insn->chanspec);
114         b_SSIProfile            = (unsigned char) data[0];
115         b_PositionTurnLength= (unsigned char) data[1];
116         b_TurnCptLength         = (unsigned char) data[2];
117         b_PCIInputClock         = (unsigned char) data[3];
118         ul_SSIOutputClock       = (unsigned int) data[4];
119         b_SSICountingMode       = (unsigned char)  data[5];     |
120 +----------------------------------------------------------------------------+
121 | Output Parameters : -                                                      |
122 +----------------------------------------------------------------------------+
123 | Return Value      : 0: No error                                            |
124 |                    -1: The handle parameter of the board is wrong          |
125 |                    -2: The module parameter is wrong                       |
126 |                    -3: The module is not a SSI module                      |
127 |                    -4: The selected SSI profile length is wrong            |
128 |                    -5: The selected SSI position data length is wrong      |
129 |                    -6: The selected SSI turn counter data length is wrong  |
130 |                    -7: The selected PCI input clock is wrong               |
131 |                    -8: The selected SSI output clock is wrong              |
132 |                    -9: The selected SSI counting mode parameter is wrong   |
133 +----------------------------------------------------------------------------+
134 */
135
136 int i_APCI1710_InsnConfigInitSSI(struct comedi_device * dev, struct comedi_subdevice * s,
137         struct comedi_insn * insn, unsigned int * data)
138 {
139         int i_ReturnValue = 0;
140         unsigned int ui_TimerValue;
141         unsigned char b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
142                 b_PCIInputClock, b_SSICountingMode;
143         unsigned int ul_SSIOutputClock;
144
145         b_ModulNbr = CR_AREF(insn->chanspec);
146         b_SSIProfile = (unsigned char) data[0];
147         b_PositionTurnLength = (unsigned char) data[1];
148         b_TurnCptLength = (unsigned char) data[2];
149         b_PCIInputClock = (unsigned char) data[3];
150         ul_SSIOutputClock = (unsigned int) data[4];
151         b_SSICountingMode = (unsigned char) data[5];
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                                                                                         (unsigned int)
254                                                                                         (
255                                                                                         ((unsigned int) (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 |                               (unsigned char_     b_BoardHandle,                    |
361 |                                unsigned char_     b_ModulNbr,                       |
362 |                                unsigned char_     b_SelectedSSI,                    |
363 |                                PULONG_ pul_Position,                       |
364 |                                PULONG_ pul_TurnCpt)
365  int i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
366         struct comedi_insn *insn,unsigned int *data)                       |
367 +----------------------------------------------------------------------------+
368 | Task              :
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  : unsigned char_ b_BoardHandle         : Handle of board APCI-1710|
377 |                     unsigned char_ b_ModulNbr            : Module number to         |
378 |                                                   configure (0 to 3)       |
379 |                     unsigned char_ b_SelectedSSI         : Selection from SSI       |
380 |                                                   counter (0 to 2)
381
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);
385 |
386 +----------------------------------------------------------------------------+
387 | Output Parameters : PULONG_  pul_Position       : SSI position in the turn |
388 |                     PULONG_  pul_TurnCpt        : Number of turns
389
390 pul_Position    =       (unsigned int *) &data[0];
391         pul_TurnCpt             =       (unsigned int *) &data[1];         |
392 +----------------------------------------------------------------------------+
393 | Return Value      : 0: No error                                            |
394 |                    -1: The handle parameter of the board is wrong          |
395 |                    -2: The module parameter is wrong                       |
396 |                    -3: The module is not a SSI module                      |
397 |                    -4: SSI not initialised see function                    |
398 |                        "i_APCI1710_InitSSI"                                |
399 |                    -5: The selected SSI is wrong                           |
400 +----------------------------------------------------------------------------+
401 */
402
403 int i_APCI1710_InsnReadSSIValue(struct comedi_device * dev, struct comedi_subdevice * s,
404         struct comedi_insn * insn, unsigned int * data)
405 {
406         int i_ReturnValue = 0;
407         unsigned char b_Cpt;
408         unsigned char b_Length;
409         unsigned char b_Schift;
410         unsigned char b_SSICpt;
411         unsigned int dw_And;
412         unsigned int dw_And1;
413         unsigned int dw_And2;
414         unsigned int dw_StatusReg;
415         unsigned int dw_CounterValue;
416         unsigned char b_ModulNbr;
417         unsigned char b_SelectedSSI;
418         unsigned char b_ReadType;
419         unsigned int * pul_Position;
420         unsigned int * pul_TurnCpt;
421         unsigned int * pul_Position1;
422         unsigned int * pul_TurnCpt1;
423
424         i_ReturnValue = insn->n;
425         pul_Position1 = (unsigned int *) & data[0];
426 /* For Read1 */
427         pul_TurnCpt1 = (unsigned int *) & data[1];
428 /* For Read all */
429         pul_Position = (unsigned int *) & data[0];      /* 0-2 */
430         pul_TurnCpt = (unsigned int *) & data[3];       /* 3-5 */
431         b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
432         b_SelectedSSI = (unsigned char) CR_CHAN(insn->chanspec);
433         b_ReadType = (unsigned char) CR_RANGE(insn->chanspec);
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 |                                       (unsigned char_     b_BoardHandle,            |
705 |                                        unsigned char_     b_ModulNbr,               |
706 |                                        unsigned char_     b_InputChannel,           |
707 |                                        unsigned char *_   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  : unsigned char_ b_BoardHandle         : Handle of board APCI-1710|
720 |                     unsigned char_ b_ModulNbr    CR_AREF        : Module number to         |
721 |                                                   configure (0 to 3)       |
722 |                     unsigned char_ b_InputChannel CR_CHAN       : Selection from digital   |
723 |                        data[0] which IOTYPE                           input ( 0 to 2)          |
724 +----------------------------------------------------------------------------+
725 | Output Parameters : unsigned char *_  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
738 int i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
739         struct comedi_insn * insn, unsigned int * data)
740 {
741         int i_ReturnValue = 0;
742         unsigned int dw_StatusReg;
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;
748         i_ReturnValue = insn->n;
749         b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
750         b_IOType = (unsigned char) 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 = (unsigned char) CR_CHAN(insn->chanspec);
789                                 pb_ChannelStatus = (unsigned char *) & 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                                                 (unsigned char) (((~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 = (unsigned char *) & data[0];
818
819                                 dw_StatusReg =
820                                         inl(devpriv->s_BoardInfos.ui_Address +
821                                         (64 * b_ModulNbr));
822                                 *pb_InputStatus =
823                                         (unsigned char) (((~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 }