Staging: comedi: add adl_pci9111 driver
[linux-2.6] / drivers / staging / comedi / drivers / addi-data / APCI1710_82x54.c
1 /**
2 @verbatim
3
4 Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
5
6         ADDI-DATA GmbH
7         Dieselstrasse 3
8         D-77833 Ottersweier
9         Tel: +19(0)7223/9493-0
10         Fax: +49(0)7223/9493-92
11         http://www.addi-data-com
12         info@addi-data.com
13
14 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 You shoud also find the complete GPL in the COPYING file accompanying this source code.
21
22 @endverbatim
23 */
24 /*
25
26   +-----------------------------------------------------------------------+
27   | (C) ADDI-DATA GmbH          Dieselstraße 3       D-77833 Ottersweier  |
28   +-----------------------------------------------------------------------+
29   | Tel : +49 (0) 7223/9493-0     | email    : info@addi-data.com         |
30   | Fax : +49 (0) 7223/9493-92    | Internet : http://www.addi-data.com   |
31   +-----------------------------------------------------------------------+
32   | Project     : API APCI1710    | Compiler : gcc                        |
33   | Module name : 82X54.C         | Version  : 2.96                       |
34   +-------------------------------+---------------------------------------+
35   | Project manager: Eric Stolz   | Date     :  02/12/2002                |
36   +-----------------------------------------------------------------------+
37   | Description :   APCI-1710 82X54 timer 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   | 27.10.03 | J. Krauth |  Add the possibility to use a 40 Mhz quartz    |
51   |          |           |                                                |
52   +-----------------------------------------------------------------------+
53 */
54
55 /*
56 +----------------------------------------------------------------------------+
57 |                               Included files                               |
58 +----------------------------------------------------------------------------+
59 */
60
61 #include "APCI1710_82x54.h"
62
63 /*
64 +----------------------------------------------------------------------------+
65 | Function Name     : _INT_     i_APCI1710_InitTimer                         |
66 |                               (BYTE_   b_BoardHandle,                      |
67 |                                BYTE_   b_ModulNbr,                         |
68 |                                BYTE_   b_TimerNbr,                         |
69 |                                BYTE_   b_TimerMode,                        |
70 |                                ULONG_ ul_ReloadValue,                      |
71 |                                BYTE_   b_InputClockSelection,              |
72 |                                BYTE_   b_InputClockLevel,                  |
73 |                                BYTE_   b_OutputLevel,                      |
74 |                                BYTE_   b_HardwareGateLevel)
75 INT i_InsnConfig_InitTimer(comedi_device *dev,comedi_subdevice *s,
76         comedi_insn *insn,lsampl_t *data)
77 |
78 +----------------------------------------------------------------------------+
79 | Task              : Configure the Timer (b_TimerNbr) operating mode        |
80 |                     (b_TimerMode) from selected module (b_ModulNbr).       |
81 |                     You must calling this function be for you call any     |
82 |                     other function witch access of the timer.              |
83 |                                                                            |
84 |                                                                            |
85 |                       Timer mode description table                         |
86 |                                                                            |
87 |+--------+-----------------------------+--------------+--------------------+|
88 ||Selected+      Mode description       +u_ReloadValue | Hardware gate input||
89 ||  mode  |                             |  description |      action        ||
90 |+--------+-----------------------------+--------------+--------------------+|
91 ||        |Mode 0 is typically used     |              |                    ||
92 ||        |for event counting. After    |              |                    ||
93 ||        |the initialisation, OUT      |              |                    ||
94 ||        |is initially low, and        |              |                    ||
95 ||   0    |will remain low until the    |Start counting|   Hardware gate    ||
96 ||        |counter reaches zero.        |   value      |                    ||
97 ||        |OUT then goes high and       |              |                    ||
98 ||        |remains high until a new     |              |                    ||
99 ||        |count is written. See        |              |                    ||
100 ||        |"i_APCI1710_WriteTimerValue" |              |                    ||
101 ||        |function.                    |              |                    ||
102 |+--------+-----------------------------+--------------+--------------------+|
103 ||        |Mode 1 is similar to mode 0  |              |                    ||
104 ||        |except for the gate input    |              |                    ||
105 ||   1    |action. The gate input is not|Start counting|  Hardware trigger  ||
106 ||        |used for enabled or disabled |   value      |                    ||
107 ||        |the timer.                   |              |                    ||
108 ||        |The gate input is used for   |              |                    ||
109 ||        |triggered the timer.         |              |                    ||
110 |+--------+-----------------------------+--------------+--------------------+|
111 ||        |This mode functions like a   |              |                    ||
112 ||        |divide-by-ul_ReloadValue     |              |                    ||
113 ||        |counter. It is typically used|              |                    ||
114 ||        |to generate a real time clock|              |                    ||
115 ||        |interrupt. OUT will initially|              |                    ||
116 ||   2    |be high after the            |   Division   |  Hardware gate     ||
117 ||        |initialisation. When the     |    factor    |                    ||
118 ||        |initial count has decremented|              |                    ||
119 ||        |to 1, OUT goes low for one   |              |                    ||
120 ||        |CLK pule. OUT then goes high |              |                    ||
121 ||        |again, the counter reloads   |              |                    ||
122 ||        |the initial count            |              |                    ||
123 ||        |(ul_ReloadValue) and the     |              |                    ||
124 ||        |process is repeated.         |              |                    ||
125 ||        |This action can generated a  |              |                    ||
126 ||        |interrupt. See function      |              |                    ||
127 ||        |"i_APCI1710_SetBoardInt-     |              |                    ||
128 ||        |RoutineX"                    |              |                    ||
129 ||        |and "i_APCI1710_EnableTimer" |              |                    ||
130 |+--------+-----------------------------+--------------+--------------------+|
131 ||        |Mode 3 is typically used for |              |                    ||
132 ||        |baud rate generation. This   |              |                    ||
133 ||        |mode is similar to mode 2    |              |                    ||
134 ||        |except for the duty cycle of |              |                    ||
135 ||   3    |OUT. OUT will initially be   |  Division    |   Hardware gate    ||
136 ||        |high after the initialisation|   factor     |                    ||
137 ||        |When half the initial count  |              |                    ||
138 ||        |(ul_ReloadValue) has expired,|              |                    ||
139 ||        |OUT goes low for the         |              |                    ||
140 ||        |remainder of the count. The  |              |                    ||
141 ||        |mode is periodic; the        |              |                    ||
142 ||        |sequence above is repeated   |              |                    ||
143 ||        |indefinitely.                |              |                    ||
144 |+--------+-----------------------------+--------------+--------------------+|
145 ||        |OUT will be initially high   |              |                    ||
146 ||        |after the initialisation.    |              |                    ||
147 ||        |When the initial count       |              |                    ||
148 ||   4    |expires OUT will go low for  |Start counting|  Hardware gate     ||
149 ||        |one CLK pulse and then go    |    value     |                    ||
150 ||        |high again.                  |              |                    ||
151 ||        |The counting sequences is    |              |                    ||
152 ||        |triggered by writing a new   |              |                    ||
153 ||        |value. See                   |              |                    ||
154 ||        |"i_APCI1710_WriteTimerValue" |              |                    ||
155 ||        |function. If a new count is  |              |                    ||
156 ||        |written during counting,     |              |                    ||
157 ||        |it will be loaded on the     |              |                    ||
158 ||        |next CLK pulse               |              |                    ||
159 |+--------+-----------------------------+--------------+--------------------+|
160 ||        |Mode 5 is similar to mode 4  |              |                    ||
161 ||        |except for the gate input    |              |                    ||
162 ||        |action. The gate input is not|              |                    ||
163 ||   5    |used for enabled or disabled |Start counting|  Hardware trigger  ||
164 ||        |the timer. The gate input is |    value     |                    ||
165 ||        |used for triggered the timer.|              |                    ||
166 |+--------+-----------------------------+--------------+--------------------+|
167 |                                                                            |
168 |                                                                            |
169 |                                                                            |
170 |                      Input clock selection table                           |
171 |                                                                            |
172 |  +--------------------------------+------------------------------------+   |
173 |  |       b_InputClockSelection    |           Description              |   |
174 |  |           parameter            |                                    |   |
175 |  +--------------------------------+------------------------------------+   |
176 |  |    APCI1710_PCI_BUS_CLOCK      | For the timer input clock, the PCI |   |
177 |  |                                | bus clock / 4 is used. This PCI bus|   |
178 |  |                                | clock can be 30MHz or 33MHz. For   |   |
179 |  |                                | Timer 0 only this selection are    |   |
180 |  |                                | available.                         |   |
181 |  +--------------------------------+------------------------------------+   |
182 |  | APCI1710_ FRONT_CONNECTOR_INPUT| Of the front connector you have the|   |
183 |  |                                | possibility to inject a input clock|   |
184 |  |                                | for Timer 1 or Timer 2. The source |   |
185 |  |                                | from this clock can eat the output |   |
186 |  |                                | clock from Timer 0 or any other    |   |
187 |  |                                | clock source.                      |   |
188 |  +--------------------------------+------------------------------------+   |
189 |                                                                            |
190 +----------------------------------------------------------------------------+
191 | Input Parameters  : BYTE_   b_BoardHandle        : Handle of board         |
192 |                                                    APCI-1710               |
193 |                     BYTE_   b_ModulNbr           : Module number to        |
194 |                                                    configure (0 to 3)      |
195 |                     BYTE_   b_TimerNbr           : Timer number to         |
196 |                                                    configure (0 to 2)      |
197 |                     BYTE_   b_TimerMode          : Timer mode selection    |
198 |                                                    (0 to 5)                |
199 |                                                    0: Interrupt on terminal|
200 |                                                       count                |
201 |                                                    1: Hardware             |
202 |                                                       retriggerable one-   |
203 |                                                       shot                 |
204 |                                                    2: Rate generator       |
205 |                                                    3: Square wave mode     |
206 |                                                    4: Software triggered   |
207 |                                                       strobe               |
208 |                                                    5: Hardware triggered   |
209 |                                                       strobe               |
210 |                                                       See timer mode       |
211 |                                                       description table.   |
212 |                     ULONG_ ul_ReloadValue         : Start counting value   |
213 |                                                     or division factor     |
214 |                                                     See timer mode         |
215 |                                                     description table.     |
216 |                     BYTE_   b_InputClockSelection : Selection from input   |
217 |                                                     timer clock.           |
218 |                                                     See input clock        |
219 |                                                     selection table.       |
220 |                     BYTE_   b_InputClockLevel     : Selection from input   |
221 |                                                     clock level.           |
222 |                                                     0 : Low active         |
223 |                                                         (Input inverted)   |
224 |                                                     1 : High active        |
225 |                     BYTE_   b_OutputLevel,        : Selection from output  |
226 |                                                     clock level.           |
227 |                                                     0 : Low active         |
228 |                                                     1 : High active        |
229 |                                                         (Output inverted)  |
230 |                     BYTE_   b_HardwareGateLevel   : Selection from         |
231 |                                                     hardware gate level.   |
232 |                                                     0 : Low active         |
233 |                                                         (Input inverted)   |
234 |                                                     1 : High active        |
235 |                                                     If you will not used   |
236 |                                                     the hardware gate set  |
237 |                                                     this value to 0.
238 |b_ModulNbr        = (BYTE) CR_AREF(insn->chanspec);
239         b_TimerNbr                = (BYTE) CR_CHAN(insn->chanspec);
240         b_TimerMode               = (BYTE) data[0];
241         ul_ReloadValue    = (ULONG) data[1];
242         b_InputClockSelection   =(BYTE) data[2];
243         b_InputClockLevel               =(BYTE) data[3];
244         b_OutputLevel                   =(BYTE) data[4];
245         b_HardwareGateLevel             =(BYTE) data[5];
246 +----------------------------------------------------------------------------+
247 | Output Parameters : -                                                      |
248 +----------------------------------------------------------------------------+
249 | Return Value      : 0: No error                                            |
250 |                    -1: The handle parameter of the board is wrong          |
251 |                    -2: Module selection wrong                              |
252 |                    -3: Timer selection wrong                               |
253 |                    -4: The module is not a TIMER module                    |
254 |                    -5: Timer mode selection is wrong                       |
255 |                    -6: Input timer clock selection is wrong                |
256 |                    -7: Selection from input clock level is wrong           |
257 |                    -8: Selection from output clock level is wrong          |
258 |                    -9: Selection from hardware gate level is wrong         |
259 +----------------------------------------------------------------------------+
260 */
261
262 INT i_APCI1710_InsnConfigInitTimer(comedi_device * dev, comedi_subdevice * s,
263         comedi_insn * insn, lsampl_t * data)
264 {
265
266         INT i_ReturnValue = 0;
267         BYTE b_ModulNbr;
268         BYTE b_TimerNbr;
269         BYTE b_TimerMode;
270         ULONG ul_ReloadValue;
271         BYTE b_InputClockSelection;
272         BYTE b_InputClockLevel;
273         BYTE b_OutputLevel;
274         BYTE b_HardwareGateLevel;
275
276         //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
277         DWORD dw_Test = 0;
278         //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
279
280         i_ReturnValue = insn->n;
281         b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
282         b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
283         b_TimerMode = (BYTE) data[0];
284         ul_ReloadValue = (ULONG) data[1];
285         b_InputClockSelection = (BYTE) data[2];
286         b_InputClockLevel = (BYTE) data[3];
287         b_OutputLevel = (BYTE) data[4];
288         b_HardwareGateLevel = (BYTE) data[5];
289
290         /**************************/
291         /* Test the module number */
292         /**************************/
293
294         if (b_ModulNbr < 4) {
295            /***********************/
296                 /* Test if 82X54 timer */
297            /***********************/
298
299                 if ((devpriv->s_BoardInfos.
300                                 dw_MolduleConfiguration[b_ModulNbr] &
301                                 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
302               /*************************/
303                         /* Test the timer number */
304               /*************************/
305
306                         if (b_TimerNbr <= 2) {
307                  /***********************/
308                                 /* Test the timer mode */
309                  /***********************/
310
311                                 if (b_TimerMode <= 5) {
312                                         //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
313                     /*********************************/
314                                         /* Test te imput clock selection */
315                     /*********************************/
316                                         /*
317                                            if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) ||
318                                            ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1))))
319                                          */
320
321                                         if (((b_TimerNbr == 0)
322                                                         &&
323                                                         (b_InputClockSelection
324                                                                 ==
325                                                                 APCI1710_PCI_BUS_CLOCK))
326                                                 || ((b_TimerNbr == 0)
327                                                         &&
328                                                         (b_InputClockSelection
329                                                                 ==
330                                                                 APCI1710_10MHZ))
331                                                 || ((b_TimerNbr != 0)
332                                                         &&
333                                                         ((b_InputClockSelection
334                                                                         ==
335                                                                         APCI1710_PCI_BUS_CLOCK)
336                                                                 ||
337                                                                 (b_InputClockSelection
338                                                                         ==
339                                                                         APCI1710_FRONT_CONNECTOR_INPUT)
340                                                                 ||
341                                                                 (b_InputClockSelection
342                                                                         ==
343                                                                         APCI1710_10MHZ))))
344                                                 //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
345                                         {
346                                                 //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
347                                                 if (((b_InputClockSelection ==
348                                                                         APCI1710_10MHZ)
349                                                                 && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) >= 0x3131)) || (b_InputClockSelection != APCI1710_10MHZ)) {
350                                                         //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
351                           /****************************************/
352                                                         /* Test the input clock level selection */
353                           /****************************************/
354
355                                                         if ((b_InputClockLevel
356                                                                         == 0)
357                                                                 ||
358                                                                 (b_InputClockLevel
359                                                                         == 1)) {
360                              /*****************************************/
361                                                                 /* Test the output clock level selection */
362                              /*****************************************/
363
364                                                                 if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) {
365                                 /******************************************/
366                                                                         /* Test the hardware gate level selection */
367                                 /******************************************/
368
369                                                                         if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) {
370                                                                                 //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
371                                    /*****************************************************/
372                                                                                 /* Test if version > 1.1 and clock selection = 10MHz */
373                                    /*****************************************************/
374
375                                                                                 if ((b_InputClockSelection == APCI1710_10MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) > 0x3131)) {
376                                       /*********************************/
377                                                                                         /* Test if 40MHz quartz on board */
378                                       /*********************************/
379
380                                                                                         dw_Test = inl(devpriv->s_BoardInfos.ui_Address + (16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)));
381
382                                                                                         dw_Test = (dw_Test >> 16) & 1;
383                                                                                 } else {
384                                                                                         dw_Test = 1;
385                                                                                 }
386
387                                    /************************/
388                                                                                 /* Test if detection OK */
389                                    /************************/
390
391                                                                                 if (dw_Test == 1) {
392                                                                                         //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
393                                       /*********************/
394                                                                                         /* Initialisation OK */
395                                       /*********************/
396
397                                                                                         devpriv->
398                                                                                                 s_ModuleInfo
399                                                                                                 [b_ModulNbr].
400                                                                                                 s_82X54ModuleInfo.
401                                                                                                 s_82X54TimerInfo
402                                                                                                 [b_TimerNbr].
403                                                                                                 b_82X54Init
404                                                                                                 =
405                                                                                                 1;
406
407                                       /**********************************/
408                                                                                         /* Save the input clock selection */
409                                       /**********************************/
410                                                                                         devpriv->
411                                                                                                 s_ModuleInfo
412                                                                                                 [b_ModulNbr].
413                                                                                                 s_82X54ModuleInfo.
414                                                                                                 s_82X54TimerInfo
415                                                                                                 [b_TimerNbr].
416                                                                                                 b_InputClockSelection
417                                                                                                 =
418                                                                                                 b_InputClockSelection;
419
420                                       /******************************/
421                                                                                         /* Save the input clock level */
422                                       /******************************/
423                                                                                         devpriv->
424                                                                                                 s_ModuleInfo
425                                                                                                 [b_ModulNbr].
426                                                                                                 s_82X54ModuleInfo.
427                                                                                                 s_82X54TimerInfo
428                                                                                                 [b_TimerNbr].
429                                                                                                 b_InputClockLevel
430                                                                                                 =
431                                                                                                 ~b_InputClockLevel
432                                                                                                 &
433                                                                                                 1;
434
435                                       /*************************/
436                                                                                         /* Save the output level */
437                                       /*************************/
438
439                                                                                         devpriv->
440                                                                                                 s_ModuleInfo
441                                                                                                 [b_ModulNbr].
442                                                                                                 s_82X54ModuleInfo.
443                                                                                                 s_82X54TimerInfo
444                                                                                                 [b_TimerNbr].
445                                                                                                 b_OutputLevel
446                                                                                                 =
447                                                                                                 ~b_OutputLevel
448                                                                                                 &
449                                                                                                 1;
450
451                                       /***********************/
452                                                                                         /* Save the gate level */
453                                       /***********************/
454
455                                                                                         devpriv->
456                                                                                                 s_ModuleInfo
457                                                                                                 [b_ModulNbr].
458                                                                                                 s_82X54ModuleInfo.
459                                                                                                 s_82X54TimerInfo
460                                                                                                 [b_TimerNbr].
461                                                                                                 b_HardwareGateLevel
462                                                                                                 =
463                                                                                                 b_HardwareGateLevel;
464
465                                       /****************************************************/
466                                                                                         /* Set the configuration word and disable the timer */
467                                       /****************************************************/
468                                                                                         //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
469                                                                                         /*
470                                                                                            devpriv->s_ModuleInfo [b_ModulNbr].
471                                                                                            s_82X54ModuleInfo.
472                                                                                            s_82X54TimerInfo  [b_TimerNbr].
473                                                                                            dw_ConfigurationWord = (DWORD) (((b_HardwareGateLevel         << 0) & 0x1) |
474                                                                                            ((b_InputClockLevel           << 1) & 0x2) |
475                                                                                            (((~b_OutputLevel       & 1)  << 2) & 0x4) |
476                                                                                            ((b_InputClockSelection       << 4) & 0x10));
477                                                                                          */
478                                       /**************************/
479                                                                                         /* Test if 10MHz selected */
480                                       /**************************/
481
482                                                                                         if (b_InputClockSelection == APCI1710_10MHZ) {
483                                                                                                 b_InputClockSelection
484                                                                                                         =
485                                                                                                         2;
486                                                                                         }
487
488                                                                                         devpriv->
489                                                                                                 s_ModuleInfo
490                                                                                                 [b_ModulNbr].
491                                                                                                 s_82X54ModuleInfo.
492                                                                                                 s_82X54TimerInfo
493                                                                                                 [b_TimerNbr].
494                                                                                                 dw_ConfigurationWord
495                                                                                                 =
496                                                                                                 (DWORD)
497                                                                                                 (
498                                                                                                 ((b_HardwareGateLevel << 0) & 0x1) | ((b_InputClockLevel << 1) & 0x2) | (((~b_OutputLevel & 1) << 2) & 0x4) | ((b_InputClockSelection << 4) & 0x30));
499                                                                                         //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
500                                                                                         outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
501
502                                       /******************************/
503                                                                                         /* Initialise the 82X54 Timer */
504                                       /******************************/
505
506                                                                                         outl((DWORD) b_TimerMode, devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
507
508                                       /**************************/
509                                                                                         /* Write the reload value */
510                                       /**************************/
511
512                                                                                         outl(ul_ReloadValue, devpriv->s_BoardInfos.ui_Address + 0 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
513                                                                                         //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
514                                                                                 }       // if (dw_Test == 1)
515                                                                                 else {
516                                       /****************************************/
517                                                                                         /* Input timer clock selection is wrong */
518                                       /****************************************/
519
520                                                                                         i_ReturnValue
521                                                                                                 =
522                                                                                                 -6;
523                                                                                 }       // if (dw_Test == 1)
524                                                                                 //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
525                                                                         }       // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
526                                                                         else {
527                                 /***********************************************/
528                                                                                 /* Selection from hardware gate level is wrong */
529                                 /***********************************************/
530
531                                                                                 DPRINTK("Selection from hardware gate level is wrong\n");
532                                                                                 i_ReturnValue
533                                                                                         =
534                                                                                         -9;
535                                                                         }       // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
536                                                                 }       // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
537                                                                 else {
538                              /**********************************************/
539                                                                         /* Selection from output clock level is wrong */
540                              /**********************************************/
541
542                                                                         DPRINTK("Selection from output clock level is wrong\n");
543                                                                         i_ReturnValue
544                                                                                 =
545                                                                                 -8;
546                                                                 }       // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
547                                                         }       // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
548                                                         else {
549                           /*********************************************/
550                                                                 /* Selection from input clock level is wrong */
551                           /*********************************************/
552
553                                                                 DPRINTK("Selection from input clock level is wrong\n");
554                                                                 i_ReturnValue =
555                                                                         -7;
556                                                         }       // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
557                                                 } else {
558                        /****************************************/
559                                                         /* Input timer clock selection is wrong */
560                        /****************************************/
561
562                                                         DPRINTK("Input timer clock selection is wrong\n");
563                                                         i_ReturnValue = -6;
564                                                 }
565                                         } else {
566                     /****************************************/
567                                                 /* Input timer clock selection is wrong */
568                     /****************************************/
569
570                                                 DPRINTK("Input timer clock selection is wrong\n");
571                                                 i_ReturnValue = -6;
572                                         }
573                                 }       // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
574                                 else {
575                  /*********************************/
576                                         /* Timer mode selection is wrong */
577                  /*********************************/
578
579                                         DPRINTK("Timer mode selection is wrong\n");
580                                         i_ReturnValue = -5;
581                                 }       // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
582                         }       // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
583                         else {
584               /*************************/
585                                 /* Timer selection wrong */
586               /*************************/
587
588                                 DPRINTK("Timer selection wrong\n");
589                                 i_ReturnValue = -3;
590                         }       // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
591                 } else {
592            /************************************/
593                         /* The module is not a TIMER module */
594            /************************************/
595
596                         DPRINTK("The module is not a TIMER module\n");
597                         i_ReturnValue = -4;
598                 }
599         } else {
600            /***********************/
601                 /* Module number error */
602            /***********************/
603
604                 DPRINTK("Module number error\n");
605                 i_ReturnValue = -2;
606         }
607
608         return (i_ReturnValue);
609 }
610
611 /*
612 +----------------------------------------------------------------------------+
613 | Function Name     : _INT_     i_APCI1710_EnableTimer                       |
614 |                               (BYTE_ b_BoardHandle,                        |
615 |                                BYTE_ b_ModulNbr,                           |
616 |                                BYTE_ b_TimerNbr,                           |
617 |                                BYTE_ b_InterruptEnable)
618 INT i_APCI1710_InsnWriteEnableDisableTimer(comedi_device *dev,comedi_subdevice *s,
619         comedi_insn *insn,lsampl_t *data)                |
620 +----------------------------------------------------------------------------+
621 | Task              : Enable OR Disable the Timer (b_TimerNbr) from selected module     |
622 |                     (b_ModulNbr). You must calling the                     |
623 |                     "i_APCI1710_InitTimer" function be for you call this   |
624 |                     function. If you enable the timer interrupt, the timer |
625 |                     generate a interrupt after the timer value reach       |
626 |                     the zero. See function "i_APCI1710_SetBoardIntRoutineX"|
627 +----------------------------------------------------------------------------+
628 | Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
629 |                                                 APCI-1710                  |
630 |                     BYTE_   b_ModulNbr        : Selected module number     |
631 |                                                 (0 to 3)                   |
632 |                     BYTE_   b_TimerNbr        : Timer number to enable     |
633 |                                                 (0 to 2)                   |
634 |                     BYTE_   b_InterruptEnable : Enable or disable the      |
635 |                                                 timer interrupt.           |
636 |                                                 APCI1710_ENABLE :          |
637 |                                                 Enable the timer interrupt |
638 |                                                 APCI1710_DISABLE :         |
639 |                                                 Disable the timer interrupt|
640 i_ReturnValue=insn->n;
641         b_ModulNbr        = (BYTE) CR_AREF(insn->chanspec);
642         b_TimerNbr                = (BYTE) CR_CHAN(insn->chanspec);
643         b_ActionType      = (BYTE) data[0]; // enable disable
644 +----------------------------------------------------------------------------+
645 | Output Parameters : -                                                      |
646 +----------------------------------------------------------------------------+
647 | Return Value      : 0: No error                                            |
648 |                    -1: The handle parameter of the board is wrong          |
649 |                    -2: Module selection wrong                              |
650 |                    -3: Timer selection wrong                               |
651 |                    -4: The module is not a TIMER module                    |
652 |                    -5: Timer not initialised see function                  |
653 |                        "i_APCI1710_InitTimer"                              |
654 |                    -6: Interrupt parameter is wrong                        |
655 |                    -7: Interrupt function not initialised.                 |
656 |                        See function "i_APCI1710_SetBoardIntRoutineX"       |
657 +----------------------------------------------------------------------------+
658 */
659
660 INT i_APCI1710_InsnWriteEnableDisableTimer(comedi_device * dev,
661         comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
662 {
663         INT i_ReturnValue = 0;
664         DWORD dw_DummyRead;
665         BYTE b_ModulNbr;
666         BYTE b_TimerNbr;
667         BYTE b_ActionType;
668         BYTE b_InterruptEnable;
669
670         i_ReturnValue = insn->n;
671         b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
672         b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
673         b_ActionType = (BYTE) data[0];  // enable disable
674         /**************************/
675         /* Test the module number */
676         /**************************/
677
678         if (b_ModulNbr < 4) {
679            /***********************/
680                 /* Test if 82X54 timer */
681            /***********************/
682
683                 if ((devpriv->s_BoardInfos.
684                                 dw_MolduleConfiguration[b_ModulNbr] &
685                                 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
686               /*************************/
687                         /* Test the timer number */
688               /*************************/
689
690                         if (b_TimerNbr <= 2) {
691                  /*****************************/
692                                 /* Test if timer initialised */
693                  /*****************************/
694
695                                 if (devpriv->s_ModuleInfo[b_ModulNbr].
696                                         s_82X54ModuleInfo.
697                                         s_82X54TimerInfo[b_TimerNbr].
698                                         b_82X54Init == 1) {
699
700                                         switch (b_ActionType) {
701                                         case APCI1710_ENABLE:
702
703                                                 b_InterruptEnable =
704                                                         (BYTE) data[1];
705                     /********************************/
706                                                 /* Test the interrupt selection */
707                     /********************************/
708
709                                                 if ((b_InterruptEnable ==
710                                                                 APCI1710_ENABLE)
711                                                         || (b_InterruptEnable ==
712                                                                 APCI1710_DISABLE))
713                                                 {
714                                                         if (b_InterruptEnable ==
715                                                                 APCI1710_ENABLE)
716                                                         {
717
718                                                                 dw_DummyRead =
719                                                                         inl
720                                                                         (devpriv->
721                                                                         s_BoardInfos.
722                                                                         ui_Address
723                                                                         + 12 +
724                                                                         (b_TimerNbr
725                                                                                 *
726                                                                                 4)
727                                                                         +
728                                                                         (64 * b_ModulNbr));
729
730                              /************************/
731                                                                 /* Enable the interrupt */
732                              /************************/
733
734                                                                 devpriv->
735                                                                         s_ModuleInfo
736                                                                         [b_ModulNbr].
737                                                                         s_82X54ModuleInfo.
738                                                                         s_82X54TimerInfo
739                                                                         [b_TimerNbr].
740                                                                         dw_ConfigurationWord
741                                                                         =
742                                                                         devpriv->
743                                                                         s_ModuleInfo
744                                                                         [b_ModulNbr].
745                                                                         s_82X54ModuleInfo.
746                                                                         s_82X54TimerInfo
747                                                                         [b_TimerNbr].
748                                                                         dw_ConfigurationWord
749                                                                         | 0x8;
750
751                                                                 outl(devpriv->
752                                                                         s_ModuleInfo
753                                                                         [b_ModulNbr].
754                                                                         s_82X54ModuleInfo.
755                                                                         s_82X54TimerInfo
756                                                                         [b_TimerNbr].
757                                                                         dw_ConfigurationWord,
758                                                                         devpriv->
759                                                                         s_BoardInfos.
760                                                                         ui_Address
761                                                                         + 32 +
762                                                                         (b_TimerNbr
763                                                                                 *
764                                                                                 4)
765                                                                         +
766                                                                         (64 * b_ModulNbr));
767                                                                 devpriv->tsk_Current = current; // Save the current process task structure
768
769                                                         }       // if (b_InterruptEnable == APCI1710_ENABLE)
770                                                         else {
771                           /*************************/
772                                                                 /* Disable the interrupt */
773                           /*************************/
774
775                                                                 devpriv->
776                                                                         s_ModuleInfo
777                                                                         [b_ModulNbr].
778                                                                         s_82X54ModuleInfo.
779                                                                         s_82X54TimerInfo
780                                                                         [b_TimerNbr].
781                                                                         dw_ConfigurationWord
782                                                                         =
783                                                                         devpriv->
784                                                                         s_ModuleInfo
785                                                                         [b_ModulNbr].
786                                                                         s_82X54ModuleInfo.
787                                                                         s_82X54TimerInfo
788                                                                         [b_TimerNbr].
789                                                                         dw_ConfigurationWord
790                                                                         & 0xF7;
791
792                                                                 outl(devpriv->
793                                                                         s_ModuleInfo
794                                                                         [b_ModulNbr].
795                                                                         s_82X54ModuleInfo.
796                                                                         s_82X54TimerInfo
797                                                                         [b_TimerNbr].
798                                                                         dw_ConfigurationWord,
799                                                                         devpriv->
800                                                                         s_BoardInfos.
801                                                                         ui_Address
802                                                                         + 32 +
803                                                                         (b_TimerNbr
804                                                                                 *
805                                                                                 4)
806                                                                         +
807                                                                         (64 * b_ModulNbr));
808
809                           /***************************/
810                                                                 /* Save the interrupt flag */
811                           /***************************/
812
813                                                                 devpriv->
814                                                                         s_ModuleInfo
815                                                                         [b_ModulNbr].
816                                                                         s_82X54ModuleInfo.
817                                                                         b_InterruptMask
818                                                                         =
819                                                                         devpriv->
820                                                                         s_ModuleInfo
821                                                                         [b_ModulNbr].
822                                                                         s_82X54ModuleInfo.
823                                                                         b_InterruptMask
824                                                                         & (0xFF
825                                                                         -
826                                                                         (1 << b_TimerNbr));
827                                                         }       // if (b_InterruptEnable == APCI1710_ENABLE)
828
829                        /***********************/
830                                                         /* Test if error occur */
831                        /***********************/
832
833                                                         if (i_ReturnValue >= 0) {
834                           /***************************/
835                                                                 /* Save the interrupt flag */
836                           /***************************/
837
838                                                                 devpriv->
839                                                                         s_ModuleInfo
840                                                                         [b_ModulNbr].
841                                                                         s_82X54ModuleInfo.
842                                                                         b_InterruptMask
843                                                                         =
844                                                                         devpriv->
845                                                                         s_ModuleInfo
846                                                                         [b_ModulNbr].
847                                                                         s_82X54ModuleInfo.
848                                                                         b_InterruptMask
849                                                                         | ((1 & b_InterruptEnable) << b_TimerNbr);
850
851                           /********************/
852                                                                 /* Enable the timer */
853                           /********************/
854
855                                                                 outl(1, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
856                                                         }
857                                                 } else {
858                        /********************************/
859                                                         /* Interrupt parameter is wrong */
860                        /********************************/
861
862                                                         DPRINTK("\n");
863                                                         i_ReturnValue = -6;
864                                                 }
865                                                 break;
866                                         case APCI1710_DISABLE:
867                         /***************************/
868                                                 /* Test the interrupt flag */
869                     /***************************/
870
871                                                 if (((devpriv->s_ModuleInfo
872                                                                         [b_ModulNbr].
873                                                                         s_82X54ModuleInfo.
874                                                                         b_InterruptMask
875                                                                         >>
876                                                                         b_TimerNbr)
877                                                                 & 1) == 1) {
878                        /*************************/
879                                                         /* Disable the interrupt */
880                        /*************************/
881
882                                                         devpriv->
883                                                                 s_ModuleInfo
884                                                                 [b_ModulNbr].
885                                                                 s_82X54ModuleInfo.
886                                                                 s_82X54TimerInfo
887                                                                 [b_TimerNbr].
888                                                                 dw_ConfigurationWord
889                                                                 =
890                                                                 devpriv->
891                                                                 s_ModuleInfo
892                                                                 [b_ModulNbr].
893                                                                 s_82X54ModuleInfo.
894                                                                 s_82X54TimerInfo
895                                                                 [b_TimerNbr].
896                                                                 dw_ConfigurationWord
897                                                                 & 0xF7;
898
899                                                         outl(devpriv->
900                                                                 s_ModuleInfo
901                                                                 [b_ModulNbr].
902                                                                 s_82X54ModuleInfo.
903                                                                 s_82X54TimerInfo
904                                                                 [b_TimerNbr].
905                                                                 dw_ConfigurationWord,
906                                                                 devpriv->
907                                                                 s_BoardInfos.
908                                                                 ui_Address +
909                                                                 32 +
910                                                                 (b_TimerNbr *
911                                                                         4) +
912                                                                 (64 * b_ModulNbr));
913
914                        /***************************/
915                                                         /* Save the interrupt flag */
916                        /***************************/
917
918                                                         devpriv->
919                                                                 s_ModuleInfo
920                                                                 [b_ModulNbr].
921                                                                 s_82X54ModuleInfo.
922                                                                 b_InterruptMask
923                                                                 =
924                                                                 devpriv->
925                                                                 s_ModuleInfo
926                                                                 [b_ModulNbr].
927                                                                 s_82X54ModuleInfo.
928                                                                 b_InterruptMask
929                                                                 & (0xFF -
930                                                                 (1 << b_TimerNbr));
931                                                 }
932
933                     /*********************/
934                                                 /* Disable the timer */
935                     /*********************/
936
937                                                 outl(0, devpriv->s_BoardInfos.
938                                                         ui_Address + 44 +
939                                                         (b_TimerNbr * 4) +
940                                                         (64 * b_ModulNbr));
941                                                 break;
942                                         }       // Switch end
943                                 } else {
944                     /**************************************/
945                                         /* Timer not initialised see function */
946                     /**************************************/
947
948                                         DPRINTK("Timer not initialised see function\n");
949                                         i_ReturnValue = -5;
950                                 }
951                         } else {
952                  /*************************/
953                                 /* Timer selection wrong */
954                  /*************************/
955
956                                 DPRINTK("Timer selection wrong\n");
957                                 i_ReturnValue = -3;
958                         }       // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
959                 } else {
960               /************************************/
961                         /* The module is not a TIMER module */
962               /************************************/
963
964                         DPRINTK("The module is not a TIMER module\n");
965                         i_ReturnValue = -4;
966                 }
967         } else {
968            /***********************/
969                 /* Module number error */
970            /***********************/
971
972                 DPRINTK("Module number error\n");
973                 i_ReturnValue = -2;
974         }
975
976         return (i_ReturnValue);
977 }
978
979 /*
980 +----------------------------------------------------------------------------+
981 | Function Name     : _INT_     i_APCI1710_ReadAllTimerValue                 |
982 |                                       (BYTE_     b_BoardHandle,            |
983 |                                        BYTE_     b_ModulNbr,               |
984 |                                        PULONG_ pul_TimerValueArray)
985 INT i_APCI1710_InsnReadAllTimerValue(comedi_device *dev,comedi_subdevice *s,
986         comedi_insn *insn,lsampl_t *data)        |
987 +----------------------------------------------------------------------------+
988 | Task              : Return the all timer values from selected timer        |
989 |                     module (b_ModulNbr).                                   |
990 +----------------------------------------------------------------------------+
991 | Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
992 |                                                 APCI-1710                  |
993 |                     BYTE_   b_ModulNbr        : Selected module number     |
994 |                                                 (0 to 3)                   |
995 +----------------------------------------------------------------------------+
996 | Output Parameters : PULONG_ pul_TimerValueArray : Timer value array.       |
997 |                           Element 0 contain the timer 0 value.             |
998 |                           Element 1 contain the timer 1 value.             |
999 |                           Element 2 contain the timer 2 value.             |
1000 +----------------------------------------------------------------------------+
1001 | Return Value      : 0: No error                                            |
1002 |                    -1: The handle parameter of the board is wrong          |
1003 |                    -2: Module selection wrong                              |
1004 |                    -3: The module is not a TIMER module                    |
1005 |                    -4: Timer 0 not initialised see function                |
1006 |                        "i_APCI1710_InitTimer"                              |
1007 |                    -5: Timer 1 not initialised see function                |
1008 |                        "i_APCI1710_InitTimer"                              |
1009 |                    -6: Timer 2 not initialised see function                |
1010 |                        "i_APCI1710_InitTimer"                              |
1011 +----------------------------------------------------------------------------+
1012 */
1013
1014 INT i_APCI1710_InsnReadAllTimerValue(comedi_device * dev, comedi_subdevice * s,
1015         comedi_insn * insn, lsampl_t * data)
1016 {
1017         INT i_ReturnValue = 0;
1018         BYTE b_ModulNbr, b_ReadType;
1019         PULONG pul_TimerValueArray;
1020
1021         b_ModulNbr = CR_AREF(insn->chanspec);
1022         b_ReadType = CR_CHAN(insn->chanspec);
1023         pul_TimerValueArray = (PULONG) data;
1024         i_ReturnValue = insn->n;
1025
1026         switch (b_ReadType) {
1027         case APCI1710_TIMER_READINTERRUPT:
1028
1029                 data[0] = devpriv->s_InterruptParameters.
1030                         s_FIFOInterruptParameters[devpriv->
1031                         s_InterruptParameters.ui_Read].b_OldModuleMask;
1032                 data[1] = devpriv->s_InterruptParameters.
1033                         s_FIFOInterruptParameters[devpriv->
1034                         s_InterruptParameters.ui_Read].ul_OldInterruptMask;
1035                 data[2] = devpriv->s_InterruptParameters.
1036                         s_FIFOInterruptParameters[devpriv->
1037                         s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
1038
1039                              /**************************/
1040                 /* Increment the read FIFO */
1041                              /***************************/
1042
1043                 devpriv->
1044                         s_InterruptParameters.
1045                         ui_Read = (devpriv->
1046                         s_InterruptParameters.
1047                         ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
1048
1049                 break;
1050
1051         case APCI1710_TIMER_READALLTIMER:
1052         /**************************/
1053                 /* Test the module number */
1054         /**************************/
1055
1056                 if (b_ModulNbr < 4) {
1057            /***********************/
1058                         /* Test if 82X54 timer */
1059            /***********************/
1060
1061                         if ((devpriv->s_BoardInfos.
1062                                         dw_MolduleConfiguration[b_ModulNbr] &
1063                                         0xFFFF0000UL) == APCI1710_82X54_TIMER) {
1064               /********************************/
1065                                 /* Test if timer 0 iniutialised */
1066               /********************************/
1067
1068                                 if (devpriv->s_ModuleInfo[b_ModulNbr].
1069                                         s_82X54ModuleInfo.
1070                                         s_82X54TimerInfo[0].b_82X54Init == 1) {
1071                  /********************************/
1072                                         /* Test if timer 1 iniutialised */
1073                  /********************************/
1074
1075                                         if (devpriv->s_ModuleInfo[b_ModulNbr].
1076                                                 s_82X54ModuleInfo.
1077                                                 s_82X54TimerInfo[1].
1078                                                 b_82X54Init == 1) {
1079                     /********************************/
1080                                                 /* Test if timer 2 iniutialised */
1081                     /********************************/
1082
1083                                                 if (devpriv->
1084                                                         s_ModuleInfo
1085                                                         [b_ModulNbr].
1086                                                         s_82X54ModuleInfo.
1087                                                         s_82X54TimerInfo[2].
1088                                                         b_82X54Init == 1) {
1089                        /*********************/
1090                                                         /* Latch all counter */
1091                        /*********************/
1092
1093                                                         outl(0x17,
1094                                                                 devpriv->
1095                                                                 s_BoardInfos.
1096                                                                 ui_Address +
1097                                                                 12 +
1098                                                                 (64 * b_ModulNbr));
1099
1100                        /**************************/
1101                                                         /* Read the timer 0 value */
1102                        /**************************/
1103
1104                                                         pul_TimerValueArray[0] =
1105                                                                 inl(devpriv->
1106                                                                 s_BoardInfos.
1107                                                                 ui_Address + 0 +
1108                                                                 (64 * b_ModulNbr));
1109
1110                        /**************************/
1111                                                         /* Read the timer 1 value */
1112                        /**************************/
1113
1114                                                         pul_TimerValueArray[1] =
1115                                                                 inl(devpriv->
1116                                                                 s_BoardInfos.
1117                                                                 ui_Address + 4 +
1118                                                                 (64 * b_ModulNbr));
1119
1120                        /**************************/
1121                                                         /* Read the timer 2 value */
1122                        /**************************/
1123
1124                                                         pul_TimerValueArray[2] =
1125                                                                 inl(devpriv->
1126                                                                 s_BoardInfos.
1127                                                                 ui_Address + 8 +
1128                                                                 (64 * b_ModulNbr));
1129                                                 } else {
1130                        /****************************************/
1131                                                         /* Timer 2 not initialised see function */
1132                        /****************************************/
1133
1134                                                         DPRINTK("Timer 2 not initialised see function\n");
1135                                                         i_ReturnValue = -6;
1136                                                 }
1137                                         } else {
1138                     /****************************************/
1139                                                 /* Timer 1 not initialised see function */
1140                     /****************************************/
1141
1142                                                 DPRINTK("Timer 1 not initialised see function\n");
1143                                                 i_ReturnValue = -5;
1144                                         }
1145                                 } else {
1146                  /****************************************/
1147                                         /* Timer 0 not initialised see function */
1148                  /****************************************/
1149
1150                                         DPRINTK("Timer 0 not initialised see function\n");
1151                                         i_ReturnValue = -4;
1152                                 }
1153                         } else {
1154               /************************************/
1155                                 /* The module is not a TIMER module */
1156               /************************************/
1157
1158                                 DPRINTK("The module is not a TIMER module\n");
1159                                 i_ReturnValue = -3;
1160                         }
1161                 } else {
1162            /***********************/
1163                         /* Module number error */
1164            /***********************/
1165
1166                         DPRINTK("Module number error\n");
1167                         i_ReturnValue = -2;
1168                 }
1169
1170         }                       // End of Switch
1171         return (i_ReturnValue);
1172 }
1173
1174 /*
1175 +----------------------------------------------------------------------------+
1176 | Function Name     :INT i_APCI1710_InsnBitsTimer(comedi_device *dev,
1177 comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)                   |
1178 +----------------------------------------------------------------------------+
1179 | Task              : Read write functions for Timer                                          |
1180 +----------------------------------------------------------------------------+
1181 | Input Parameters  :
1182 +----------------------------------------------------------------------------+
1183 | Output Parameters : -                                                      |
1184 +----------------------------------------------------------------------------+
1185 | Return Value      :
1186 +----------------------------------------------------------------------------+
1187 */
1188
1189 INT i_APCI1710_InsnBitsTimer(comedi_device * dev, comedi_subdevice * s,
1190         comedi_insn * insn, lsampl_t * data)
1191 {
1192         BYTE b_BitsType;
1193         INT i_ReturnValue = 0;
1194         b_BitsType = data[0];
1195
1196         printk("\n82X54");
1197
1198         switch (b_BitsType) {
1199         case APCI1710_TIMER_READVALUE:
1200                 i_ReturnValue = i_APCI1710_ReadTimerValue(dev,
1201                         (BYTE) CR_AREF(insn->chanspec),
1202                         (BYTE) CR_CHAN(insn->chanspec), (PULONG) & data[0]);
1203                 break;
1204
1205         case APCI1710_TIMER_GETOUTPUTLEVEL:
1206                 i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev,
1207                         (BYTE) CR_AREF(insn->chanspec),
1208                         (BYTE) CR_CHAN(insn->chanspec), (PBYTE) & data[0]);
1209                 break;
1210
1211         case APCI1710_TIMER_GETPROGRESSSTATUS:
1212                 i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev,
1213                         (BYTE) CR_AREF(insn->chanspec),
1214                         (BYTE) CR_CHAN(insn->chanspec), (PBYTE) & data[0]);
1215                 break;
1216
1217         case APCI1710_TIMER_WRITEVALUE:
1218                 i_ReturnValue = i_APCI1710_WriteTimerValue(dev,
1219                         (BYTE) CR_AREF(insn->chanspec),
1220                         (BYTE) CR_CHAN(insn->chanspec), (ULONG) data[1]);
1221
1222                 break;
1223
1224         default:
1225                 printk("Bits Config Parameter Wrong\n");
1226                 i_ReturnValue = -1;
1227         }
1228
1229         if (i_ReturnValue >= 0)
1230                 i_ReturnValue = insn->n;
1231         return (i_ReturnValue);
1232 }
1233
1234 /*
1235 +----------------------------------------------------------------------------+
1236 | Function Name     : _INT_     i_APCI1710_ReadTimerValue                    |
1237 |                                       (BYTE_     b_BoardHandle,            |
1238 |                                        BYTE_     b_ModulNbr,               |
1239 |                                        BYTE_     b_TimerNbr,               |
1240 |                                        PULONG_ pul_TimerValue)             |
1241 +----------------------------------------------------------------------------+
1242 | Task              : Return the timer value from selected digital timer     |
1243 |                     (b_TimerNbr) from selected timer  module (b_ModulNbr). |
1244 +----------------------------------------------------------------------------+
1245 | Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
1246 |                                                 APCI-1710                  |
1247 |                     BYTE_   b_ModulNbr        : Selected module number     |
1248 |                                                 (0 to 3)                   |
1249 |                     BYTE_   b_TimerNbr        : Timer number to read       |
1250 |                                                 (0 to 2)                   |
1251 +----------------------------------------------------------------------------+
1252 | Output Parameters : PULONG_ pul_TimerValue    : Timer value                |
1253 +----------------------------------------------------------------------------+
1254 | Return Value      : 0: No error                                            |
1255 |                    -1: The handle parameter of the board is wrong          |
1256 |                    -2: Module selection wrong                              |
1257 |                    -3: Timer selection wrong                               |
1258 |                    -4: The module is not a TIMER module                    |
1259 |                    -5: Timer not initialised see function                  |
1260 |                        "i_APCI1710_InitTimer"                              |
1261 +----------------------------------------------------------------------------+
1262 */
1263
1264 INT i_APCI1710_ReadTimerValue(comedi_device * dev,
1265         BYTE b_ModulNbr, BYTE b_TimerNbr, PULONG pul_TimerValue)
1266 {
1267         INT i_ReturnValue = 0;
1268
1269         /**************************/
1270         /* Test the module number */
1271         /**************************/
1272
1273         if (b_ModulNbr < 4) {
1274            /***********************/
1275                 /* Test if 82X54 timer */
1276            /***********************/
1277
1278                 if ((devpriv->s_BoardInfos.
1279                                 dw_MolduleConfiguration[b_ModulNbr] &
1280                                 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
1281               /*************************/
1282                         /* Test the timer number */
1283               /*************************/
1284
1285                         if (b_TimerNbr <= 2) {
1286                  /*****************************/
1287                                 /* Test if timer initialised */
1288                  /*****************************/
1289
1290                                 if (devpriv->
1291                                         s_ModuleInfo[b_ModulNbr].
1292                                         s_82X54ModuleInfo.
1293                                         s_82X54TimerInfo[b_TimerNbr].
1294                                         b_82X54Init == 1) {
1295                     /*************************/
1296                                         /* Latch the timer value */
1297                     /*************************/
1298
1299                                         outl((2 << b_TimerNbr) | 0xD0,
1300                                                 devpriv->s_BoardInfos.
1301                                                 ui_Address + 12 +
1302                                                 (64 * b_ModulNbr));
1303
1304                     /**************************/
1305                                         /* Read the counter value */
1306                     /**************************/
1307
1308                                         *pul_TimerValue =
1309                                                 inl(devpriv->s_BoardInfos.
1310                                                 ui_Address + (b_TimerNbr * 4) +
1311                                                 (64 * b_ModulNbr));
1312                                 } else {
1313                     /**************************************/
1314                                         /* Timer not initialised see function */
1315                     /**************************************/
1316                                         DPRINTK("Timer not initialised see function\n");
1317                                         i_ReturnValue = -5;
1318                                 }
1319                         } else {
1320                  /*************************/
1321                                 /* Timer selection wrong */
1322                  /*************************/
1323                                 DPRINTK("Timer selection wrong\n");
1324                                 i_ReturnValue = -3;
1325                         }       // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
1326                 } else {
1327               /************************************/
1328                         /* The module is not a TIMER module */
1329               /************************************/
1330                         DPRINTK("The module is not a TIMER module\n");
1331                         i_ReturnValue = -4;
1332                 }
1333         } else {
1334            /***********************/
1335                 /* Module number error */
1336            /***********************/
1337                 DPRINTK("Module number error\n");
1338                 i_ReturnValue = -2;
1339         }
1340
1341         return (i_ReturnValue);
1342 }
1343
1344         /*
1345            +----------------------------------------------------------------------------+
1346            | Function Name     : _INT_     i_APCI1710_GetTimerOutputLevel               |
1347            |                                       (BYTE_     b_BoardHandle,            |
1348            |                                        BYTE_     b_ModulNbr,               |
1349            |                                        BYTE_     b_TimerNbr,               |
1350            |                                        PBYTE_   pb_OutputLevel)            |
1351            +----------------------------------------------------------------------------+
1352            | Task              : Return the output signal level (pb_OutputLevel) from   |
1353            |                     selected digital timer (b_TimerNbr) from selected timer|
1354            |                     module (b_ModulNbr).                                   |
1355            +----------------------------------------------------------------------------+
1356            | Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
1357            |                                                 APCI-1710                  |
1358            |                     BYTE_   b_ModulNbr        : Selected module number     |
1359            |                                                 (0 to 3)                   |
1360            |                     BYTE_   b_TimerNbr        : Timer number to test       |
1361            |                                                 (0 to 2)                   |
1362            +----------------------------------------------------------------------------+
1363            | Output Parameters : PBYTE_ pb_OutputLevel     : Output signal level        |
1364            |                                                 0 : The output is low      |
1365            |                                                 1 : The output is high     |
1366            +----------------------------------------------------------------------------+
1367            | Return Value      : 0: No error                                            |
1368            |                    -1: The handle parameter of the board is wrong          |
1369            |                    -2: Module selection wrong                              |
1370            |                    -3: Timer selection wrong                               |
1371            |                    -4: The module is not a TIMER module                    |
1372            |                    -5: Timer not initialised see function                  |
1373            |                        "i_APCI1710_InitTimer"                              |
1374            +----------------------------------------------------------------------------+
1375          */
1376
1377 INT i_APCI1710_GetTimerOutputLevel(comedi_device * dev,
1378         BYTE b_ModulNbr, BYTE b_TimerNbr, PBYTE pb_OutputLevel)
1379 {
1380         INT i_ReturnValue = 0;
1381         DWORD dw_TimerStatus;
1382
1383         /**************************/
1384         /* Test the module number */
1385         /**************************/
1386
1387         if (b_ModulNbr < 4) {
1388            /***********************/
1389                 /* Test if 82X54 timer */
1390            /***********************/
1391
1392                 if ((devpriv->s_BoardInfos.
1393                                 dw_MolduleConfiguration[b_ModulNbr] &
1394                                 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
1395               /*************************/
1396                         /* Test the timer number */
1397               /*************************/
1398
1399                         if (b_TimerNbr <= 2) {
1400                  /*****************************/
1401                                 /* Test if timer initialised */
1402                  /*****************************/
1403
1404                                 if (devpriv->
1405                                         s_ModuleInfo[b_ModulNbr].
1406                                         s_82X54ModuleInfo.
1407                                         s_82X54TimerInfo[b_TimerNbr].
1408                                         b_82X54Init == 1) {
1409                     /*************************/
1410                                         /* Latch the timer value */
1411                     /*************************/
1412
1413                                         outl((2 << b_TimerNbr) | 0xE0,
1414                                                 devpriv->s_BoardInfos.
1415                                                 ui_Address + 12 +
1416                                                 (64 * b_ModulNbr));
1417
1418                     /*************************/
1419                                         /* Read the timer status */
1420                     /*************************/
1421
1422                                         dw_TimerStatus =
1423                                                 inl(devpriv->s_BoardInfos.
1424                                                 ui_Address + 16 +
1425                                                 (b_TimerNbr * 4) +
1426                                                 (64 * b_ModulNbr));
1427
1428                                         *pb_OutputLevel =
1429                                                 (BYTE) (((dw_TimerStatus >> 7) &
1430                                                         1) ^ devpriv->
1431                                                 s_ModuleInfo[b_ModulNbr].
1432                                                 s_82X54ModuleInfo.
1433                                                 s_82X54TimerInfo[b_TimerNbr].
1434                                                 b_OutputLevel);
1435                                 } else {
1436                     /**************************************/
1437                                         /* Timer not initialised see function */
1438                     /**************************************/
1439                                         DPRINTK("Timer not initialised see function\n");
1440                                         i_ReturnValue = -5;
1441                                 }
1442                         } else {
1443                  /*************************/
1444                                 /* Timer selection wrong */
1445                  /*************************/
1446                                 DPRINTK("Timer selection wrong\n");
1447                                 i_ReturnValue = -3;
1448                         }       // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
1449                 } else {
1450               /************************************/
1451                         /* The module is not a TIMER module */
1452               /************************************/
1453                         DPRINTK("The module is not a TIMER module\n");
1454                         i_ReturnValue = -4;
1455                 }
1456         } else {
1457            /***********************/
1458                 /* Module number error */
1459            /***********************/
1460                 DPRINTK("Module number error\n");
1461                 i_ReturnValue = -2;
1462         }
1463
1464         return (i_ReturnValue);
1465 }
1466
1467 /*
1468 +----------------------------------------------------------------------------+
1469 | Function Name     : _INT_     i_APCI1710_GetTimerProgressStatus            |
1470 |                                       (BYTE_     b_BoardHandle,            |
1471 |                                        BYTE_     b_ModulNbr,               |
1472 |                                        BYTE_     b_TimerNbr,               |
1473 |                                        PBYTE_   pb_TimerStatus)            |
1474 +----------------------------------------------------------------------------+
1475 | Task              : Return the progress status (pb_TimerStatus) from       |
1476 |                     selected digital timer (b_TimerNbr) from selected timer|
1477 |                     module (b_ModulNbr).                                   |
1478 +----------------------------------------------------------------------------+
1479 | Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
1480 |                                                 APCI-1710                  |
1481 |                     BYTE_   b_ModulNbr        : Selected module number     |
1482 |                                                 (0 to 3)                   |
1483 |                     BYTE_   b_TimerNbr        : Timer number to test       |
1484 |                                                 (0 to 2)                   |
1485 +----------------------------------------------------------------------------+
1486 | Output Parameters : PBYTE_ pb_TimerStatus     : Output signal level        |
1487 |                                                 0 : Timer not in progress  |
1488 |                                                 1 : Timer in progress      |
1489 +----------------------------------------------------------------------------+
1490 | Return Value      : 0: No error                                            |
1491 |                    -1: The handle parameter of the board is wrong          |
1492 |                    -2: Module selection wrong                              |
1493 |                    -3: Timer selection wrong                               |
1494 |                    -4: The module is not a TIMER module                    |
1495 |                    -5: Timer not initialised see function                  |
1496 |                        "i_APCI1710_InitTimer"                              |
1497 +----------------------------------------------------------------------------+
1498 */
1499
1500 INT i_APCI1710_GetTimerProgressStatus(comedi_device * dev,
1501         BYTE b_ModulNbr, BYTE b_TimerNbr, PBYTE pb_TimerStatus)
1502 {
1503         INT i_ReturnValue = 0;
1504         DWORD dw_TimerStatus;
1505
1506         /**************************/
1507         /* Test the module number */
1508         /**************************/
1509
1510         if (b_ModulNbr < 4) {
1511            /***********************/
1512                 /* Test if 82X54 timer */
1513            /***********************/
1514
1515                 if ((devpriv->s_BoardInfos.
1516                                 dw_MolduleConfiguration[b_ModulNbr] &
1517                                 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
1518               /*************************/
1519                         /* Test the timer number */
1520               /*************************/
1521
1522                         if (b_TimerNbr <= 2) {
1523                  /*****************************/
1524                                 /* Test if timer initialised */
1525                  /*****************************/
1526
1527                                 if (devpriv->
1528                                         s_ModuleInfo[b_ModulNbr].
1529                                         s_82X54ModuleInfo.
1530                                         s_82X54TimerInfo[b_TimerNbr].
1531                                         b_82X54Init == 1) {
1532                     /*************************/
1533                                         /* Latch the timer value */
1534                     /*************************/
1535
1536                                         outl((2 << b_TimerNbr) | 0xE0,
1537                                                 devpriv->s_BoardInfos.
1538                                                 ui_Address + 12 +
1539                                                 (64 * b_ModulNbr));
1540
1541                     /*************************/
1542                                         /* Read the timer status */
1543                     /*************************/
1544
1545                                         dw_TimerStatus =
1546                                                 inl(devpriv->s_BoardInfos.
1547                                                 ui_Address + 16 +
1548                                                 (b_TimerNbr * 4) +
1549                                                 (64 * b_ModulNbr));
1550
1551                                         *pb_TimerStatus =
1552                                                 (BYTE) ((dw_TimerStatus) >> 8) &
1553                                                 1;
1554                                         printk("ProgressStatus : %d",
1555                                                 *pb_TimerStatus);
1556                                 } else {
1557                     /**************************************/
1558                                         /* Timer not initialised see function */
1559                     /**************************************/
1560
1561                                         i_ReturnValue = -5;
1562                                 }
1563                         } else {
1564                  /*************************/
1565                                 /* Timer selection wrong */
1566                  /*************************/
1567
1568                                 i_ReturnValue = -3;
1569                         }       // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
1570                 } else {
1571               /************************************/
1572                         /* The module is not a TIMER module */
1573               /************************************/
1574
1575                         i_ReturnValue = -4;
1576                 }
1577         } else {
1578            /***********************/
1579                 /* Module number error */
1580            /***********************/
1581
1582                 i_ReturnValue = -2;
1583         }
1584
1585         return (i_ReturnValue);
1586 }
1587
1588 /*
1589 +----------------------------------------------------------------------------+
1590 | Function Name     : _INT_     i_APCI1710_WriteTimerValue                   |
1591 |                                       (BYTE_   b_BoardHandle,              |
1592 |                                        BYTE_   b_ModulNbr,                 |
1593 |                                        BYTE_   b_TimerNbr,                 |
1594 |                                        ULONG_ ul_WriteValue)               |
1595 +----------------------------------------------------------------------------+
1596 | Task              : Write the value (ul_WriteValue) into the selected timer|
1597 |                     (b_TimerNbr) from selected timer module (b_ModulNbr).  |
1598 |                     The action in depend of the time mode selection.       |
1599 |                     See timer mode description table.                      |
1600 +----------------------------------------------------------------------------+
1601 | Input Parameters  : BYTE_   b_BoardHandle     : Handle of board            |
1602 |                                                 APCI-1710                  |
1603 |                     BYTE_   b_ModulNbr        : Selected module number     |
1604 |                                                 (0 to 3)                   |
1605 |                     BYTE_   b_TimerNbr        : Timer number to write      |
1606 |                                                 (0 to 2)                   |
1607 |                     ULONG_ ul_WriteValue      : Value to write             |
1608 +----------------------------------------------------------------------------+
1609 | Output Parameters : -                                                      |
1610 +----------------------------------------------------------------------------+
1611 | Return Value      : 0: No error                                            |
1612 |                    -1: The handle parameter of the board is wrong          |
1613 |                    -2: Module selection wrong                              |
1614 |                    -3: Timer selection wrong                               |
1615 |                    -4: The module is not a TIMER module                    |
1616 |                    -5: Timer not initialised see function                  |
1617 |                        "i_APCI1710_InitTimer"                              |
1618 +----------------------------------------------------------------------------+
1619 */
1620
1621 INT i_APCI1710_WriteTimerValue(comedi_device * dev,
1622         BYTE b_ModulNbr, BYTE b_TimerNbr, ULONG ul_WriteValue)
1623 {
1624         INT i_ReturnValue = 0;
1625
1626         /**************************/
1627         /* Test the module number */
1628         /**************************/
1629
1630         if (b_ModulNbr < 4) {
1631            /***********************/
1632                 /* Test if 82X54 timer */
1633            /***********************/
1634
1635                 if ((devpriv->s_BoardInfos.
1636                                 dw_MolduleConfiguration[b_ModulNbr] &
1637                                 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
1638               /*************************/
1639                         /* Test the timer number */
1640               /*************************/
1641
1642                         if (b_TimerNbr <= 2) {
1643                  /*****************************/
1644                                 /* Test if timer initialised */
1645                  /*****************************/
1646
1647                                 if (devpriv->
1648                                         s_ModuleInfo[b_ModulNbr].
1649                                         s_82X54ModuleInfo.
1650                                         s_82X54TimerInfo[b_TimerNbr].
1651                                         b_82X54Init == 1) {
1652                     /*******************/
1653                                         /* Write the value */
1654                     /*******************/
1655
1656                                         outl(ul_WriteValue,
1657                                                 devpriv->s_BoardInfos.
1658                                                 ui_Address + (b_TimerNbr * 4) +
1659                                                 (64 * b_ModulNbr));
1660                                 } else {
1661                     /**************************************/
1662                                         /* Timer not initialised see function */
1663                     /**************************************/
1664                                         DPRINTK("Timer not initialised see function\n");
1665                                         i_ReturnValue = -5;
1666                                 }
1667                         } else {
1668                  /*************************/
1669                                 /* Timer selection wrong */
1670                  /*************************/
1671                                 DPRINTK("Timer selection wrong\n");
1672                                 i_ReturnValue = -3;
1673                         }       // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
1674                 } else {
1675               /************************************/
1676                         /* The module is not a TIMER module */
1677               /************************************/
1678                         DPRINTK("The module is not a TIMER module\n");
1679                         i_ReturnValue = -4;
1680                 }
1681         } else {
1682            /***********************/
1683                 /* Module number error */
1684            /***********************/
1685                 DPRINTK("Module number error\n");
1686                 i_ReturnValue = -2;
1687         }
1688
1689         return (i_ReturnValue);
1690 }