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