packaging: release out (3.8.3)
[profile/ivi/kernel-adaptation-intel-automotive.git] / drivers / staging / comedi / drivers / addi-data / APCI1710_Chrono.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 : CHRONO.C        | Version  : 2.96                       |
34   +-------------------------------+---------------------------------------+
35   | Project manager: Eric Stolz   | Date     :  02/12/2002                |
36   +-----------------------------------------------------------------------+
37   | Description :   APCI-1710 chronometer module                          |
38   |                                                                       |
39   |                                                                       |
40   +-----------------------------------------------------------------------+
41   |                             UPDATES                                   |
42   +-----------------------------------------------------------------------+
43   |   Date   |   Author  |          Description of updates                |
44   +----------+-----------+------------------------------------------------+
45   | 29/06/98 | S. Weber  | Digital input / output implementation          |
46   |----------|-----------|------------------------------------------------|
47   | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
48   |          |           |   available                                    |
49   +-----------------------------------------------------------------------+
50   |          |           |                                                |
51   |          |           |                                                |
52   +-----------------------------------------------------------------------+
53 */
54
55 #define APCI1710_30MHZ                  30
56 #define APCI1710_33MHZ                  33
57 #define APCI1710_40MHZ                  40
58
59 #define APCI1710_SINGLE                 0
60 #define APCI1710_CONTINUOUS             1
61
62 #define APCI1710_CHRONO_PROGRESS_STATUS 0
63 #define APCI1710_CHRONO_READVALUE       1
64 #define APCI1710_CHRONO_CONVERTVALUE    2
65 #define APCI1710_CHRONO_READINTERRUPT   3
66
67 #define APCI1710_CHRONO_SET_CHANNELON   0
68 #define APCI1710_CHRONO_SET_CHANNELOFF  1
69 #define APCI1710_CHRONO_READ_CHANNEL    2
70 #define APCI1710_CHRONO_READ_PORT       3
71
72 /*
73 +----------------------------------------------------------------------------+
74 | Function Name     : _INT_     i_APCI1710_InitChrono                        |
75 |                                       (unsigned char_     b_BoardHandle,            |
76 |                                        unsigned char_     b_ModulNbr,               |
77 |                                        unsigned char_     b_ChronoMode,             |
78 |                                        unsigned char_     b_PCIInputClock,          |
79 |                                        unsigned char_     b_TimingUnit,             |
80 |                                        ULONG_   ul_TimingInterval,         |
81 |                                        PULONG_ pul_RealTimingInterval)
82
83 +----------------------------------------------------------------------------+
84 | Task              : Configure the chronometer operating mode (b_ChronoMode)|
85 |                     from selected module (b_ModulNbr).                     |
86 |                     The ul_TimingInterval and ul_TimingUnit determine the  |
87 |                     timing base for the measurement.                       |
88 |                     The pul_RealTimingInterval return the real timing      |
89 |                     value. You must calling this function be for you call  |
90 |                     any other function witch access of the chronometer.    |
91 |                                                                            |
92 |                     Witch this functionality from the APCI-1710 you have   |
93 |                     the possibility to measure the timing witch two event. |
94 |                                                                            |
95 |                     The mode 0 and 1 is appropriate for period measurement.|
96 |                     The mode 2 and 3 is appropriate for frequent           |
97 |                     measurement.                                           |
98 |                     The mode 4 to 7 is appropriate for measuring the timing|
99 |                     between  two event.                                    |
100 +----------------------------------------------------------------------------+
101 | Input Parameters  : unsigned char_   b_BoardHandle    : Handle of board APCI-1710   |
102 | unsigned char_   b_ModulNbr  CR_AREF(insn->chanspec)  : Module number to configure  |
103 |                                                (0 to 3)                    |
104 | unsigned char_   b_ChronoMode                         data[0]    : Chronometer action mode     |
105 |                                                (0 to 7).                   |
106 | unsigned char_   b_PCIInputClock                      data[1] : Selection from PCI bus clock|
107 |                                                - APCI1710_30MHZ :          |
108 |                                                  The PC have a PCI bus     |
109 |                                                  clock from 30 MHz         |
110 |                                                - APCI1710_33MHZ :          |
111 |                                                  The PC have a PCI bus     |
112 |                                                  clock from 33 MHz         |
113 |                                                - APCI1710_40MHZ            |
114 |                                                  The APCI-1710 have a      |
115 |                                                  integrated 40Mhz          |
116 |                                                  quartz.                   |
117 |               unsigned char_   b_TimingUnit   data[2]    : Base timing unity (0 to 4) |
118 |                                                 0 : ns                     |
119 |                                                 1 : µs                     |
120 |                                                 2 : ms                     |
121 |                                                 3 : s                      |
122 |                                                 4 : mn                     |
123 |         ULONG_ ul_TimingInterval : data[3]     Base timing value.          |
124 +----------------------------------------------------------------------------+
125 | Output Parameters : PULONG_  pul_RealTimingInterval : Real  base timing    |
126 |                                                       value.
127 |                     data[0]
128 +----------------------------------------------------------------------------+
129 | Return Value      :  0: No error                                           |
130 |                     -1: The handle parameter of the board is wrong         |
131 |                     -2: Module selection wrong                             |
132 |                     -3: The module is not a Chronometer module             |
133 |                     -4: Chronometer mode selection is wrong                |
134 |                     -5: The selected PCI input clock is wrong              |
135 |                     -6: Timing unity selection is wrong                    |
136 |                     -7: Base timing selection is wrong                     |
137 |                     -8: You can not used the 40MHz clock selection with    |
138 |                         this board                                         |
139 |                     -9: You can not used the 40MHz clock selection with    |
140 |                         this CHRONOS version                               |
141 +----------------------------------------------------------------------------+
142 */
143 static int i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev,
144                                            struct comedi_subdevice *s,
145                                            struct comedi_insn *insn,
146                                            unsigned int *data)
147 {
148         struct addi_private *devpriv = dev->private;
149         int i_ReturnValue = 0;
150         unsigned int ul_TimerValue = 0;
151         unsigned int ul_TimingInterval = 0;
152         unsigned int ul_RealTimingInterval = 0;
153         double d_RealTimingInterval = 0;
154         unsigned int dw_ModeArray[8] =
155                 { 0x01, 0x05, 0x00, 0x04, 0x02, 0x0E, 0x0A, 0x06 };
156         unsigned char b_ModulNbr, b_ChronoMode, b_PCIInputClock, b_TimingUnit;
157
158         b_ModulNbr = CR_AREF(insn->chanspec);
159         b_ChronoMode = (unsigned char) data[0];
160         b_PCIInputClock = (unsigned char) data[1];
161         b_TimingUnit = (unsigned char) data[2];
162         ul_TimingInterval = (unsigned int) data[3];
163         i_ReturnValue = insn->n;
164
165         /**************************/
166         /* Test the module number */
167         /**************************/
168
169         if (b_ModulNbr < 4) {
170            /***********************/
171                 /* Test if chronometer */
172            /***********************/
173
174                 if ((devpriv->s_BoardInfos.
175                                 dw_MolduleConfiguration[b_ModulNbr] &
176                                 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
177               /*****************************/
178                         /* Test the chronometer mode */
179               /*****************************/
180
181                         if (b_ChronoMode <= 7) {
182                  /**************************/
183                                 /* Test the PCI bus clock */
184                  /**************************/
185
186                                 if ((b_PCIInputClock == APCI1710_30MHZ) ||
187                                         (b_PCIInputClock == APCI1710_33MHZ) ||
188                                         (b_PCIInputClock == APCI1710_40MHZ)) {
189                     /*************************/
190                                         /* Test the timing unity */
191                     /*************************/
192
193                                         if (b_TimingUnit <= 4) {
194                        /**********************************/
195                                                 /* Test the base timing selection */
196                        /**********************************/
197
198                                                 if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 66) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165576UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 60) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150240UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 50) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374182UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 1UL))) {
199                           /**************************/
200                                                         /* Test the board version */
201                           /**************************/
202
203                                                         if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
204                              /************************/
205                                                                 /* Test the TOR version */
206                              /************************/
207
208                                                                 if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || (b_PCIInputClock != APCI1710_40MHZ)) {
209                                                                         fpu_begin
210                                                                                 ();
211
212                                 /****************************************/
213                                                                         /* Calculate the timer 0 division fator */
214                                 /****************************************/
215
216                                                                         switch (b_TimingUnit) {
217                                    /******/
218                                                                                 /* ns */
219                                    /******/
220
221                                                                         case 0:
222
223                                            /******************/
224                                                                                 /* Timer 0 factor */
225                                            /******************/
226
227                                                                                 ul_TimerValue
228                                                                                         =
229                                                                                         (unsigned int)
230                                                                                         (ul_TimingInterval
231                                                                                         *
232                                                                                         (0.001 * b_PCIInputClock));
233
234                                            /*******************/
235                                                                                 /* Round the value */
236                                            /*******************/
237
238                                                                                 if ((double)((double)ul_TimingInterval * (0.001 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
239                                                                                         ul_TimerValue
240                                                                                                 =
241                                                                                                 ul_TimerValue
242                                                                                                 +
243                                                                                                 1;
244                                                                                 }
245
246                                            /*****************************/
247                                                                                 /* Calculate the real timing */
248                                            /*****************************/
249
250                                                                                 ul_RealTimingInterval
251                                                                                         =
252                                                                                         (unsigned int)
253                                                                                         (ul_TimerValue
254                                                                                         /
255                                                                                         (0.001 * (double)b_PCIInputClock));
256                                                                                 d_RealTimingInterval
257                                                                                         =
258                                                                                         (double)
259                                                                                         ul_TimerValue
260                                                                                         /
261                                                                                         (0.001
262                                                                                         *
263                                                                                         (double)
264                                                                                         b_PCIInputClock);
265
266                                                                                 if ((double)((double)ul_TimerValue / (0.001 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
267                                                                                         ul_RealTimingInterval
268                                                                                                 =
269                                                                                                 ul_RealTimingInterval
270                                                                                                 +
271                                                                                                 1;
272                                                                                 }
273
274                                                                                 ul_TimingInterval
275                                                                                         =
276                                                                                         ul_TimingInterval
277                                                                                         -
278                                                                                         1;
279                                                                                 ul_TimerValue
280                                                                                         =
281                                                                                         ul_TimerValue
282                                                                                         -
283                                                                                         2;
284                                                                                 if (b_PCIInputClock != APCI1710_40MHZ) {
285                                                                                         ul_TimerValue
286                                                                                                 =
287                                                                                                 (unsigned int)
288                                                                                                 (
289                                                                                                 (double)
290                                                                                                 (ul_TimerValue)
291                                                                                                 *
292                                                                                                 0.99392);
293                                                                                 }
294
295                                                                                 break;
296
297                                    /******/
298                                                                                 /* æs */
299                                    /******/
300
301                                                                         case 1:
302
303                                            /******************/
304                                                                                 /* Timer 0 factor */
305                                            /******************/
306
307                                                                                 ul_TimerValue
308                                                                                         =
309                                                                                         (unsigned int)
310                                                                                         (ul_TimingInterval
311                                                                                         *
312                                                                                         (1.0 * b_PCIInputClock));
313
314                                            /*******************/
315                                                                                 /* Round the value */
316                                            /*******************/
317
318                                                                                 if ((double)((double)ul_TimingInterval * (1.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
319                                                                                         ul_TimerValue
320                                                                                                 =
321                                                                                                 ul_TimerValue
322                                                                                                 +
323                                                                                                 1;
324                                                                                 }
325
326                                            /*****************************/
327                                                                                 /* Calculate the real timing */
328                                            /*****************************/
329
330                                                                                 ul_RealTimingInterval
331                                                                                         =
332                                                                                         (unsigned int)
333                                                                                         (ul_TimerValue
334                                                                                         /
335                                                                                         (1.0 * (double)b_PCIInputClock));
336                                                                                 d_RealTimingInterval
337                                                                                         =
338                                                                                         (double)
339                                                                                         ul_TimerValue
340                                                                                         /
341                                                                                         (
342                                                                                         (double)
343                                                                                         1.0
344                                                                                         *
345                                                                                         (double)
346                                                                                         b_PCIInputClock);
347
348                                                                                 if ((double)((double)ul_TimerValue / (1.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
349                                                                                         ul_RealTimingInterval
350                                                                                                 =
351                                                                                                 ul_RealTimingInterval
352                                                                                                 +
353                                                                                                 1;
354                                                                                 }
355
356                                                                                 ul_TimingInterval
357                                                                                         =
358                                                                                         ul_TimingInterval
359                                                                                         -
360                                                                                         1;
361                                                                                 ul_TimerValue
362                                                                                         =
363                                                                                         ul_TimerValue
364                                                                                         -
365                                                                                         2;
366                                                                                 if (b_PCIInputClock != APCI1710_40MHZ) {
367                                                                                         ul_TimerValue
368                                                                                                 =
369                                                                                                 (unsigned int)
370                                                                                                 (
371                                                                                                 (double)
372                                                                                                 (ul_TimerValue)
373                                                                                                 *
374                                                                                                 0.99392);
375                                                                                 }
376
377                                                                                 break;
378
379                                    /******/
380                                                                                 /* ms */
381                                    /******/
382
383                                                                         case 2:
384
385                                            /******************/
386                                                                                 /* Timer 0 factor */
387                                            /******************/
388
389                                                                                 ul_TimerValue
390                                                                                         =
391                                                                                         ul_TimingInterval
392                                                                                         *
393                                                                                         (1000
394                                                                                         *
395                                                                                         b_PCIInputClock);
396
397                                            /*******************/
398                                                                                 /* Round the value */
399                                            /*******************/
400
401                                                                                 if ((double)((double)ul_TimingInterval * (1000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
402                                                                                         ul_TimerValue
403                                                                                                 =
404                                                                                                 ul_TimerValue
405                                                                                                 +
406                                                                                                 1;
407                                                                                 }
408
409                                            /*****************************/
410                                                                                 /* Calculate the real timing */
411                                            /*****************************/
412
413                                                                                 ul_RealTimingInterval
414                                                                                         =
415                                                                                         (unsigned int)
416                                                                                         (ul_TimerValue
417                                                                                         /
418                                                                                         (1000.0 * (double)b_PCIInputClock));
419                                                                                 d_RealTimingInterval
420                                                                                         =
421                                                                                         (double)
422                                                                                         ul_TimerValue
423                                                                                         /
424                                                                                         (1000.0
425                                                                                         *
426                                                                                         (double)
427                                                                                         b_PCIInputClock);
428
429                                                                                 if ((double)((double)ul_TimerValue / (1000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
430                                                                                         ul_RealTimingInterval
431                                                                                                 =
432                                                                                                 ul_RealTimingInterval
433                                                                                                 +
434                                                                                                 1;
435                                                                                 }
436
437                                                                                 ul_TimingInterval
438                                                                                         =
439                                                                                         ul_TimingInterval
440                                                                                         -
441                                                                                         1;
442                                                                                 ul_TimerValue
443                                                                                         =
444                                                                                         ul_TimerValue
445                                                                                         -
446                                                                                         2;
447                                                                                 if (b_PCIInputClock != APCI1710_40MHZ) {
448                                                                                         ul_TimerValue
449                                                                                                 =
450                                                                                                 (unsigned int)
451                                                                                                 (
452                                                                                                 (double)
453                                                                                                 (ul_TimerValue)
454                                                                                                 *
455                                                                                                 0.99392);
456                                                                                 }
457
458                                                                                 break;
459
460                                    /*****/
461                                                                                 /* s */
462                                    /*****/
463
464                                                                         case 3:
465
466                                            /******************/
467                                                                                 /* Timer 0 factor */
468                                            /******************/
469
470                                                                                 ul_TimerValue
471                                                                                         =
472                                                                                         (unsigned int)
473                                                                                         (ul_TimingInterval
474                                                                                         *
475                                                                                         (1000000.0
476                                                                                                 *
477                                                                                                 b_PCIInputClock));
478
479                                            /*******************/
480                                                                                 /* Round the value */
481                                            /*******************/
482
483                                                                                 if ((double)((double)ul_TimingInterval * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
484                                                                                         ul_TimerValue
485                                                                                                 =
486                                                                                                 ul_TimerValue
487                                                                                                 +
488                                                                                                 1;
489                                                                                 }
490
491                                            /*****************************/
492                                                                                 /* Calculate the real timing */
493                                            /*****************************/
494
495                                                                                 ul_RealTimingInterval
496                                                                                         =
497                                                                                         (unsigned int)
498                                                                                         (ul_TimerValue
499                                                                                         /
500                                                                                         (1000000.0
501                                                                                                 *
502                                                                                                 (double)
503                                                                                                 b_PCIInputClock));
504                                                                                 d_RealTimingInterval
505                                                                                         =
506                                                                                         (double)
507                                                                                         ul_TimerValue
508                                                                                         /
509                                                                                         (1000000.0
510                                                                                         *
511                                                                                         (double)
512                                                                                         b_PCIInputClock);
513
514                                                                                 if ((double)((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
515                                                                                         ul_RealTimingInterval
516                                                                                                 =
517                                                                                                 ul_RealTimingInterval
518                                                                                                 +
519                                                                                                 1;
520                                                                                 }
521
522                                                                                 ul_TimingInterval
523                                                                                         =
524                                                                                         ul_TimingInterval
525                                                                                         -
526                                                                                         1;
527                                                                                 ul_TimerValue
528                                                                                         =
529                                                                                         ul_TimerValue
530                                                                                         -
531                                                                                         2;
532                                                                                 if (b_PCIInputClock != APCI1710_40MHZ) {
533                                                                                         ul_TimerValue
534                                                                                                 =
535                                                                                                 (unsigned int)
536                                                                                                 (
537                                                                                                 (double)
538                                                                                                 (ul_TimerValue)
539                                                                                                 *
540                                                                                                 0.99392);
541                                                                                 }
542
543                                                                                 break;
544
545                                    /******/
546                                                                                 /* mn */
547                                    /******/
548
549                                                                         case 4:
550
551                                            /******************/
552                                                                                 /* Timer 0 factor */
553                                            /******************/
554
555                                                                                 ul_TimerValue
556                                                                                         =
557                                                                                         (unsigned int)
558                                                                                         (
559                                                                                         (ul_TimingInterval
560                                                                                                 *
561                                                                                                 60)
562                                                                                         *
563                                                                                         (1000000.0
564                                                                                                 *
565                                                                                                 b_PCIInputClock));
566
567                                            /*******************/
568                                                                                 /* Round the value */
569                                            /*******************/
570
571                                                                                 if ((double)((double)(ul_TimingInterval * 60.0) * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
572                                                                                         ul_TimerValue
573                                                                                                 =
574                                                                                                 ul_TimerValue
575                                                                                                 +
576                                                                                                 1;
577                                                                                 }
578
579                                            /*****************************/
580                                                                                 /* Calculate the real timing */
581                                            /*****************************/
582
583                                                                                 ul_RealTimingInterval
584                                                                                         =
585                                                                                         (unsigned int)
586                                                                                         (ul_TimerValue
587                                                                                         /
588                                                                                         (1000000.0
589                                                                                                 *
590                                                                                                 (double)
591                                                                                                 b_PCIInputClock))
592                                                                                         /
593                                                                                         60;
594                                                                                 d_RealTimingInterval
595                                                                                         =
596                                                                                         (
597                                                                                         (double)
598                                                                                         ul_TimerValue
599                                                                                         /
600                                                                                         (0.001 * (double)b_PCIInputClock)) / 60.0;
601
602                                                                                 if ((double)(((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
603                                                                                         ul_RealTimingInterval
604                                                                                                 =
605                                                                                                 ul_RealTimingInterval
606                                                                                                 +
607                                                                                                 1;
608                                                                                 }
609
610                                                                                 ul_TimingInterval
611                                                                                         =
612                                                                                         ul_TimingInterval
613                                                                                         -
614                                                                                         1;
615                                                                                 ul_TimerValue
616                                                                                         =
617                                                                                         ul_TimerValue
618                                                                                         -
619                                                                                         2;
620                                                                                 if (b_PCIInputClock != APCI1710_40MHZ) {
621                                                                                         ul_TimerValue
622                                                                                                 =
623                                                                                                 (unsigned int)
624                                                                                                 (
625                                                                                                 (double)
626                                                                                                 (ul_TimerValue)
627                                                                                                 *
628                                                                                                 0.99392);
629                                                                                 }
630
631                                                                                 break;
632                                                                         }
633
634                                                                         fpu_end();
635
636                                 /****************************/
637                                                                         /* Save the PCI input clock */
638                                 /****************************/
639
640                                                                         devpriv->
641                                                                                 s_ModuleInfo
642                                                                                 [b_ModulNbr].
643                                                                                 s_ChronoModuleInfo.
644                                                                                 b_PCIInputClock
645                                                                                 =
646                                                                                 b_PCIInputClock;
647
648                                 /*************************/
649                                                                         /* Save the timing unity */
650                                 /*************************/
651
652                                                                         devpriv->
653                                                                                 s_ModuleInfo
654                                                                                 [b_ModulNbr].
655                                                                                 s_ChronoModuleInfo.
656                                                                                 b_TimingUnit
657                                                                                 =
658                                                                                 b_TimingUnit;
659
660                                 /************************/
661                                                                         /* Save the base timing */
662                                 /************************/
663
664                                                                         devpriv->
665                                                                                 s_ModuleInfo
666                                                                                 [b_ModulNbr].
667                                                                                 s_ChronoModuleInfo.
668                                                                                 d_TimingInterval
669                                                                                 =
670                                                                                 d_RealTimingInterval;
671
672                                 /****************************/
673                                                                         /* Set the chronometer mode */
674                                 /****************************/
675
676                                                                         devpriv->
677                                                                                 s_ModuleInfo
678                                                                                 [b_ModulNbr].
679                                                                                 s_ChronoModuleInfo.
680                                                                                 dw_ConfigReg
681                                                                                 =
682                                                                                 dw_ModeArray
683                                                                                 [b_ChronoMode];
684
685                                 /***********************/
686                                                                         /* Test if 40 MHz used */
687                                 /***********************/
688
689                                                                         if (b_PCIInputClock == APCI1710_40MHZ) {
690                                                                                 devpriv->
691                                                                                         s_ModuleInfo
692                                                                                         [b_ModulNbr].
693                                                                                         s_ChronoModuleInfo.
694                                                                                         dw_ConfigReg
695                                                                                         =
696                                                                                         devpriv->
697                                                                                         s_ModuleInfo
698                                                                                         [b_ModulNbr].
699                                                                                         s_ChronoModuleInfo.
700                                                                                         dw_ConfigReg
701                                                                                         |
702                                                                                         0x80;
703                                                                         }
704
705                                                                         outl(devpriv->s_ModuleInfo[b_ModulNbr].s_ChronoModuleInfo.dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 16 + (64 * b_ModulNbr));
706
707                                 /***********************/
708                                                                         /* Write timer 0 value */
709                                 /***********************/
710
711                                                                         outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
712
713                                 /*********************/
714                                                                         /* Chronometer init. */
715                                 /*********************/
716
717                                                                         devpriv->
718                                                                                 s_ModuleInfo
719                                                                                 [b_ModulNbr].
720                                                                                 s_ChronoModuleInfo.
721                                                                                 b_ChronoInit
722                                                                                 =
723                                                                                 1;
724                                                                 } else {
725                                 /***********************************************/
726                                                                         /* TOR version error for 40MHz clock selection */
727                                 /***********************************************/
728
729                                                                         DPRINTK("TOR version error for 40MHz clock selection\n");
730                                                                         i_ReturnValue
731                                                                                 =
732                                                                                 -9;
733                                                                 }
734                                                         } else {
735                              /**************************************************************/
736                                                                 /* You can not use the 40MHz clock selection with this board */
737                              /**************************************************************/
738
739                                                                 DPRINTK("You can not used the 40MHz clock selection with this board\n");
740                                                                 i_ReturnValue =
741                                                                         -8;
742                                                         }
743                                                 } else {
744                           /**********************************/
745                                                         /* Base timing selection is wrong */
746                           /**********************************/
747
748                                                         DPRINTK("Base timing selection is wrong\n");
749                                                         i_ReturnValue = -7;
750                                                 }
751                                         }       /*  if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
752                                         else {
753                        /***********************************/
754                                                 /* Timing unity selection is wrong */
755                        /***********************************/
756
757                                                 DPRINTK("Timing unity selection is wrong\n");
758                                                 i_ReturnValue = -6;
759                                         }       /*  if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
760                                 }       /*  if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */
761                                 else {
762                     /*****************************************/
763                                         /* The selected PCI input clock is wrong */
764                     /*****************************************/
765
766                                         DPRINTK("The selected PCI input clock is wrong\n");
767                                         i_ReturnValue = -5;
768                                 }       /*  if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) */
769                         }       /*  if (b_ChronoMode >= 0 && b_ChronoMode <= 7) */
770                         else {
771                  /***************************************/
772                                 /* Chronometer mode selection is wrong */
773                  /***************************************/
774
775                                 DPRINTK("Chronometer mode selection is wrong\n");
776                                 i_ReturnValue = -4;
777                         }       /*  if (b_ChronoMode >= 0 && b_ChronoMode <= 7) */
778                 } else {
779               /******************************************/
780                         /* The module is not a Chronometer module */
781               /******************************************/
782
783                         DPRINTK("The module is not a Chronometer module\n");
784                         i_ReturnValue = -3;
785                 }
786         } else {
787            /***********************/
788                 /* Module number error */
789            /***********************/
790
791                 DPRINTK("Module number error\n");
792                 i_ReturnValue = -2;
793         }
794         data[0] = ul_RealTimingInterval;
795         return i_ReturnValue;
796 }
797
798 /*
799 +----------------------------------------------------------------------------+
800 | Function Name     : _INT_ i_APCI1710_EnableChrono                          |
801 |                                               (unsigned char_ b_BoardHandle,        |
802 |                                                unsigned char_ b_ModulNbr,           |
803 |                                                unsigned char_ b_CycleMode,          |
804 |                                                unsigned char_ b_InterruptEnable)
805 int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
806 struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)                                          |
807 +----------------------------------------------------------------------------+
808 | Task              : Enable the chronometer from selected module            |
809 |                     (b_ModulNbr). You must calling the                     |
810 |                     "i_APCI1710_InitChrono" function be for you call this  |
811 |                     function.                                              |
812 |                     If you enable the chronometer interrupt, the           |
813 |                     chronometer generate a interrupt after the stop signal.|
814 |                     See function "i_APCI1710_SetBoardIntRoutineX" and the  |
815 |                     Interrupt mask description chapter from this manual.   |
816 |                     The b_CycleMode parameter determine if you will        |
817 |                     measured a single or more cycle.
818
819 |                                         Disable the chronometer from selected module           |
820 |                     (b_ModulNbr). If you disable the chronometer after a   |
821 |                     start signal occur and you restart the chronometer     |
822 |                     witch the " i_APCI1710_EnableChrono" function, if no   |
823 |                     stop signal occur this start signal is ignored.
824 +----------------------------------------------------------------------------+
825 | Input Parameters  : unsigned char_ b_BoardHandle  : Handle of board APCI-1710       |
826 |                     unsigned char_ b_ModulNbr   CR_AREF(chanspec)  : Selected module number (0 to 3) |
827                                   data[0]  ENABle/Disable chrono
828 |                     unsigned char_ b_CycleMode    : Selected the chronometer        |
829 |                                  data[1]           acquisition mode                |
830 |                     unsigned char_ b_InterruptEnable : Enable or disable the        |
831 |                                   data[2]            chronometer interrupt.       |
832 |                                               APCI1710_ENABLE:             |
833 |                                               Enable the chronometer       |
834 |                                               interrupt                    |
835 |                                               APCI1710_DISABLE:            |
836 |                                               Disable the chronometer      |
837 |                                               interrupt                    |
838 +----------------------------------------------------------------------------+
839 | Output Parameters : -                                                      |
840 +----------------------------------------------------------------------------+
841 | Return Value      :  0: No error                                           |
842 |                     -1: The handle parameter of the board is wrong         |
843 |                     -2: Module selection wrong                             |
844 |                     -3: The module is not a Chronometer module             |
845 |                     -4: Chronometer not initialised see function           |
846 |                         "i_APCI1710_InitChrono"                            |
847 |                     -5: Chronometer acquisition mode cycle is wrong        |
848 |                     -6: Interrupt parameter is wrong                       |
849 |                     -7: Interrupt function not initialised.                |
850 |                         See function "i_APCI1710_SetBoardIntRoutineX"
851                       -8: data[0] wrong input    |
852 +----------------------------------------------------------------------------+
853 */
854 static int i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
855                                                    struct comedi_subdevice *s,
856                                                    struct comedi_insn *insn,
857                                                    unsigned int *data)
858 {
859         struct addi_private *devpriv = dev->private;
860         int i_ReturnValue = 0;
861         unsigned char b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action;
862         b_ModulNbr = CR_AREF(insn->chanspec);
863         b_Action = (unsigned char) data[0];
864         b_CycleMode = (unsigned char) data[1];
865         b_InterruptEnable = (unsigned char) data[2];
866         i_ReturnValue = insn->n;
867
868         /**************************/
869         /* Test the module number */
870         /**************************/
871
872         if (b_ModulNbr < 4) {
873            /***********************/
874                 /* Test if chronometer */
875            /***********************/
876
877                 if ((devpriv->s_BoardInfos.
878                                 dw_MolduleConfiguration[b_ModulNbr] &
879                                 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
880               /***********************************/
881                         /* Test if chronometer initialised */
882               /***********************************/
883
884                         if (devpriv->s_ModuleInfo[b_ModulNbr].
885                                 s_ChronoModuleInfo.b_ChronoInit == 1) {
886
887                                 switch (b_Action) {
888
889                                 case APCI1710_ENABLE:
890
891                  /*********************************/
892                                         /* Test the cycle mode parameter */
893                  /*********************************/
894
895                                         if ((b_CycleMode == APCI1710_SINGLE)
896                                                 || (b_CycleMode ==
897                                                         APCI1710_CONTINUOUS)) {
898                     /***************************/
899                                                 /* Test the interrupt flag */
900                     /***************************/
901
902                                                 if ((b_InterruptEnable ==
903                                                                 APCI1710_ENABLE)
904                                                         || (b_InterruptEnable ==
905                                                                 APCI1710_DISABLE))
906                                                 {
907
908                           /***************************/
909                                                         /* Save the interrupt flag */
910                           /***************************/
911
912                                                         devpriv->
913                                                                 s_ModuleInfo
914                                                                 [b_ModulNbr].
915                                                                 s_ChronoModuleInfo.
916                                                                 b_InterruptMask
917                                                                 =
918                                                                 b_InterruptEnable;
919
920                           /***********************/
921                                                         /* Save the cycle mode */
922                           /***********************/
923
924                                                         devpriv->
925                                                                 s_ModuleInfo
926                                                                 [b_ModulNbr].
927                                                                 s_ChronoModuleInfo.
928                                                                 b_CycleMode =
929                                                                 b_CycleMode;
930
931                                                         devpriv->
932                                                                 s_ModuleInfo
933                                                                 [b_ModulNbr].
934                                                                 s_ChronoModuleInfo.
935                                                                 dw_ConfigReg =
936                                                                 (devpriv->
937                                                                 s_ModuleInfo
938                                                                 [b_ModulNbr].
939                                                                 s_ChronoModuleInfo.
940                                                                 dw_ConfigReg &
941                                                                 0x8F) | ((1 &
942                                                                         b_InterruptEnable)
943                                                                 << 5) | ((1 &
944                                                                         b_CycleMode)
945                                                                 << 6) | 0x10;
946
947                           /*****************************/
948                                                         /* Test if interrupt enabled */
949                           /*****************************/
950
951                                                         if (b_InterruptEnable ==
952                                                                 APCI1710_ENABLE)
953                                                         {
954                              /****************************/
955                                                                 /* Clear the interrupt flag */
956                              /****************************/
957
958                                                                 outl(devpriv->
959                                                                         s_ModuleInfo
960                                                                         [b_ModulNbr].
961                                                                         s_ChronoModuleInfo.
962                                                                         dw_ConfigReg,
963                                                                         devpriv->
964                                                                         s_BoardInfos.
965                                                                         ui_Address
966                                                                         + 32 +
967                                                                         (64 * b_ModulNbr));
968                                                                 devpriv->tsk_Current = current; /*  Save the current process task structure */
969                                                         }
970
971                           /***********************************/
972                                                         /* Enable or disable the interrupt */
973                                                         /* Enable the chronometer          */
974                           /***********************************/
975
976                                                         outl(devpriv->
977                                                                 s_ModuleInfo
978                                                                 [b_ModulNbr].
979                                                                 s_ChronoModuleInfo.
980                                                                 dw_ConfigReg,
981                                                                 devpriv->
982                                                                 s_BoardInfos.
983                                                                 ui_Address +
984                                                                 16 +
985                                                                 (64 * b_ModulNbr));
986
987                           /*************************/
988                                                         /* Clear status register */
989                           /*************************/
990
991                                                         outl(0, devpriv->
992                                                                 s_BoardInfos.
993                                                                 ui_Address +
994                                                                 36 +
995                                                                 (64 * b_ModulNbr));
996
997                                                 }       /*  if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) */
998                                                 else {
999                        /********************************/
1000                                                         /* Interrupt parameter is wrong */
1001                        /********************************/
1002
1003                                                         DPRINTK("Interrupt parameter is wrong\n");
1004                                                         i_ReturnValue = -6;
1005                                                 }       /*  if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) */
1006                                         }       /*  if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */
1007                                         else {
1008                     /***********************************************/
1009                                                 /* Chronometer acquisition mode cycle is wrong */
1010                     /***********************************************/
1011
1012                                                 DPRINTK("Chronometer acquisition mode cycle is wrong\n");
1013                                                 i_ReturnValue = -5;
1014                                         }       /*  if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) */
1015                                         break;
1016
1017                                 case APCI1710_DISABLE:
1018
1019                                         devpriv->s_ModuleInfo[b_ModulNbr].
1020                                                 s_ChronoModuleInfo.
1021                                                 b_InterruptMask = 0;
1022
1023                                         devpriv->s_ModuleInfo[b_ModulNbr].
1024                                                 s_ChronoModuleInfo.
1025                                                 dw_ConfigReg =
1026                                                 devpriv->
1027                                                 s_ModuleInfo[b_ModulNbr].
1028                                                 s_ChronoModuleInfo.
1029                                                 dw_ConfigReg & 0x2F;
1030
1031                  /***************************/
1032                                         /* Disable the interrupt   */
1033                                         /* Disable the chronometer */
1034                  /***************************/
1035
1036                                         outl(devpriv->s_ModuleInfo[b_ModulNbr].
1037                                                 s_ChronoModuleInfo.dw_ConfigReg,
1038                                                 devpriv->s_BoardInfos.
1039                                                 ui_Address + 16 +
1040                                                 (64 * b_ModulNbr));
1041
1042                  /***************************/
1043                                         /* Test if continuous mode */
1044                  /***************************/
1045
1046                                         if (devpriv->s_ModuleInfo[b_ModulNbr].
1047                                                 s_ChronoModuleInfo.
1048                                                 b_CycleMode ==
1049                                                 APCI1710_CONTINUOUS) {
1050                     /*************************/
1051                                                 /* Clear status register */
1052                     /*************************/
1053
1054                                                 outl(0, devpriv->s_BoardInfos.
1055                                                         ui_Address + 36 +
1056                                                         (64 * b_ModulNbr));
1057                                         }
1058                                         break;
1059
1060                                 default:
1061                                         DPRINTK("Inputs wrong! Enable or Disable chrono\n");
1062                                         i_ReturnValue = -8;
1063                                 }       /*  switch ENABLE/DISABLE */
1064                         } else {
1065                  /*******************************/
1066                                 /* Chronometer not initialised */
1067                  /*******************************/
1068
1069                                 DPRINTK("Chronometer not initialised\n");
1070                                 i_ReturnValue = -4;
1071                         }
1072                 } else {
1073               /******************************************/
1074                         /* The module is not a Chronometer module */
1075               /******************************************/
1076
1077                         DPRINTK("The module is not a Chronometer module\n");
1078                         i_ReturnValue = -3;
1079                 }
1080         } else {
1081            /***********************/
1082                 /* Module number error */
1083            /***********************/
1084
1085                 DPRINTK("Module number error\n");
1086                 i_ReturnValue = -2;
1087         }
1088
1089         return i_ReturnValue;
1090 }
1091
1092 /*
1093 +----------------------------------------------------------------------------+
1094 | Function Name     : _INT_ i_APCI1710_GetChronoProgressStatus               |
1095 |                               (unsigned char_    b_BoardHandle,                     |
1096 |                                unsigned char_    b_ModulNbr,                        |
1097 |                                unsigned char *_  pb_ChronoStatus)                    |
1098 +----------------------------------------------------------------------------+
1099 | Task              : Return the chronometer status (pb_ChronoStatus) from   |
1100 |                     selected chronometer module (b_ModulNbr).              |
1101 +----------------------------------------------------------------------------+
1102 | Input Parameters  : unsigned char_ b_BoardHandle  : Handle of board APCI-1710       |
1103 |                     unsigned char_ b_ModulNbr     : Selected module number (0 to 3) |
1104 +----------------------------------------------------------------------------+
1105 | Output Parameters : PULONG_  pb_ChronoStatus : Return the chronometer      |
1106 |                                                status.                     |
1107 |                                                0 : Measurement not started.|
1108 |                                                    No start signal occur.  |
1109 |                                                1 : Measurement started.    |
1110 |                                                    A start signal occur.   |
1111 |                                                2 : Measurement stopped.    |
1112 |                                                    A stop signal occur.    |
1113 |                                                    The measurement is      |
1114 |                                                    terminate.              |
1115 |                                                3: A overflow occur. You    |
1116 |                                                   must change the base     |
1117 |                                                   timing witch the         |
1118 |                                                   function                 |
1119 |                                                   "i_APCI1710_InitChrono"  |
1120 +----------------------------------------------------------------------------+
1121 | Return Value      :  0: No error                                           |
1122 |                     -1: The handle parameter of the board is wrong         |
1123 |                     -2: Module selection wrong                             |
1124 |                     -3: The module is not a Chronometer module             |
1125 |                     -4: Chronometer not initialised see function           |
1126 |                         "i_APCI1710_InitChrono"                            |
1127 +----------------------------------------------------------------------------+
1128 */
1129 static int i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
1130                                               unsigned char b_ModulNbr,
1131                                               unsigned char *pb_ChronoStatus)
1132 {
1133         struct addi_private *devpriv = dev->private;
1134         int i_ReturnValue = 0;
1135         unsigned int dw_Status;
1136
1137         /**************************/
1138         /* Test the module number */
1139         /**************************/
1140
1141         if (b_ModulNbr < 4) {
1142            /***********************/
1143                 /* Test if chronometer */
1144            /***********************/
1145
1146                 if ((devpriv->s_BoardInfos.
1147                                 dw_MolduleConfiguration[b_ModulNbr] &
1148                                 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1149               /***********************************/
1150                         /* Test if chronometer initialised */
1151               /***********************************/
1152
1153                         if (devpriv->
1154                                 s_ModuleInfo[b_ModulNbr].
1155                                 s_ChronoModuleInfo.b_ChronoInit == 1) {
1156
1157                                 dw_Status = inl(devpriv->s_BoardInfos.
1158                                         ui_Address + 8 + (64 * b_ModulNbr));
1159
1160                  /********************/
1161                                 /* Test if overflow */
1162                  /********************/
1163
1164                                 if ((dw_Status & 8) == 8) {
1165                     /******************/
1166                                         /* Overflow occur */
1167                     /******************/
1168
1169                                         *pb_ChronoStatus = 3;
1170                                 }       /*  if ((dw_Status & 8) == 8) */
1171                                 else {
1172                     /*******************************/
1173                                         /* Test if measurement stopped */
1174                     /*******************************/
1175
1176                                         if ((dw_Status & 2) == 2) {
1177                        /***********************/
1178                                                 /* A stop signal occur */
1179                        /***********************/
1180
1181                                                 *pb_ChronoStatus = 2;
1182                                         }       /*  if ((dw_Status & 2) == 2) */
1183                                         else {
1184                        /*******************************/
1185                                                 /* Test if measurement started */
1186                        /*******************************/
1187
1188                                                 if ((dw_Status & 1) == 1) {
1189                           /************************/
1190                                                         /* A start signal occur */
1191                           /************************/
1192
1193                                                         *pb_ChronoStatus = 1;
1194                                                 }       /*  if ((dw_Status & 1) == 1) */
1195                                                 else {
1196                           /***************************/
1197                                                         /* Measurement not started */
1198                           /***************************/
1199
1200                                                         *pb_ChronoStatus = 0;
1201                                                 }       /*  if ((dw_Status & 1) == 1) */
1202                                         }       /*  if ((dw_Status & 2) == 2) */
1203                                 }       /*  if ((dw_Status & 8) == 8) */
1204                         } else {
1205                  /*******************************/
1206                                 /* Chronometer not initialised */
1207                  /*******************************/
1208                                 DPRINTK("Chronometer not initialised\n");
1209                                 i_ReturnValue = -4;
1210                         }
1211                 } else {
1212               /******************************************/
1213                         /* The module is not a Chronometer module */
1214               /******************************************/
1215                         DPRINTK("The module is not a Chronometer module\n");
1216                         i_ReturnValue = -3;
1217                 }
1218         } else {
1219            /***********************/
1220                 /* Module number error */
1221            /***********************/
1222                 DPRINTK("Module number error\n");
1223                 i_ReturnValue = -2;
1224         }
1225
1226         return i_ReturnValue;
1227 }
1228
1229 /*
1230 +----------------------------------------------------------------------------+
1231 | Function Name     : _INT_ i_APCI1710_ReadChronoValue                       |
1232 |                               (unsigned char_     b_BoardHandle,                    |
1233 |                                unsigned char_     b_ModulNbr,                       |
1234 |                                unsigned int_    ui_TimeOut,                        |
1235 |                                unsigned char *_   pb_ChronoStatus,                   |
1236 |                                PULONG_ pul_ChronoValue)                    |
1237 +----------------------------------------------------------------------------+
1238 | Task              : Return the chronometer status (pb_ChronoStatus) and the|
1239 |                     timing value (pul_ChronoValue) after a stop signal     |
1240 |                     occur from selected chronometer module (b_ModulNbr).   |
1241 |                     This function are only avaible if you have disabled    |
1242 |                     the interrupt functionality. See function              |
1243 |                     "i_APCI1710_EnableChrono" and the Interrupt mask       |
1244 |                     description chapter.                                   |
1245 |                     You can test the chronometer status witch the          |
1246 |                     "i_APCI1710_GetChronoProgressStatus" function.         |
1247 |                                                                            |
1248 |                     The returned value from pul_ChronoValue parameter is   |
1249 |                     not real measured timing.                              |
1250 |                     You must used the "i_APCI1710_ConvertChronoValue"      |
1251 |                     function or make this operation for calculate the      |
1252 |                     timing:                                                |
1253 |                                                                            |
1254 |                     Timing = pul_ChronoValue * pul_RealTimingInterval.     |
1255 |                                                                            |
1256 |                     pul_RealTimingInterval is the returned parameter from  |
1257 |                     "i_APCI1710_InitChrono" function and the time unity is |
1258 |                     the b_TimingUnit from "i_APCI1710_InitChrono" function|
1259 +----------------------------------------------------------------------------+
1260 | Input Parameters  : unsigned char_ b_BoardHandle  : Handle of board APCI-1710       |
1261 |                     unsigned char_ b_ModulNbr     : Selected module number (0 to 3) |
1262 +----------------------------------------------------------------------------+
1263 | Output Parameters : PULONG_  pb_ChronoStatus : Return the chronometer      |
1264 |                                                status.                     |
1265 |                                                0 : Measurement not started.|
1266 |                                                    No start signal occur.  |
1267 |                                                1 : Measurement started.    |
1268 |                                                    A start signal occur.   |
1269 |                                                2 : Measurement stopped.    |
1270 |                                                    A stop signal occur.    |
1271 |                                                    The measurement is      |
1272 |                                                    terminate.              |
1273 |                                                3: A overflow occur. You    |
1274 |                                                   must change the base     |
1275 |                                                   timing witch the         |
1276 |                                                   function                 |
1277 |                                                   "i_APCI1710_InitChrono"  |
1278 |                     unsigned int *  pul_ChronoValue  : Chronometer timing value.   |
1279 +----------------------------------------------------------------------------+
1280 | Return Value      :  0: No error                                           |
1281 |                     -1: The handle parameter of the board is wrong         |
1282 |                     -2: Module selection wrong                             |
1283 |                     -3: The module is not a Chronometer module             |
1284 |                     -4: Chronometer not initialised see function           |
1285 |                         "i_APCI1710_InitChrono"                            |
1286 |                     -5: Timeout parameter is wrong (0 to 65535)            |
1287 |                     -6: Interrupt routine installed. You can not read      |
1288 |                         directly the chronometer measured timing.          |
1289 +----------------------------------------------------------------------------+
1290 */
1291 static int i_APCI1710_ReadChronoValue(struct comedi_device *dev,
1292                                       unsigned char b_ModulNbr,
1293                                       unsigned int ui_TimeOut,
1294                                       unsigned char *pb_ChronoStatus,
1295                                       unsigned int *pul_ChronoValue)
1296 {
1297         struct addi_private *devpriv = dev->private;
1298         int i_ReturnValue = 0;
1299         unsigned int dw_Status;
1300         unsigned int dw_TimeOut = 0;
1301
1302         /**************************/
1303         /* Test the module number */
1304         /**************************/
1305
1306         if (b_ModulNbr < 4) {
1307            /***********************/
1308                 /* Test if chronometer */
1309            /***********************/
1310
1311                 if ((devpriv->s_BoardInfos.
1312                                 dw_MolduleConfiguration[b_ModulNbr] &
1313                                 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1314               /***********************************/
1315                         /* Test if chronometer initialised */
1316               /***********************************/
1317
1318                         if (devpriv->
1319                                 s_ModuleInfo[b_ModulNbr].
1320                                 s_ChronoModuleInfo.b_ChronoInit == 1) {
1321                  /*****************************/
1322                                 /* Test the timout parameter */
1323                  /*****************************/
1324
1325                                 if (ui_TimeOut <= 65535UL) {
1326
1327                                         for (;;) {
1328                           /*******************/
1329                                                 /* Read the status */
1330                           /*******************/
1331
1332                                                 dw_Status =
1333                                                         inl(devpriv->
1334                                                         s_BoardInfos.
1335                                                         ui_Address + 8 +
1336                                                         (64 * b_ModulNbr));
1337
1338                           /********************/
1339                                                 /* Test if overflow */
1340                           /********************/
1341
1342                                                 if ((dw_Status & 8) == 8) {
1343                              /******************/
1344                                                         /* Overflow occur */
1345                              /******************/
1346
1347                                                         *pb_ChronoStatus = 3;
1348
1349                              /***************************/
1350                                                         /* Test if continuous mode */
1351                              /***************************/
1352
1353                                                         if (devpriv->
1354                                                                 s_ModuleInfo
1355                                                                 [b_ModulNbr].
1356                                                                 s_ChronoModuleInfo.
1357                                                                 b_CycleMode ==
1358                                                                 APCI1710_CONTINUOUS)
1359                                                         {
1360                                 /*************************/
1361                                                                 /* Clear status register */
1362                                 /*************************/
1363
1364                                                                 outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
1365                                                         }
1366
1367                                                         break;
1368                                                 }       /*  if ((dw_Status & 8) == 8) */
1369                                                 else {
1370                              /*******************************/
1371                                                         /* Test if measurement stopped */
1372                              /*******************************/
1373
1374                                                         if ((dw_Status & 2) ==
1375                                                                 2) {
1376                                 /***********************/
1377                                                                 /* A stop signal occur */
1378                                 /***********************/
1379
1380                                                                 *pb_ChronoStatus
1381                                                                         = 2;
1382
1383                                 /***************************/
1384                                                                 /* Test if continnous mode */
1385                                 /***************************/
1386
1387                                                                 if (devpriv->
1388                                                                         s_ModuleInfo
1389                                                                         [b_ModulNbr].
1390                                                                         s_ChronoModuleInfo.
1391                                                                         b_CycleMode
1392                                                                         ==
1393                                                                         APCI1710_CONTINUOUS)
1394                                                                 {
1395                                    /*************************/
1396                                                                         /* Clear status register */
1397                                    /*************************/
1398
1399                                                                         outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
1400                                                                 }
1401                                                                 break;
1402                                                         }       /*  if ((dw_Status & 2) == 2) */
1403                                                         else {
1404                                 /*******************************/
1405                                                                 /* Test if measurement started */
1406                                 /*******************************/
1407
1408                                                                 if ((dw_Status & 1) == 1) {
1409                                    /************************/
1410                                                                         /* A start signal occur */
1411                                    /************************/
1412
1413                                                                         *pb_ChronoStatus
1414                                                                                 =
1415                                                                                 1;
1416                                                                 }       /*  if ((dw_Status & 1) == 1) */
1417                                                                 else {
1418                                    /***************************/
1419                                                                         /* Measurement not started */
1420                                    /***************************/
1421
1422                                                                         *pb_ChronoStatus
1423                                                                                 =
1424                                                                                 0;
1425                                                                 }       /*  if ((dw_Status & 1) == 1) */
1426                                                         }       /*  if ((dw_Status & 2) == 2) */
1427                                                 }       /*  if ((dw_Status & 8) == 8) */
1428
1429                                                 if (dw_TimeOut == ui_TimeOut) {
1430                              /*****************/
1431                                                         /* Timeout occur */
1432                              /*****************/
1433
1434                                                         break;
1435                                                 } else {
1436                              /*************************/
1437                                                         /* Increment the timeout */
1438                              /*************************/
1439
1440                                                         dw_TimeOut =
1441                                                                 dw_TimeOut + 1;
1442                                                         mdelay(1000);
1443
1444                                                 }
1445                                         }       /*  for (;;) */
1446
1447                        /*****************************/
1448                                         /* Test if stop signal occur */
1449                        /*****************************/
1450
1451                                         if (*pb_ChronoStatus == 2) {
1452                           /**********************************/
1453                                                 /* Read the measured timing value */
1454                           /**********************************/
1455
1456                                                 *pul_ChronoValue =
1457                                                         inl(devpriv->
1458                                                         s_BoardInfos.
1459                                                         ui_Address + 4 +
1460                                                         (64 * b_ModulNbr));
1461
1462                                                 if (*pul_ChronoValue != 0) {
1463                                                         *pul_ChronoValue =
1464                                                                 *pul_ChronoValue
1465                                                                 - 1;
1466                                                 }
1467                                         } else {
1468                           /*************************/
1469                                                 /* Test if timeout occur */
1470                           /*************************/
1471
1472                                                 if ((*pb_ChronoStatus != 3)
1473                                                         && (dw_TimeOut ==
1474                                                                 ui_TimeOut)
1475                                                         && (ui_TimeOut != 0)) {
1476                              /*****************/
1477                                                         /* Timeout occur */
1478                              /*****************/
1479
1480                                                         *pb_ChronoStatus = 4;
1481                                                 }
1482                                         }
1483
1484                                 } else {
1485                     /******************************/
1486                                         /* Timeout parameter is wrong */
1487                     /******************************/
1488                                         DPRINTK("Timeout parameter is wrong\n");
1489                                         i_ReturnValue = -5;
1490                                 }
1491                         } else {
1492                  /*******************************/
1493                                 /* Chronometer not initialised */
1494                  /*******************************/
1495                                 DPRINTK("Chronometer not initialised\n");
1496                                 i_ReturnValue = -4;
1497                         }
1498                 } else {
1499               /******************************************/
1500                         /* The module is not a Chronometer module */
1501               /******************************************/
1502                         DPRINTK("The module is not a Chronometer module\n");
1503                         i_ReturnValue = -3;
1504                 }
1505         } else {
1506            /***********************/
1507                 /* Module number error */
1508            /***********************/
1509                 DPRINTK("Module number error\n");
1510                 i_ReturnValue = -2;
1511         }
1512
1513         return i_ReturnValue;
1514 }
1515
1516 /*
1517 +----------------------------------------------------------------------------+
1518 | Function Name     : _INT_ i_APCI1710_ConvertChronoValue                    |
1519 |                               (unsigned char_     b_BoardHandle,                    |
1520 |                                unsigned char_     b_ModulNbr,                       |
1521 |                                ULONG_   ul_ChronoValue,                    |
1522 |                                PULONG_ pul_Hour,                           |
1523 |                                unsigned char *_   pb_Minute,                         |
1524 |                                unsigned char *_   pb_Second,                         |
1525 |                                unsigned int *_  pui_MilliSecond,                    |
1526 |                                unsigned int *_  pui_MicroSecond,                    |
1527 |                                unsigned int *_  pui_NanoSecond)                     |
1528 +----------------------------------------------------------------------------+
1529 | Task              : Convert the chronometer measured timing                |
1530 |                     (ul_ChronoValue) in to h, mn, s, ms, µs, ns.           |
1531 +----------------------------------------------------------------------------+
1532 | Input Parameters  : unsigned char_   b_BoardHandle : Handle of board APCI-1710      |
1533 |                     unsigned char_   b_ModulNbr    : Selected module number (0 to 3)|
1534 |                     ULONG_ ul_ChronoValue : Measured chronometer timing    |
1535 |                                             value.                         |
1536 |                                             See"i_APCI1710_ReadChronoValue"|
1537 +----------------------------------------------------------------------------+
1538 | Output Parameters : PULONG_   pul_Hour        : Chronometer timing hour    |
1539 |                     unsigned char *_     pb_Minute      : Chronometer timing minute  |
1540 |                     unsigned char *_     pb_Second      : Chronometer timing second  |
1541 |                     unsigned int *_    pui_MilliSecond  : Chronometer timing mini   |
1542 |                                                 second                     |
1543 |                     unsigned int *_    pui_MicroSecond : Chronometer timing micro   |
1544 |                                                 second                     |
1545 |                     unsigned int *_    pui_NanoSecond  : Chronometer timing nano    |
1546 |                                                 second                     |
1547 +----------------------------------------------------------------------------+
1548 | Return Value      :  0: No error                                           |
1549 |                     -1: The handle parameter of the board is wrong         |
1550 |                     -2: Module selection wrong                             |
1551 |                     -3: The module is not a Chronometer module             |
1552 |                     -4: Chronometer not initialised see function           |
1553 |                         "i_APCI1710_InitChrono"                            |
1554 +----------------------------------------------------------------------------+
1555 */
1556 static int i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
1557                                          unsigned char b_ModulNbr,
1558                                          unsigned int ul_ChronoValue,
1559                                          unsigned int *pul_Hour,
1560                                          unsigned char *pb_Minute,
1561                                          unsigned char *pb_Second,
1562                                          unsigned int *pui_MilliSecond,
1563                                          unsigned int *pui_MicroSecond,
1564                                          unsigned int *pui_NanoSecond)
1565 {
1566         struct addi_private *devpriv = dev->private;
1567         int i_ReturnValue = 0;
1568         double d_Hour;
1569         double d_Minute;
1570         double d_Second;
1571         double d_MilliSecond;
1572         double d_MicroSecond;
1573         double d_NanoSecond;
1574
1575         /**************************/
1576         /* Test the module number */
1577         /**************************/
1578
1579         if (b_ModulNbr < 4) {
1580            /***********************/
1581                 /* Test if chronometer */
1582            /***********************/
1583
1584                 if ((devpriv->s_BoardInfos.
1585                                 dw_MolduleConfiguration[b_ModulNbr] &
1586                                 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1587               /***********************************/
1588                         /* Test if chronometer initialised */
1589               /***********************************/
1590
1591                         if (devpriv->
1592                                 s_ModuleInfo[b_ModulNbr].
1593                                 s_ChronoModuleInfo.b_ChronoInit == 1) {
1594                                 fpu_begin();
1595
1596                                 d_Hour = (double)ul_ChronoValue *(double)
1597                                         devpriv->s_ModuleInfo[b_ModulNbr].
1598                                         s_ChronoModuleInfo.d_TimingInterval;
1599
1600                                 switch (devpriv->
1601                                         s_ModuleInfo[b_ModulNbr].
1602                                         s_ChronoModuleInfo.b_TimingUnit) {
1603                                 case 0:
1604                                         d_Hour = d_Hour / (double)1000.0;
1605
1606                                 case 1:
1607                                         d_Hour = d_Hour / (double)1000.0;
1608
1609                                 case 2:
1610                                         d_Hour = d_Hour / (double)1000.0;
1611
1612                                 case 3:
1613                                         d_Hour = d_Hour / (double)60.0;
1614
1615                                 case 4:
1616                             /**********************/
1617                                         /* Calculate the hour */
1618                             /**********************/
1619
1620                                         d_Hour = d_Hour / (double)60.0;
1621                                         *pul_Hour = (unsigned int) d_Hour;
1622
1623                             /************************/
1624                                         /* Calculate the minute */
1625                             /************************/
1626
1627                                         d_Minute = d_Hour - *pul_Hour;
1628                                         d_Minute = d_Minute * 60;
1629                                         *pb_Minute = (unsigned char) d_Minute;
1630
1631                             /************************/
1632                                         /* Calculate the second */
1633                             /************************/
1634
1635                                         d_Second = d_Minute - *pb_Minute;
1636                                         d_Second = d_Second * 60;
1637                                         *pb_Second = (unsigned char) d_Second;
1638
1639                             /*****************************/
1640                                         /* Calculate the mini second */
1641                             /*****************************/
1642
1643                                         d_MilliSecond = d_Second - *pb_Second;
1644                                         d_MilliSecond = d_MilliSecond * 1000;
1645                                         *pui_MilliSecond = (unsigned int) d_MilliSecond;
1646
1647                             /******************************/
1648                                         /* Calculate the micro second */
1649                             /******************************/
1650
1651                                         d_MicroSecond =
1652                                                 d_MilliSecond -
1653                                                 *pui_MilliSecond;
1654                                         d_MicroSecond = d_MicroSecond * 1000;
1655                                         *pui_MicroSecond = (unsigned int) d_MicroSecond;
1656
1657                             /******************************/
1658                                         /* Calculate the micro second */
1659                             /******************************/
1660
1661                                         d_NanoSecond =
1662                                                 d_MicroSecond -
1663                                                 *pui_MicroSecond;
1664                                         d_NanoSecond = d_NanoSecond * 1000;
1665                                         *pui_NanoSecond = (unsigned int) d_NanoSecond;
1666                                         break;
1667                                 }
1668
1669                                 fpu_end();
1670                         } else {
1671                  /*******************************/
1672                                 /* Chronometer not initialised */
1673                  /*******************************/
1674                                 DPRINTK("Chronometer not initialised\n");
1675                                 i_ReturnValue = -4;
1676                         }
1677                 } else {
1678               /******************************************/
1679                         /* The module is not a Chronometer module */
1680               /******************************************/
1681                         DPRINTK("The module is not a Chronometer module\n");
1682                         i_ReturnValue = -3;
1683                 }
1684         } else {
1685            /***********************/
1686                 /* Module number error */
1687            /***********************/
1688                 DPRINTK("Module number error\n");
1689                 i_ReturnValue = -2;
1690         }
1691
1692         return i_ReturnValue;
1693 }
1694
1695 /*
1696 +----------------------------------------------------------------------------+
1697 | Function Name     :INT        i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s,
1698 struct comedi_insn *insn,unsigned int *data)                   |
1699 +----------------------------------------------------------------------------+
1700 | Task              : Read  functions for Timer                                     |
1701 +----------------------------------------------------------------------------+
1702 | Input Parameters  :
1703 +----------------------------------------------------------------------------+
1704 | Output Parameters : -                                                      |
1705 +----------------------------------------------------------------------------+
1706 | Return Value      :
1707 +----------------------------------------------------------------------------+
1708 */
1709 static int i_APCI1710_InsnReadChrono(struct comedi_device *dev,
1710                                      struct comedi_subdevice *s,
1711                                      struct comedi_insn *insn,
1712                                      unsigned int *data)
1713 {
1714         struct addi_private *devpriv = dev->private;
1715         unsigned char b_ReadType;
1716         int i_ReturnValue = insn->n;
1717
1718         b_ReadType = CR_CHAN(insn->chanspec);
1719
1720         switch (b_ReadType) {
1721         case APCI1710_CHRONO_PROGRESS_STATUS:
1722                 i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev,
1723                         (unsigned char) CR_AREF(insn->chanspec), (unsigned char *) &data[0]);
1724                 break;
1725
1726         case APCI1710_CHRONO_READVALUE:
1727                 i_ReturnValue = i_APCI1710_ReadChronoValue(dev,
1728                         (unsigned char) CR_AREF(insn->chanspec),
1729                         (unsigned int) insn->unused[0],
1730                         (unsigned char *) &data[0], (unsigned int *) &data[1]);
1731                 break;
1732
1733         case APCI1710_CHRONO_CONVERTVALUE:
1734                 i_ReturnValue = i_APCI1710_ConvertChronoValue(dev,
1735                         (unsigned char) CR_AREF(insn->chanspec),
1736                         (unsigned int) insn->unused[0],
1737                         (unsigned int *) &data[0],
1738                         (unsigned char *) &data[1],
1739                         (unsigned char *) &data[2],
1740                         (unsigned int *) &data[3],
1741                         (unsigned int *) &data[4], (unsigned int *) &data[5]);
1742                 break;
1743
1744         case APCI1710_CHRONO_READINTERRUPT:
1745                 printk("In Chrono Read Interrupt\n");
1746
1747                 data[0] = devpriv->s_InterruptParameters.
1748                         s_FIFOInterruptParameters[devpriv->
1749                         s_InterruptParameters.ui_Read].b_OldModuleMask;
1750                 data[1] = devpriv->s_InterruptParameters.
1751                         s_FIFOInterruptParameters[devpriv->
1752                         s_InterruptParameters.ui_Read].ul_OldInterruptMask;
1753                 data[2] = devpriv->s_InterruptParameters.
1754                         s_FIFOInterruptParameters[devpriv->
1755                         s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
1756
1757                              /**************************/
1758                 /* Increment the read FIFO */
1759                              /***************************/
1760
1761                 devpriv->
1762                         s_InterruptParameters.
1763                         ui_Read = (devpriv->
1764                         s_InterruptParameters.
1765                         ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
1766                 break;
1767
1768         default:
1769                 printk("ReadType Parameter wrong\n");
1770         }
1771
1772         if (i_ReturnValue >= 0)
1773                 i_ReturnValue = insn->n;
1774         return i_ReturnValue;
1775
1776 }
1777
1778 /*
1779 +----------------------------------------------------------------------------+
1780 | Function Name     : int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s,
1781         struct comedi_insn *insn,unsigned int *data)                    |
1782 +----------------------------------------------------------------------------+
1783 | Task              : Sets the output witch has been passed with the         |
1784 |                     parameter b_Channel. Setting an output means setting an|
1785 |                     output high.                                           |
1786 +----------------------------------------------------------------------------+
1787 | Input Parameters  : unsigned char_ b_BoardHandle   : Handle of board APCI-1710      |
1788 |                     unsigned char_ b_ModulNbr      : Selected module number (0 to 3)|
1789 |                     unsigned char_ b_OutputChannel : Selection from digital output  |
1790 |                           CR_CHAN()                  channel (0 to 2)               |
1791 |                                              0 : Channel H                 |
1792 |                                              1 : Channel A                 |
1793 |                                              2 : Channel B                 |
1794 +----------------------------------------------------------------------------+
1795 | Output Parameters : -                                                      |
1796 +----------------------------------------------------------------------------+
1797 | Return Value      :  0: No error                                           |
1798 |                     -1: The handle parameter of the board is wrong         |
1799 |                     -2: Module selection wrong                             |
1800 |                     -3: The module is not a Chronometer module             |
1801 |                     -4: The selected digital output is wrong               |
1802 |                     -5: Chronometer not initialised see function           |
1803 |                         "i_APCI1710_InitChrono"                            |
1804 +----------------------------------------------------------------------------+
1805 */
1806
1807 /*
1808 +----------------------------------------------------------------------------+
1809 | Function Name     : _INT_ i_APCI1710_SetChronoChlOff                       |
1810 |                               (unsigned char_  b_BoardHandle,                       |
1811 |                                unsigned char_  b_ModulNbr,                          |
1812 |                                unsigned char_  b_OutputChannel)                     |
1813 +----------------------------------------------------------------------------+
1814 | Task              : Resets the output witch has been passed with the       |
1815 |                     parameter b_Channel. Resetting an output means setting |
1816 |                     an output low.                                         |
1817 +----------------------------------------------------------------------------+
1818 | Input Parameters  : unsigned char_ b_BoardHandle   : Handle of board APCI-1710
1819                         data[0] : Chl ON, Chl OFF , Chl Read , Port Read
1820
1821 |                     unsigned char_ b_ModulNbr  CR_AREF    : Selected module number (0 to 3)|
1822 |                     unsigned char_ b_OutputChannel CR_CHAN : Selection from digital output  |
1823 |                                             channel (0 to 2)               |
1824 |                                              0 : Channel H                 |
1825 |                                              1 : Channel A                 |
1826 |                                              2 : Channel B                 |
1827 +----------------------------------------------------------------------------+
1828 | Output Parameters : -                                                      |
1829 +----------------------------------------------------------------------------+
1830 | Return Value      :  0: No error                                           |
1831 |                     -1: The handle parameter of the board is wrong         |
1832 |                     -2: Module selection wrong                             |
1833 |                     -3: The module is not a Chronometer module             |
1834 |                     -4: The selected digital output is wrong               |
1835 |                     -5: Chronometer not initialised see function           |
1836 |                         "i_APCI1710_InitChrono"                            |
1837 +----------------------------------------------------------------------------+
1838 */
1839
1840 /*
1841 +----------------------------------------------------------------------------+
1842 | Function Name     : _INT_ i_APCI1710_ReadChronoChlValue                    |
1843 |                               (unsigned char_   b_BoardHandle,                      |
1844 |                                unsigned char_   b_ModulNbr,                         |
1845 |                                unsigned char_   b_InputChannel,                     |
1846 |                                unsigned char *_ pb_ChannelStatus)                    |
1847 +----------------------------------------------------------------------------+
1848 | Task              : Return the status from selected digital input          |
1849 |                     (b_InputChannel) from selected chronometer             |
1850 |                     module (b_ModulNbr).                                   |
1851 +----------------------------------------------------------------------------+
1852 | Input Parameters  : unsigned char_ b_BoardHandle   : Handle of board APCI-1710      |
1853 |                     unsigned char_ b_ModulNbr      : Selected module number (0 to 3)|
1854 |                     unsigned char_ b_InputChannel  : Selection from digital input   |
1855 |                                             channel (0 to 2)               |
1856 |                                   CR_CHAN()             0 : Channel E               |
1857 |                                                1 : Channel F               |
1858 |                                                2 : Channel G               |
1859 +----------------------------------------------------------------------------+
1860 | Output Parameters : unsigned char *_ pb_ChannelStatus : Digital input channel status.|
1861 |                                data[0]                0 : Channel is not active   |
1862 |                                                1 : Channel is active       |
1863 +----------------------------------------------------------------------------+
1864 | Return Value      :  0: No error                                           |
1865 |                     -1: The handle parameter of the board is wrong         |
1866 |                     -2: Module selection wrong                             |
1867 |                     -3: The module is not a Chronometer module             |
1868 |                     -4: The selected digital input is wrong                |
1869 |                     -5: Chronometer not initialised see function           |
1870 |                         "i_APCI1710_InitChrono"                            |
1871 +----------------------------------------------------------------------------+
1872 */
1873
1874 /*
1875 +----------------------------------------------------------------------------+
1876 | Function Name     : _INT_ i_APCI1710_ReadChronoPortValue                   |
1877 |                               (unsigned char_   b_BoardHandle,                      |
1878 |                                unsigned char_   b_ModulNbr,                         |
1879 |                                unsigned char *_ pb_PortValue)                        |
1880 +----------------------------------------------------------------------------+
1881 | Task              : Return the status from digital inputs port from        |
1882 |                     selected  (b_ModulNbr) chronometer module.             |
1883 +----------------------------------------------------------------------------+
1884 | Input Parameters  : unsigned char_ b_BoardHandle   : Handle of board APCI-1710      |
1885 |                     unsigned char_ b_ModulNbr      : Selected module number (0 to 3)|
1886 +----------------------------------------------------------------------------+
1887 | Output Parameters : unsigned char *_ pb_PortValue   : Digital inputs port status.
1888 |                     data[0]
1889 +----------------------------------------------------------------------------+
1890 | Return Value      :  0: No error                                           |
1891 |                     -1: The handle parameter of the board is wrong         |
1892 |                     -2: Module selection wrong                             |
1893 |                     -3: The module is not a Chronometer module             |
1894 |                     -4: Chronometer not initialised see function           |
1895 |                         "i_APCI1710_InitChrono"                            |
1896 +----------------------------------------------------------------------------+
1897 */
1898 static int i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,
1899                                               struct comedi_subdevice *s,
1900                                               struct comedi_insn *insn,
1901                                               unsigned int *data)
1902 {
1903         struct addi_private *devpriv = dev->private;
1904         int i_ReturnValue = 0;
1905         unsigned char b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType;
1906         unsigned int dw_Status;
1907         unsigned char *pb_ChannelStatus;
1908         unsigned char *pb_PortValue;
1909
1910         b_ModulNbr = CR_AREF(insn->chanspec);
1911         i_ReturnValue = insn->n;
1912         b_IOType = (unsigned char) data[0];
1913
1914         /**************************/
1915         /* Test the module number */
1916         /**************************/
1917
1918         if (b_ModulNbr < 4) {
1919            /***********************/
1920                 /* Test if chronometer */
1921            /***********************/
1922
1923                 if ((devpriv->s_BoardInfos.
1924                                 dw_MolduleConfiguration[b_ModulNbr] &
1925                                 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
1926               /***********************************/
1927                         /* Test if chronometer initialised */
1928               /***********************************/
1929
1930                         if (devpriv->s_ModuleInfo[b_ModulNbr].
1931                                 s_ChronoModuleInfo.b_ChronoInit == 1) {
1932                  /***********************************/
1933                                 /* Test the digital output channel */
1934                  /***********************************/
1935                                 switch (b_IOType) {
1936
1937                                 case APCI1710_CHRONO_SET_CHANNELOFF:
1938
1939                                         b_OutputChannel =
1940                                                 (unsigned char) CR_CHAN(insn->chanspec);
1941                                         if (b_OutputChannel <= 2) {
1942
1943                                                 outl(0, devpriv->s_BoardInfos.
1944                                                         ui_Address + 20 +
1945                                                         (b_OutputChannel * 4) +
1946                                                         (64 * b_ModulNbr));
1947                                         }       /*  if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
1948                                         else {
1949                     /****************************************/
1950                                                 /* The selected digital output is wrong */
1951                     /****************************************/
1952
1953                                                 DPRINTK("The selected digital output is wrong\n");
1954                                                 i_ReturnValue = -4;
1955
1956                                         }       /*  if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
1957
1958                                         break;
1959
1960                                 case APCI1710_CHRONO_SET_CHANNELON:
1961
1962                                         b_OutputChannel =
1963                                                 (unsigned char) CR_CHAN(insn->chanspec);
1964                                         if (b_OutputChannel <= 2) {
1965
1966                                                 outl(1, devpriv->s_BoardInfos.
1967                                                         ui_Address + 20 +
1968                                                         (b_OutputChannel * 4) +
1969                                                         (64 * b_ModulNbr));
1970                                         }       /*  if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
1971                                         else {
1972                     /****************************************/
1973                                                 /* The selected digital output is wrong */
1974                     /****************************************/
1975
1976                                                 DPRINTK("The selected digital output is wrong\n");
1977                                                 i_ReturnValue = -4;
1978
1979                                         }       /*  if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2)) */
1980
1981                                         break;
1982
1983                                 case APCI1710_CHRONO_READ_CHANNEL:
1984                  /**********************************/
1985                                         /* Test the digital input channel */
1986                  /**********************************/
1987                                         pb_ChannelStatus = (unsigned char *) &data[0];
1988                                         b_InputChannel =
1989                                                 (unsigned char) CR_CHAN(insn->chanspec);
1990
1991                                         if (b_InputChannel <= 2) {
1992
1993                                                 dw_Status =
1994                                                         inl(devpriv->
1995                                                         s_BoardInfos.
1996                                                         ui_Address + 12 +
1997                                                         (64 * b_ModulNbr));
1998
1999                                                 *pb_ChannelStatus =
2000                                                         (unsigned char) (((dw_Status >>
2001                                                                         b_InputChannel)
2002                                                                 & 1) ^ 1);
2003                                         }       /*  if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) */
2004                                         else {
2005                     /***************************************/
2006                                                 /* The selected digital input is wrong */
2007                     /***************************************/
2008
2009                                                 DPRINTK("The selected digital input is wrong\n");
2010                                                 i_ReturnValue = -4;
2011                                         }       /*  if ((b_InputChannel >= 0) && (b_InputChannel <= 2)) */
2012
2013                                         break;
2014
2015                                 case APCI1710_CHRONO_READ_PORT:
2016
2017                                         pb_PortValue = (unsigned char *) &data[0];
2018
2019                                         dw_Status =
2020                                                 inl(devpriv->s_BoardInfos.
2021                                                 ui_Address + 12 +
2022                                                 (64 * b_ModulNbr));
2023
2024                                         *pb_PortValue =
2025                                                 (unsigned char) ((dw_Status & 0x7) ^ 7);
2026                                         break;
2027                                 }
2028                         } else {
2029                  /*******************************/
2030                                 /* Chronometer not initialised */
2031                  /*******************************/
2032
2033                                 DPRINTK("Chronometer not initialised\n");
2034                                 i_ReturnValue = -5;
2035                         }
2036                 } else {
2037               /******************************************/
2038                         /* The module is not a Chronometer module */
2039               /******************************************/
2040
2041                         DPRINTK("The module is not a Chronometer module\n");
2042                         i_ReturnValue = -3;
2043                 }
2044         } else {
2045            /***********************/
2046                 /* Module number error */
2047            /***********************/
2048
2049                 DPRINTK("Module number error\n");
2050                 i_ReturnValue = -2;
2051         }
2052
2053         return i_ReturnValue;
2054 }