Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6
[pandora-kernel.git] / drivers / staging / comedi / drivers / addi-data / APCI1710_Inp_cpt.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 : Inp_CPT.C       | Version  : 2.96                       |
34   +-------------------------------+---------------------------------------+
35   | Project manager: Eric Stolz   | Date     :  02/12/2002                |
36   +-----------------------------------------------------------------------+
37   | Description :   APCI-1710 pulse encoder module                        |
38   |                                                                       |
39   |                                                                       |
40   +-----------------------------------------------------------------------+
41   |                             UPDATES                                   |
42   +-----------------------------------------------------------------------+
43   |   Date   |   Author  |          Description of updates                |
44   +----------+-----------+------------------------------------------------+
45   |          |           |                                                |
46   |----------|-----------|------------------------------------------------|
47   | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
48   |          |           |   available                                    |
49   +-----------------------------------------------------------------------+
50 */
51
52 /*
53 +----------------------------------------------------------------------------+
54 |                               Included files                               |
55 +----------------------------------------------------------------------------+
56 */
57
58 #include "APCI1710_Inp_cpt.h"
59
60 /*
61 +----------------------------------------------------------------------------+
62 | Function Name     : _INT_ i_APCI1710_InitPulseEncoder                      |
63 |                               (unsigned char_          b_BoardHandle,               |
64 |                                unsigned char_          b_ModulNbr,                  |
65 |                                unsigned char_          b_PulseEncoderNbr,           |
66 |                                unsigned char_          b_InputLevelSelection,       |
67 |                                unsigned char_          b_TriggerOutputAction,       |
68 |                                ULONG_        ul_StartValue)                |
69 +----------------------------------------------------------------------------+
70 | Task              : Configure the pulse encoder operating mode selected via|
71 |                     b_ModulNbr and b_PulseEncoderNbr. The pulse encoder    |
72 |                     after each pulse decrement the counter value from 1.   |
73 |                                                                            |
74 |                     You must calling this function be for you call any     |
75 |                     other function witch access of pulse encoders.         |
76 +----------------------------------------------------------------------------+
77 | Input Parameters  : unsigned char_ b_BoardHandle         : Handle of board APCI-1710|
78 |                     unsigned char_ b_ModulNbr            : Module number to         |
79 |                                                   configure (0 to 3)       |
80 |                     unsigned char_ b_PulseEncoderNbr     : Pulse encoder selection  |
81 |                                                   (0 to 3)                 |
82 |                     unsigned char_ b_InputLevelSelection : Input level selection    |
83 |                                                   (0 or 1)                 |
84 |                                                       0 : Set pulse encoder|
85 |                                                           count the the low|
86 |                                                           level pulse.     |
87 |                                                       1 : Set pulse encoder|
88 |                                                           count the the    |
89 |                                                           high level pulse.|
90 |                     unsigned char_ b_TriggerOutputAction : Digital TRIGGER output   |
91 |                                                   action                   |
92 |                                                       0 : No action        |
93 |                                                       1 : Set the trigger  |
94 |                                                           output to "1"    |
95 |                                                           (high) after the |
96 |                                                           passage from 1 to|
97 |                                                           0 from pulse     |
98 |                                                           encoder.         |
99 |                                                       2 : Set the trigger  |
100 |                                                           output to "0"    |
101 |                                                           (low) after the  |
102 |                                                           passage from 1 to|
103 |                                                           0 from pulse     |
104 |                                                           encoder          |
105 |                     ULONG_ ul_StartValue        : Pulse encoder start value|
106 |                                                   (1 to 4294967295)
107         b_ModulNbr                              =(unsigned char) CR_AREF(insn->chanspec);
108         b_PulseEncoderNbr               =(unsigned char) data[0];
109         b_InputLevelSelection   =(unsigned char) data[1];
110         b_TriggerOutputAction   =(unsigned char) data[2];
111         ul_StartValue                   =(unsigned int) data[3];
112        |
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 is not a pulse encoder module            |
119 |                    -3: Pulse encoder selection is wrong                    |
120 |                    -4: Input level selection is wrong                      |
121 |                    -5: Digital TRIGGER output action selection is wrong    |
122 |                    -6: Pulse encoder start value is wrong                  |
123 +----------------------------------------------------------------------------+
124 */
125
126 int i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
127         struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
128 {
129         int i_ReturnValue = 0;
130         unsigned int dw_IntRegister;
131
132         unsigned char b_ModulNbr;
133         unsigned char b_PulseEncoderNbr;
134         unsigned char b_InputLevelSelection;
135         unsigned char b_TriggerOutputAction;
136         unsigned int ul_StartValue;
137
138         b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
139         b_PulseEncoderNbr = (unsigned char) data[0];
140         b_InputLevelSelection = (unsigned char) data[1];
141         b_TriggerOutputAction = (unsigned char) data[2];
142         ul_StartValue = (unsigned int) data[3];
143
144         i_ReturnValue = insn->n;
145
146         /***********************************/
147         /* Test the selected module number */
148         /***********************************/
149
150         if (b_ModulNbr <= 3) {
151            /*************************/
152                 /* Test if pulse encoder */
153            /*************************/
154
155                 if ((devpriv->s_BoardInfos.
156                                 dw_MolduleConfiguration[b_ModulNbr] &
157                                 APCI1710_PULSE_ENCODER) ==
158                         APCI1710_PULSE_ENCODER) {
159               /******************************************/
160                         /* Test the selected pulse encoder number */
161               /******************************************/
162
163                         if (b_PulseEncoderNbr <= 3) {
164                  /************************/
165                                 /* Test the input level */
166                  /************************/
167
168                                 if ((b_InputLevelSelection == 0)
169                                         || (b_InputLevelSelection == 1)) {
170                     /*******************************************/
171                                         /* Test the ouput TRIGGER action selection */
172                     /*******************************************/
173
174                                         if ((b_TriggerOutputAction <= 2)
175                                                 || (b_PulseEncoderNbr > 0)) {
176                                                 if (ul_StartValue > 1) {
177
178                                                         dw_IntRegister =
179                                                                 inl(devpriv->
180                                                                 s_BoardInfos.
181                                                                 ui_Address +
182                                                                 20 +
183                                                                 (64 * b_ModulNbr));
184
185                           /***********************/
186                                                         /* Set the start value */
187                           /***********************/
188
189                                                         outl(ul_StartValue,
190                                                                 devpriv->
191                                                                 s_BoardInfos.
192                                                                 ui_Address +
193                                                                 (b_PulseEncoderNbr
194                                                                         * 4) +
195                                                                 (64 * b_ModulNbr));
196
197                           /***********************/
198                                                         /* Set the input level */
199                           /***********************/
200                                                         devpriv->
201                                                                 s_ModuleInfo
202                                                                 [b_ModulNbr].
203                                                                 s_PulseEncoderModuleInfo.
204                                                                 dw_SetRegister =
205                                                                 (devpriv->
206                                                                 s_ModuleInfo
207                                                                 [b_ModulNbr].
208                                                                 s_PulseEncoderModuleInfo.
209                                                                 dw_SetRegister &
210                                                                 (0xFFFFFFFFUL -
211                                                                         (1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));
212
213                           /*******************************/
214                                                         /* Test if output trigger used */
215                           /*******************************/
216
217                                                         if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) {
218                              /****************************/
219                                                                 /* Enable the output action */
220                              /****************************/
221
222                                                                 devpriv->
223                                                                         s_ModuleInfo
224                                                                         [b_ModulNbr].
225                                                                         s_PulseEncoderModuleInfo.
226                                                                         dw_SetRegister
227                                                                         =
228                                                                         devpriv->
229                                                                         s_ModuleInfo
230                                                                         [b_ModulNbr].
231                                                                         s_PulseEncoderModuleInfo.
232                                                                         dw_SetRegister
233                                                                         | (1UL
234                                                                         << (4 + b_PulseEncoderNbr));
235
236                              /*********************************/
237                                                                 /* Set the output TRIGGER action */
238                              /*********************************/
239
240                                                                 devpriv->
241                                                                         s_ModuleInfo
242                                                                         [b_ModulNbr].
243                                                                         s_PulseEncoderModuleInfo.
244                                                                         dw_SetRegister
245                                                                         =
246                                                                         (devpriv->
247                                                                         s_ModuleInfo
248                                                                         [b_ModulNbr].
249                                                                         s_PulseEncoderModuleInfo.
250                                                                         dw_SetRegister
251                                                                         &
252                                                                         (0xFFFFFFFFUL
253                                                                                 -
254                                                                                 (1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));
255                                                         } else {
256                              /*****************************/
257                                                                 /* Disable the output action */
258                              /*****************************/
259
260                                                                 devpriv->
261                                                                         s_ModuleInfo
262                                                                         [b_ModulNbr].
263                                                                         s_PulseEncoderModuleInfo.
264                                                                         dw_SetRegister
265                                                                         =
266                                                                         devpriv->
267                                                                         s_ModuleInfo
268                                                                         [b_ModulNbr].
269                                                                         s_PulseEncoderModuleInfo.
270                                                                         dw_SetRegister
271                                                                         &
272                                                                         (0xFFFFFFFFUL
273                                                                         -
274                                                                         (1UL << (4 + b_PulseEncoderNbr)));
275                                                         }
276
277                           /*************************/
278                                                         /* Set the configuration */
279                           /*************************/
280
281                                                         outl(devpriv->
282                                                                 s_ModuleInfo
283                                                                 [b_ModulNbr].
284                                                                 s_PulseEncoderModuleInfo.
285                                                                 dw_SetRegister,
286                                                                 devpriv->
287                                                                 s_BoardInfos.
288                                                                 ui_Address +
289                                                                 20 +
290                                                                 (64 * b_ModulNbr));
291
292                                                         devpriv->
293                                                                 s_ModuleInfo
294                                                                 [b_ModulNbr].
295                                                                 s_PulseEncoderModuleInfo.
296                                                                 s_PulseEncoderInfo
297                                                                 [b_PulseEncoderNbr].
298                                                                 b_PulseEncoderInit
299                                                                 = 1;
300                                                 } else {
301                           /**************************************/
302                                                         /* Pulse encoder start value is wrong */
303                           /**************************************/
304
305                                                         DPRINTK("Pulse encoder start value is wrong\n");
306                                                         i_ReturnValue = -6;
307                                                 }
308                                         } else {
309                        /****************************************************/
310                                                 /* Digital TRIGGER output action selection is wrong */
311                        /****************************************************/
312
313                                                 DPRINTK("Digital TRIGGER output action selection is wrong\n");
314                                                 i_ReturnValue = -5;
315                                         }
316                                 } else {
317                     /**********************************/
318                                         /* Input level selection is wrong */
319                     /**********************************/
320
321                                         DPRINTK("Input level selection is wrong\n");
322                                         i_ReturnValue = -4;
323                                 }
324                         } else {
325                  /************************************/
326                                 /* Pulse encoder selection is wrong */
327                  /************************************/
328
329                                 DPRINTK("Pulse encoder selection is wrong\n");
330                                 i_ReturnValue = -3;
331                         }
332                 } else {
333               /********************************************/
334                         /* The module is not a pulse encoder module */
335               /********************************************/
336
337                         DPRINTK("The module is not a pulse encoder module\n");
338                         i_ReturnValue = -2;
339                 }
340         } else {
341            /********************************************/
342                 /* The module is not a pulse encoder module */
343            /********************************************/
344
345                 DPRINTK("The module is not a pulse encoder module\n");
346                 i_ReturnValue = -2;
347         }
348
349         return i_ReturnValue;
350 }
351
352 /*
353 +----------------------------------------------------------------------------+
354 | Function Name     : _INT_ i_APCI1710_EnablePulseEncoder                    |
355 |                                       (unsigned char_  b_BoardHandle,               |
356 |                                        unsigned char_  b_ModulNbr,                  |
357 |                                        unsigned char_  b_PulseEncoderNbr,           |
358 |                                        unsigned char_  b_CycleSelection,            |
359 |                                        unsigned char_  b_InterruptHandling)         |
360 +----------------------------------------------------------------------------+
361 | Task              : Enableor disable  the selected pulse encoder (b_PulseEncoderNbr)  |
362 |                     from selected module (b_ModulNbr). Each input pulse    |
363 |                     decrement the pulse encoder counter value from 1.      |
364 |                     If you enabled the interrupt (b_InterruptHandling), a  |
365 |                     interrupt is generated when the pulse encoder has run  |
366 |                     down.                                                  |
367 +----------------------------------------------------------------------------+
368 | Input Parameters  : unsigned char_   b_BoardHandle       : Handle of board APCI-1710|
369 |                     unsigned char_   b_ModulNbr          : Module number to         |
370 |                                                   configure (0 to 3)       |
371 |                     unsigned char_   b_PulseEncoderNbr   : Pulse encoder selection  |
372 |                                                   (0 to 3)                 |
373 |                     unsigned char_   b_CycleSelection    : APCI1710_CONTINUOUS:     |
374 |                                                       Each time the        |
375 |                                                       counting value is set|
376 |                                                       on "0", the pulse    |
377 |                                                       encoder load the     |
378 |                                                       start value after    |
379 |                                                       the next pulse.      |
380 |                                                   APCI1710_SINGLE:         |
381 |                                                       If the counter is set|
382 |                                                       on "0", the pulse    |
383 |                                                       encoder is stopped.  |
384 |                     unsigned char_   b_InterruptHandling : Interrupts can be        |
385 |                                                   generated, when the pulse|
386 |                                                   encoder has run down.    |
387 |                                                   With this parameter the  |
388 |                                                   user decides if          |
389 |                                                   interrupts are used or   |
390 |                                                   not.                     |
391 |                                                     APCI1710_ENABLE:       |
392 |                                                     Interrupts are enabled |
393 |                                                     APCI1710_DISABLE:      |
394 |                                                     Interrupts are disabled
395
396         b_ModulNbr                      =(unsigned char) CR_AREF(insn->chanspec);
397         b_Action                        =(unsigned char) data[0];
398         b_PulseEncoderNbr       =(unsigned char) data[1];
399         b_CycleSelection        =(unsigned char) data[2];
400         b_InterruptHandling     =(unsigned char) data[3];|
401 +----------------------------------------------------------------------------+
402 | Output Parameters : -                                                      |
403 +----------------------------------------------------------------------------+
404 | Return Value      :  0: No error                                           |
405 |                     -1: The handle parameter of the board is wrong         |
406 |                     -2: Module selection is wrong                          |
407 |                     -3: Pulse encoder selection is wrong                   |
408 |                     -4: Pulse encoder not initialised.                     |
409 |                         See function "i_APCI1710_InitPulseEncoder"         |
410 |                     -5: Cycle selection mode is wrong                      |
411 |                     -6: Interrupt handling mode is wrong                   |
412 |                     -7: Interrupt routine not installed.                   |
413 |                         See function "i_APCI1710_SetBoardIntRoutineX"      |
414 +----------------------------------------------------------------------------+
415 */
416
417 int i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
418         struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
419 {
420         int i_ReturnValue = 0;
421         unsigned char b_ModulNbr;
422         unsigned char b_PulseEncoderNbr;
423         unsigned char b_CycleSelection;
424         unsigned char b_InterruptHandling;
425         unsigned char b_Action;
426
427         i_ReturnValue = insn->n;
428         b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
429         b_Action = (unsigned char) data[0];
430         b_PulseEncoderNbr = (unsigned char) data[1];
431         b_CycleSelection = (unsigned char) data[2];
432         b_InterruptHandling = (unsigned char) data[3];
433
434         /***********************************/
435         /* Test the selected module number */
436         /***********************************/
437
438         if (b_ModulNbr <= 3) {
439            /******************************************/
440                 /* Test the selected pulse encoder number */
441            /******************************************/
442
443                 if (b_PulseEncoderNbr <= 3) {
444               /*************************************/
445                         /* Test if pulse encoder initialised */
446               /*************************************/
447
448                         if (devpriv->s_ModuleInfo[b_ModulNbr].
449                                 s_PulseEncoderModuleInfo.
450                                 s_PulseEncoderInfo[b_PulseEncoderNbr].
451                                 b_PulseEncoderInit == 1) {
452                                 switch (b_Action) {
453
454                                 case APCI1710_ENABLE:
455                  /****************************/
456                                         /* Test the cycle selection */
457                  /****************************/
458
459                                         if (b_CycleSelection ==
460                                                 APCI1710_CONTINUOUS
461                                                 || b_CycleSelection ==
462                                                 APCI1710_SINGLE) {
463                     /*******************************/
464                                                 /* Test the interrupt handling */
465                     /*******************************/
466
467                                                 if (b_InterruptHandling ==
468                                                         APCI1710_ENABLE
469                                                         || b_InterruptHandling
470                                                         == APCI1710_DISABLE) {
471                        /******************************/
472                                                         /* Test if interrupt not used */
473                        /******************************/
474
475                                                         if (b_InterruptHandling
476                                                                 ==
477                                                                 APCI1710_DISABLE)
478                                                         {
479                           /*************************/
480                                                                 /* Disable the interrupt */
481                           /*************************/
482
483                                                                 devpriv->
484                                                                         s_ModuleInfo
485                                                                         [b_ModulNbr].
486                                                                         s_PulseEncoderModuleInfo.
487                                                                         dw_SetRegister
488                                                                         =
489                                                                         devpriv->
490                                                                         s_ModuleInfo
491                                                                         [b_ModulNbr].
492                                                                         s_PulseEncoderModuleInfo.
493                                                                         dw_SetRegister
494                                                                         &
495                                                                         (0xFFFFFFFFUL
496                                                                         -
497                                                                         (1UL << b_PulseEncoderNbr));
498                                                         } else {
499
500                              /************************/
501                                                                 /* Enable the interrupt */
502                              /************************/
503
504                                                                 devpriv->
505                                                                         s_ModuleInfo
506                                                                         [b_ModulNbr].
507                                                                         s_PulseEncoderModuleInfo.
508                                                                         dw_SetRegister
509                                                                         =
510                                                                         devpriv->
511                                                                         s_ModuleInfo
512                                                                         [b_ModulNbr].
513                                                                         s_PulseEncoderModuleInfo.
514                                                                         dw_SetRegister
515                                                                         | (1UL
516                                                                         <<
517                                                                         b_PulseEncoderNbr);
518                                                                 devpriv->tsk_Current = current; /*  Save the current process task structure */
519
520                                                         }
521
522                                                         if (i_ReturnValue >= 0) {
523                           /***********************************/
524                                                                 /* Enable or disable the interrupt */
525                           /***********************************/
526
527                                                                 outl(devpriv->
528                                                                         s_ModuleInfo
529                                                                         [b_ModulNbr].
530                                                                         s_PulseEncoderModuleInfo.
531                                                                         dw_SetRegister,
532                                                                         devpriv->
533                                                                         s_BoardInfos.
534                                                                         ui_Address
535                                                                         + 20 +
536                                                                         (64 * b_ModulNbr));
537
538                           /****************************/
539                                                                 /* Enable the pulse encoder */
540                           /****************************/
541                                                                 devpriv->
542                                                                         s_ModuleInfo
543                                                                         [b_ModulNbr].
544                                                                         s_PulseEncoderModuleInfo.
545                                                                         dw_ControlRegister
546                                                                         =
547                                                                         devpriv->
548                                                                         s_ModuleInfo
549                                                                         [b_ModulNbr].
550                                                                         s_PulseEncoderModuleInfo.
551                                                                         dw_ControlRegister
552                                                                         | (1UL
553                                                                         <<
554                                                                         b_PulseEncoderNbr);
555
556                           /**********************/
557                                                                 /* Set the cycle mode */
558                           /**********************/
559
560                                                                 devpriv->
561                                                                         s_ModuleInfo
562                                                                         [b_ModulNbr].
563                                                                         s_PulseEncoderModuleInfo.
564                                                                         dw_ControlRegister
565                                                                         =
566                                                                         (devpriv->
567                                                                         s_ModuleInfo
568                                                                         [b_ModulNbr].
569                                                                         s_PulseEncoderModuleInfo.
570                                                                         dw_ControlRegister
571                                                                         &
572                                                                         (0xFFFFFFFFUL
573                                                                                 -
574                                                                                 (1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));
575
576                           /****************************/
577                                                                 /* Enable the pulse encoder */
578                           /****************************/
579
580                                                                 outl(devpriv->
581                                                                         s_ModuleInfo
582                                                                         [b_ModulNbr].
583                                                                         s_PulseEncoderModuleInfo.
584                                                                         dw_ControlRegister,
585                                                                         devpriv->
586                                                                         s_BoardInfos.
587                                                                         ui_Address
588                                                                         + 16 +
589                                                                         (64 * b_ModulNbr));
590                                                         }
591                                                 } else {
592                        /************************************/
593                                                         /* Interrupt handling mode is wrong */
594                        /************************************/
595
596                                                         DPRINTK("Interrupt handling mode is wrong\n");
597                                                         i_ReturnValue = -6;
598                                                 }
599                                         } else {
600                     /*********************************/
601                                                 /* Cycle selection mode is wrong */
602                     /*********************************/
603
604                                                 DPRINTK("Cycle selection mode is wrong\n");
605                                                 i_ReturnValue = -5;
606                                         }
607                                         break;
608
609                                 case APCI1710_DISABLE:
610                                         devpriv->s_ModuleInfo[b_ModulNbr].
611                                                 s_PulseEncoderModuleInfo.
612                                                 dw_ControlRegister =
613                                                 devpriv->
614                                                 s_ModuleInfo[b_ModulNbr].
615                                                 s_PulseEncoderModuleInfo.
616                                                 dw_ControlRegister &
617                                                 (0xFFFFFFFFUL -
618                                                 (1UL << b_PulseEncoderNbr));
619
620                  /*****************************/
621                                         /* Disable the pulse encoder */
622                  /*****************************/
623
624                                         outl(devpriv->s_ModuleInfo[b_ModulNbr].
625                                                 s_PulseEncoderModuleInfo.
626                                                 dw_ControlRegister,
627                                                 devpriv->s_BoardInfos.
628                                                 ui_Address + 16 +
629                                                 (64 * b_ModulNbr));
630
631                                         break;
632                                 }       /*  switch End */
633
634                         } else {
635                  /*********************************/
636                                 /* Pulse encoder not initialised */
637                  /*********************************/
638
639                                 DPRINTK("Pulse encoder not initialised\n");
640                                 i_ReturnValue = -4;
641                         }
642                 } else {
643               /************************************/
644                         /* Pulse encoder selection is wrong */
645               /************************************/
646
647                         DPRINTK("Pulse encoder selection is wrong\n");
648                         i_ReturnValue = -3;
649                 }
650         } else {
651            /*****************************/
652                 /* Module selection is wrong */
653            /*****************************/
654
655                 DPRINTK("Module selection is wrong\n");
656                 i_ReturnValue = -2;
657         }
658
659         return i_ReturnValue;
660 }
661
662 /*
663 +----------------------------------------------------------------------------+
664 | Function Name     : _INT_ i_APCI1710_ReadPulseEncoderStatus                |
665 |                                       (unsigned char_  b_BoardHandle,               |
666 |                                        unsigned char_  b_ModulNbr,                  |
667 |                                        unsigned char_  b_PulseEncoderNbr,           |
668 |                                        unsigned char *_ pb_Status)                   |
669 +----------------------------------------------------------------------------+
670 | Task    APCI1710_PULSEENCODER_READ          : Reads the pulse encoder status
671                                                                                         and valuefrom selected pulse     |
672 |                     encoder (b_PulseEncoderNbr) from selected module       |
673 |                     (b_ModulNbr).                                          |
674 +----------------------------------------------------------------------------+
675         unsigned char   b_Type; data[0]
676    APCI1710_PULSEENCODER_WRITE
677  Writes a 32-bit value (ul_WriteValue) into the selected|
678 |                     pulse encoder (b_PulseEncoderNbr) from selected module |
679 |                     (b_ModulNbr). This operation set the new start pulse   |
680 |                     encoder value.
681  APCI1710_PULSEENCODER_READ
682 | Input Parameters  : unsigned char_   b_BoardHandle       : Handle of board APCI-1710|
683 |            CRAREF()         unsigned char_   b_ModulNbr          : Module number to         |
684 |                                                   configure (0 to 3)       |
685 |              data[1]       unsigned char_   b_PulseEncoderNbr   : Pulse encoder selection  |
686 |                                                   (0 to 3)
687    APCI1710_PULSEENCODER_WRITE
688                                 data[2]         ULONG_ ul_WriteValue        : 32-bit value to be       |
689 |                                                   written             |
690 +----------------------------------------------------------------------------+
691 | Output Parameters : unsigned char *_ pb_Status            : Pulse encoder status.    |
692 |                                                       0 : No overflow occur|
693 |                                                       1 : Overflow occur
694                                                 PULONG_ pul_ReadValue       : Pulse encoder value      |  |
695 +----------------------------------------------------------------------------+
696 | Return Value      :  0: No error                                           |
697 |                     -1: The handle parameter of the board is wrong         |
698 |                     -2: Module selection is wrong                          |
699 |                     -3: Pulse encoder selection is wrong                   |
700 |                     -4: Pulse encoder not initialised.                     |
701 |                         See function "i_APCI1710_InitPulseEncoder"         |
702 +----------------------------------------------------------------------------+
703 */
704
705 /*_INT_   i_APCI1710_ReadPulseEncoderStatus       (unsigned char_   b_BoardHandle,
706                                                  unsigned char_   b_ModulNbr,
707                                                  unsigned char_   b_PulseEncoderNbr,
708
709                                                  unsigned char *_ pb_Status)
710                                                  */
711 int i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
712         struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
713 {
714         int i_ReturnValue = 0;
715         unsigned int dw_StatusRegister;
716         unsigned char b_ModulNbr;
717         unsigned char b_PulseEncoderNbr;
718         unsigned char *pb_Status;
719         unsigned char b_Type;
720         unsigned int *pul_ReadValue;
721         unsigned int ul_WriteValue;
722
723         i_ReturnValue = insn->n;
724         b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
725         b_Type = (unsigned char) data[0];
726         b_PulseEncoderNbr = (unsigned char) data[1];
727         pb_Status = (unsigned char *) &data[0];
728         pul_ReadValue = (unsigned int *) &data[1];
729
730         /***********************************/
731         /* Test the selected module number */
732         /***********************************/
733
734         if (b_ModulNbr <= 3) {
735            /******************************************/
736                 /* Test the selected pulse encoder number */
737            /******************************************/
738
739                 if (b_PulseEncoderNbr <= 3) {
740               /*************************************/
741                         /* Test if pulse encoder initialised */
742               /*************************************/
743
744                         if (devpriv->s_ModuleInfo[b_ModulNbr].
745                                 s_PulseEncoderModuleInfo.
746                                 s_PulseEncoderInfo[b_PulseEncoderNbr].
747                                 b_PulseEncoderInit == 1) {
748
749                                 switch (b_Type) {
750                                 case APCI1710_PULSEENCODER_READ:
751                  /****************************/
752                                         /* Read the status register */
753                  /****************************/
754
755                                         dw_StatusRegister =
756                                                 inl(devpriv->s_BoardInfos.
757                                                 ui_Address + 16 +
758                                                 (64 * b_ModulNbr));
759
760                                         devpriv->s_ModuleInfo[b_ModulNbr].
761                                                 s_PulseEncoderModuleInfo.
762                                                 dw_StatusRegister = devpriv->
763                                                 s_ModuleInfo[b_ModulNbr].
764                                                 s_PulseEncoderModuleInfo.
765                                                 dw_StatusRegister |
766                                                 dw_StatusRegister;
767
768                                         *pb_Status =
769                                                 (unsigned char) (devpriv->
770                                                 s_ModuleInfo[b_ModulNbr].
771                                                 s_PulseEncoderModuleInfo.
772                                                 dw_StatusRegister >> (1 +
773                                                         b_PulseEncoderNbr)) & 1;
774
775                                         devpriv->s_ModuleInfo[b_ModulNbr].
776                                                 s_PulseEncoderModuleInfo.
777                                                 dw_StatusRegister =
778                                                 devpriv->
779                                                 s_ModuleInfo[b_ModulNbr].
780                                                 s_PulseEncoderModuleInfo.
781                                                 dw_StatusRegister &
782                                                 (0xFFFFFFFFUL - (1 << (1 +
783                                                                 b_PulseEncoderNbr)));
784
785                  /******************/
786                                         /* Read the value */
787                  /******************/
788
789                                         *pul_ReadValue =
790                                                 inl(devpriv->s_BoardInfos.
791                                                 ui_Address +
792                                                 (4 * b_PulseEncoderNbr) +
793                                                 (64 * b_ModulNbr));
794                                         break;
795
796                                 case APCI1710_PULSEENCODER_WRITE:
797                                         ul_WriteValue = (unsigned int) data[2];
798                         /*******************/
799                                         /* Write the value */
800                         /*******************/
801
802                                         outl(ul_WriteValue,
803                                                 devpriv->s_BoardInfos.
804                                                 ui_Address +
805                                                 (4 * b_PulseEncoderNbr) +
806                                                 (64 * b_ModulNbr));
807
808                                 }       /* end of switch */
809                         } else {
810                  /*********************************/
811                                 /* Pulse encoder not initialised */
812                  /*********************************/
813
814                                 DPRINTK("Pulse encoder not initialised\n");
815                                 i_ReturnValue = -4;
816                         }
817                 } else {
818               /************************************/
819                         /* Pulse encoder selection is wrong */
820               /************************************/
821
822                         DPRINTK("Pulse encoder selection is wrong\n");
823                         i_ReturnValue = -3;
824                 }
825         } else {
826            /*****************************/
827                 /* Module selection is wrong */
828            /*****************************/
829
830                 DPRINTK("Module selection is wrong\n");
831                 i_ReturnValue = -2;
832         }
833
834         return i_ReturnValue;
835 }
836
837 int i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev,
838         struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
839 {
840
841         data[0] = devpriv->s_InterruptParameters.
842                 s_FIFOInterruptParameters[devpriv->
843                 s_InterruptParameters.ui_Read].b_OldModuleMask;
844         data[1] = devpriv->s_InterruptParameters.
845                 s_FIFOInterruptParameters[devpriv->
846                 s_InterruptParameters.ui_Read].ul_OldInterruptMask;
847         data[2] = devpriv->s_InterruptParameters.
848                 s_FIFOInterruptParameters[devpriv->
849                 s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
850
851         /***************************/
852         /* Increment the read FIFO */
853         /***************************/
854
855         devpriv->s_InterruptParameters.
856                 ui_Read = (devpriv->
857                 s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
858
859         return insn->n;
860
861 }