Merge branch 'for-2.6.30' into for-2.6.31
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / comedi / drivers / addi-data / APCI1710_82x54.c
CommitLineData
c995fe94 1/*
75c794f0
GKH
2 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
3 *
4 * ADDI-DATA GmbH
5 * Dieselstrasse 3
6 * D-77833 Ottersweier
7 * Tel: +19(0)7223/9493-0
8 * Fax: +49(0)7223/9493-92
9 * http://www.addi-data-com
10 * info@addi-data.com
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the Free
14 * Software Foundation; either version 2 of the License, or (at your option)
15 * any later version.
16 */
c995fe94 17/*
75c794f0 18 | Description : APCI-1710 82X54 timer module |
c995fe94
ADG
19*/
20
21#include "APCI1710_82x54.h"
22
23/*
24+----------------------------------------------------------------------------+
25| Function Name : _INT_ i_APCI1710_InitTimer |
26| (BYTE_ b_BoardHandle, |
27| BYTE_ b_ModulNbr, |
28| BYTE_ b_TimerNbr, |
29| BYTE_ b_TimerMode, |
30| ULONG_ ul_ReloadValue, |
31| BYTE_ b_InputClockSelection, |
32| BYTE_ b_InputClockLevel, |
33| BYTE_ b_OutputLevel, |
34| BYTE_ b_HardwareGateLevel)
34c43922 35INT i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s,
90035c08 36 struct comedi_insn *insn,unsigned int *data)
c995fe94
ADG
37|
38+----------------------------------------------------------------------------+
39| Task : Configure the Timer (b_TimerNbr) operating mode |
40| (b_TimerMode) from selected module (b_ModulNbr). |
41| You must calling this function be for you call any |
42| other function witch access of the timer. |
43| |
44| |
45| Timer mode description table |
46| |
47|+--------+-----------------------------+--------------+--------------------+|
48||Selected+ Mode description +u_ReloadValue | Hardware gate input||
49|| mode | | description | action ||
50|+--------+-----------------------------+--------------+--------------------+|
51|| |Mode 0 is typically used | | ||
52|| |for event counting. After | | ||
53|| |the initialisation, OUT | | ||
54|| |is initially low, and | | ||
55|| 0 |will remain low until the |Start counting| Hardware gate ||
56|| |counter reaches zero. | value | ||
57|| |OUT then goes high and | | ||
58|| |remains high until a new | | ||
59|| |count is written. See | | ||
60|| |"i_APCI1710_WriteTimerValue" | | ||
61|| |function. | | ||
62|+--------+-----------------------------+--------------+--------------------+|
63|| |Mode 1 is similar to mode 0 | | ||
64|| |except for the gate input | | ||
65|| 1 |action. The gate input is not|Start counting| Hardware trigger ||
66|| |used for enabled or disabled | value | ||
67|| |the timer. | | ||
68|| |The gate input is used for | | ||
69|| |triggered the timer. | | ||
70|+--------+-----------------------------+--------------+--------------------+|
71|| |This mode functions like a | | ||
72|| |divide-by-ul_ReloadValue | | ||
73|| |counter. It is typically used| | ||
74|| |to generate a real time clock| | ||
75|| |interrupt. OUT will initially| | ||
76|| 2 |be high after the | Division | Hardware gate ||
77|| |initialisation. When the | factor | ||
78|| |initial count has decremented| | ||
79|| |to 1, OUT goes low for one | | ||
80|| |CLK pule. OUT then goes high | | ||
81|| |again, the counter reloads | | ||
82|| |the initial count | | ||
83|| |(ul_ReloadValue) and the | | ||
84|| |process is repeated. | | ||
85|| |This action can generated a | | ||
86|| |interrupt. See function | | ||
87|| |"i_APCI1710_SetBoardInt- | | ||
88|| |RoutineX" | | ||
89|| |and "i_APCI1710_EnableTimer" | | ||
90|+--------+-----------------------------+--------------+--------------------+|
91|| |Mode 3 is typically used for | | ||
92|| |baud rate generation. This | | ||
93|| |mode is similar to mode 2 | | ||
94|| |except for the duty cycle of | | ||
95|| 3 |OUT. OUT will initially be | Division | Hardware gate ||
96|| |high after the initialisation| factor | ||
97|| |When half the initial count | | ||
98|| |(ul_ReloadValue) has expired,| | ||
99|| |OUT goes low for the | | ||
100|| |remainder of the count. The | | ||
101|| |mode is periodic; the | | ||
102|| |sequence above is repeated | | ||
103|| |indefinitely. | | ||
104|+--------+-----------------------------+--------------+--------------------+|
105|| |OUT will be initially high | | ||
106|| |after the initialisation. | | ||
107|| |When the initial count | | ||
108|| 4 |expires OUT will go low for |Start counting| Hardware gate ||
109|| |one CLK pulse and then go | value | ||
110|| |high again. | | ||
111|| |The counting sequences is | | ||
112|| |triggered by writing a new | | ||
113|| |value. See | | ||
114|| |"i_APCI1710_WriteTimerValue" | | ||
115|| |function. If a new count is | | ||
116|| |written during counting, | | ||
117|| |it will be loaded on the | | ||
118|| |next CLK pulse | | ||
119|+--------+-----------------------------+--------------+--------------------+|
120|| |Mode 5 is similar to mode 4 | | ||
121|| |except for the gate input | | ||
122|| |action. The gate input is not| | ||
123|| 5 |used for enabled or disabled |Start counting| Hardware trigger ||
124|| |the timer. The gate input is | value | ||
125|| |used for triggered the timer.| | ||
126|+--------+-----------------------------+--------------+--------------------+|
127| |
128| |
129| |
130| Input clock selection table |
131| |
132| +--------------------------------+------------------------------------+ |
133| | b_InputClockSelection | Description | |
134| | parameter | | |
135| +--------------------------------+------------------------------------+ |
136| | APCI1710_PCI_BUS_CLOCK | For the timer input clock, the PCI | |
137| | | bus clock / 4 is used. This PCI bus| |
138| | | clock can be 30MHz or 33MHz. For | |
139| | | Timer 0 only this selection are | |
140| | | available. | |
141| +--------------------------------+------------------------------------+ |
142| | APCI1710_ FRONT_CONNECTOR_INPUT| Of the front connector you have the| |
143| | | possibility to inject a input clock| |
144| | | for Timer 1 or Timer 2. The source | |
145| | | from this clock can eat the output | |
146| | | clock from Timer 0 or any other | |
147| | | clock source. | |
148| +--------------------------------+------------------------------------+ |
149| |
150+----------------------------------------------------------------------------+
151| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
152| APCI-1710 |
153| BYTE_ b_ModulNbr : Module number to |
154| configure (0 to 3) |
155| BYTE_ b_TimerNbr : Timer number to |
156| configure (0 to 2) |
157| BYTE_ b_TimerMode : Timer mode selection |
158| (0 to 5) |
159| 0: Interrupt on terminal|
160| count |
161| 1: Hardware |
162| retriggerable one- |
163| shot |
164| 2: Rate generator |
165| 3: Square wave mode |
166| 4: Software triggered |
167| strobe |
168| 5: Hardware triggered |
169| strobe |
170| See timer mode |
171| description table. |
172| ULONG_ ul_ReloadValue : Start counting value |
173| or division factor |
174| See timer mode |
175| description table. |
176| BYTE_ b_InputClockSelection : Selection from input |
177| timer clock. |
178| See input clock |
179| selection table. |
180| BYTE_ b_InputClockLevel : Selection from input |
181| clock level. |
182| 0 : Low active |
183| (Input inverted) |
184| 1 : High active |
185| BYTE_ b_OutputLevel, : Selection from output |
186| clock level. |
187| 0 : Low active |
188| 1 : High active |
189| (Output inverted) |
190| BYTE_ b_HardwareGateLevel : Selection from |
191| hardware gate level. |
192| 0 : Low active |
193| (Input inverted) |
194| 1 : High active |
195| If you will not used |
196| the hardware gate set |
197| this value to 0.
198|b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
199 b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
200 b_TimerMode = (BYTE) data[0];
201 ul_ReloadValue = (ULONG) data[1];
202 b_InputClockSelection =(BYTE) data[2];
203 b_InputClockLevel =(BYTE) data[3];
204 b_OutputLevel =(BYTE) data[4];
205 b_HardwareGateLevel =(BYTE) data[5];
206+----------------------------------------------------------------------------+
207| Output Parameters : - |
208+----------------------------------------------------------------------------+
209| Return Value : 0: No error |
210| -1: The handle parameter of the board is wrong |
211| -2: Module selection wrong |
212| -3: Timer selection wrong |
213| -4: The module is not a TIMER module |
214| -5: Timer mode selection is wrong |
215| -6: Input timer clock selection is wrong |
216| -7: Selection from input clock level is wrong |
217| -8: Selection from output clock level is wrong |
218| -9: Selection from hardware gate level is wrong |
219+----------------------------------------------------------------------------+
220*/
221
34c43922 222INT i_APCI1710_InsnConfigInitTimer(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 223 struct comedi_insn * insn, unsigned int * data)
c995fe94
ADG
224{
225
226 INT i_ReturnValue = 0;
227 BYTE b_ModulNbr;
228 BYTE b_TimerNbr;
229 BYTE b_TimerMode;
230 ULONG ul_ReloadValue;
231 BYTE b_InputClockSelection;
232 BYTE b_InputClockLevel;
233 BYTE b_OutputLevel;
234 BYTE b_HardwareGateLevel;
235
236 //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
237 DWORD dw_Test = 0;
238 //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
239
240 i_ReturnValue = insn->n;
241 b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
242 b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
243 b_TimerMode = (BYTE) data[0];
244 ul_ReloadValue = (ULONG) data[1];
245 b_InputClockSelection = (BYTE) data[2];
246 b_InputClockLevel = (BYTE) data[3];
247 b_OutputLevel = (BYTE) data[4];
248 b_HardwareGateLevel = (BYTE) data[5];
249
c995fe94 250 /* Test the module number */
c995fe94 251 if (b_ModulNbr < 4) {
c995fe94 252 /* Test if 82X54 timer */
75c794f0 253 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
c995fe94 254 /* Test the timer number */
c995fe94
ADG
255
256 if (b_TimerNbr <= 2) {
c995fe94 257 /* Test the timer mode */
c995fe94
ADG
258 if (b_TimerMode <= 5) {
259 //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
c995fe94 260 /* Test te imput clock selection */
c995fe94
ADG
261 /*
262 if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) ||
263 ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1))))
264 */
265
75c794f0
GKH
266 if (((b_TimerNbr == 0) &&
267 (b_InputClockSelection == APCI1710_PCI_BUS_CLOCK)) ||
268 ((b_TimerNbr == 0) &&
269 (b_InputClockSelection == APCI1710_10MHZ)) ||
270 ((b_TimerNbr != 0) &&
271 ((b_InputClockSelection == APCI1710_PCI_BUS_CLOCK) ||
272 (b_InputClockSelection == APCI1710_FRONT_CONNECTOR_INPUT) ||
273 (b_InputClockSelection == APCI1710_10MHZ)))) {
c995fe94 274 //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
75c794f0
GKH
275 if (((b_InputClockSelection == APCI1710_10MHZ) &&
276 ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) >= 0x3131)) ||
277 (b_InputClockSelection != APCI1710_10MHZ)) {
c995fe94 278 //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
c995fe94 279 /* Test the input clock level selection */
c995fe94 280
75c794f0
GKH
281 if ((b_InputClockLevel == 0) ||
282 (b_InputClockLevel == 1)) {
283 /* Test the output clock level selection */
c995fe94 284 if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) {
c995fe94 285 /* Test the hardware gate level selection */
c995fe94
ADG
286 if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) {
287 //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
c995fe94 288 /* Test if version > 1.1 and clock selection = 10MHz */
c995fe94 289 if ((b_InputClockSelection == APCI1710_10MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) > 0x3131)) {
c995fe94 290 /* Test if 40MHz quartz on board */
c995fe94
ADG
291 dw_Test = inl(devpriv->s_BoardInfos.ui_Address + (16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)));
292
293 dw_Test = (dw_Test >> 16) & 1;
294 } else {
295 dw_Test = 1;
296 }
297
c995fe94 298 /* Test if detection OK */
c995fe94
ADG
299 if (dw_Test == 1) {
300 //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
c995fe94 301 /* Initialisation OK */
75c794f0
GKH
302 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init = 1;
303
c995fe94 304 /* Save the input clock selection */
75c794f0
GKH
305 devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockSelection = b_InputClockSelection;
306
c995fe94 307 /* Save the input clock level */
75c794f0
GKH
308 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockLevel = ~b_InputClockLevel & 1;
309
c995fe94 310 /* Save the output level */
75c794f0
GKH
311 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel = ~b_OutputLevel & 1;
312
c995fe94 313 /* Save the gate level */
75c794f0
GKH
314 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_HardwareGateLevel = b_HardwareGateLevel;
315
c995fe94 316 /* Set the configuration word and disable the timer */
c995fe94
ADG
317 //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
318 /*
319 devpriv->s_ModuleInfo [b_ModulNbr].
320 s_82X54ModuleInfo.
321 s_82X54TimerInfo [b_TimerNbr].
322 dw_ConfigurationWord = (DWORD) (((b_HardwareGateLevel << 0) & 0x1) |
323 ((b_InputClockLevel << 1) & 0x2) |
324 (((~b_OutputLevel & 1) << 2) & 0x4) |
325 ((b_InputClockSelection << 4) & 0x10));
326 */
c995fe94 327 /* Test if 10MHz selected */
c995fe94 328 if (b_InputClockSelection == APCI1710_10MHZ) {
75c794f0 329 b_InputClockSelection = 2;
c995fe94
ADG
330 }
331
75c794f0 332 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = (DWORD)(((b_HardwareGateLevel << 0) & 0x1) | ((b_InputClockLevel << 1) & 0x2) | (((~b_OutputLevel & 1) << 2) & 0x4) | ((b_InputClockSelection << 4) & 0x30));
c995fe94
ADG
333 //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
334 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));
335
c995fe94 336 /* Initialise the 82X54 Timer */
c995fe94
ADG
337 outl((DWORD) b_TimerMode, devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
338
c995fe94 339 /* Write the reload value */
c995fe94
ADG
340 outl(ul_ReloadValue, devpriv->s_BoardInfos.ui_Address + 0 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
341 //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
342 } // if (dw_Test == 1)
343 else {
c995fe94 344 /* Input timer clock selection is wrong */
75c794f0 345 i_ReturnValue = -6;
c995fe94
ADG
346 } // if (dw_Test == 1)
347 //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
348 } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
349 else {
c995fe94 350 /* Selection from hardware gate level is wrong */
c995fe94 351 DPRINTK("Selection from hardware gate level is wrong\n");
75c794f0 352 i_ReturnValue = -9;
c995fe94
ADG
353 } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
354 } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
355 else {
c995fe94 356 /* Selection from output clock level is wrong */
c995fe94 357 DPRINTK("Selection from output clock level is wrong\n");
75c794f0 358 i_ReturnValue = -8;
c995fe94
ADG
359 } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
360 } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
361 else {
c995fe94 362 /* Selection from input clock level is wrong */
c995fe94 363 DPRINTK("Selection from input clock level is wrong\n");
75c794f0 364 i_ReturnValue = -7;
c995fe94
ADG
365 } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
366 } else {
c995fe94 367 /* Input timer clock selection is wrong */
c995fe94
ADG
368 DPRINTK("Input timer clock selection is wrong\n");
369 i_ReturnValue = -6;
370 }
371 } else {
c995fe94 372 /* Input timer clock selection is wrong */
c995fe94
ADG
373 DPRINTK("Input timer clock selection is wrong\n");
374 i_ReturnValue = -6;
375 }
376 } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
377 else {
c995fe94 378 /* Timer mode selection is wrong */
c995fe94
ADG
379 DPRINTK("Timer mode selection is wrong\n");
380 i_ReturnValue = -5;
381 } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
382 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
383 else {
c995fe94 384 /* Timer selection wrong */
c995fe94
ADG
385 DPRINTK("Timer selection wrong\n");
386 i_ReturnValue = -3;
387 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
388 } else {
c995fe94 389 /* The module is not a TIMER module */
c995fe94
ADG
390 DPRINTK("The module is not a TIMER module\n");
391 i_ReturnValue = -4;
392 }
393 } else {
c995fe94 394 /* Module number error */
c995fe94
ADG
395 DPRINTK("Module number error\n");
396 i_ReturnValue = -2;
397 }
398
399 return (i_ReturnValue);
400}
401
402/*
403+----------------------------------------------------------------------------+
404| Function Name : _INT_ i_APCI1710_EnableTimer |
405| (BYTE_ b_BoardHandle, |
406| BYTE_ b_ModulNbr, |
407| BYTE_ b_TimerNbr, |
408| BYTE_ b_InterruptEnable)
34c43922 409INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,struct comedi_subdevice *s,
90035c08 410 struct comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
411+----------------------------------------------------------------------------+
412| Task : Enable OR Disable the Timer (b_TimerNbr) from selected module |
413| (b_ModulNbr). You must calling the |
414| "i_APCI1710_InitTimer" function be for you call this |
415| function. If you enable the timer interrupt, the timer |
416| generate a interrupt after the timer value reach |
417| the zero. See function "i_APCI1710_SetBoardIntRoutineX"|
418+----------------------------------------------------------------------------+
419| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
420| APCI-1710 |
421| BYTE_ b_ModulNbr : Selected module number |
422| (0 to 3) |
423| BYTE_ b_TimerNbr : Timer number to enable |
424| (0 to 2) |
425| BYTE_ b_InterruptEnable : Enable or disable the |
426| timer interrupt. |
427| APCI1710_ENABLE : |
428| Enable the timer interrupt |
429| APCI1710_DISABLE : |
430| Disable the timer interrupt|
431i_ReturnValue=insn->n;
432 b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
433 b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
434 b_ActionType = (BYTE) data[0]; // enable disable
435+----------------------------------------------------------------------------+
436| Output Parameters : - |
437+----------------------------------------------------------------------------+
438| Return Value : 0: No error |
439| -1: The handle parameter of the board is wrong |
440| -2: Module selection wrong |
441| -3: Timer selection wrong |
442| -4: The module is not a TIMER module |
443| -5: Timer not initialised see function |
444| "i_APCI1710_InitTimer" |
445| -6: Interrupt parameter is wrong |
446| -7: Interrupt function not initialised. |
447| See function "i_APCI1710_SetBoardIntRoutineX" |
448+----------------------------------------------------------------------------+
449*/
450
71b5f4f1 451INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device * dev,
34c43922 452 struct comedi_subdevice * s,
90035c08 453 struct comedi_insn * insn, unsigned int * data)
c995fe94
ADG
454{
455 INT i_ReturnValue = 0;
456 DWORD dw_DummyRead;
457 BYTE b_ModulNbr;
458 BYTE b_TimerNbr;
459 BYTE b_ActionType;
460 BYTE b_InterruptEnable;
461
462 i_ReturnValue = insn->n;
463 b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
464 b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
465 b_ActionType = (BYTE) data[0]; // enable disable
c995fe94 466
75c794f0 467 /* Test the module number */
c995fe94 468 if (b_ModulNbr < 4) {
c995fe94 469 /* Test if 82X54 timer */
75c794f0 470 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
c995fe94 471 /* Test the timer number */
c995fe94 472 if (b_TimerNbr <= 2) {
c995fe94 473 /* Test if timer initialised */
75c794f0 474 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
c995fe94
ADG
475
476 switch (b_ActionType) {
477 case APCI1710_ENABLE:
75c794f0 478 b_InterruptEnable = (BYTE) data[1];
c995fe94 479 /* Test the interrupt selection */
75c794f0
GKH
480 if ((b_InterruptEnable == APCI1710_ENABLE) ||
481 (b_InterruptEnable == APCI1710_DISABLE)) {
482 if (b_InterruptEnable == APCI1710_ENABLE) {
483
484 dw_DummyRead = inl(devpriv->s_BoardInfos.ui_Address + 12 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
485
c995fe94 486 /* Enable the interrupt */
75c794f0
GKH
487 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord | 0x8;
488
489 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));
c995fe94
ADG
490 devpriv->tsk_Current = current; // Save the current process task structure
491
492 } // if (b_InterruptEnable == APCI1710_ENABLE)
493 else {
c995fe94 494 /* Disable the interrupt */
75c794f0
GKH
495 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
496
497 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));
498
c995fe94 499 /* Save the interrupt flag */
75c794f0 500 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
c995fe94
ADG
501 } // if (b_InterruptEnable == APCI1710_ENABLE)
502
c995fe94 503 /* Test if error occur */
c995fe94 504 if (i_ReturnValue >= 0) {
c995fe94 505 /* Save the interrupt flag */
75c794f0 506 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask | ((1 & b_InterruptEnable) << b_TimerNbr);
c995fe94 507
75c794f0 508 /* Enable the timer */
c995fe94
ADG
509 outl(1, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
510 }
511 } else {
c995fe94 512 /* Interrupt parameter is wrong */
c995fe94
ADG
513 DPRINTK("\n");
514 i_ReturnValue = -6;
515 }
516 break;
517 case APCI1710_DISABLE:
c995fe94 518 /* Test the interrupt flag */
75c794f0 519 if (((devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask >> b_TimerNbr) & 1) == 1) {
c995fe94 520 /* Disable the interrupt */
75c794f0
GKH
521
522 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr]. dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
523
524 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));
525
c995fe94 526 /* Save the interrupt flag */
75c794f0 527 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
c995fe94
ADG
528 }
529
c995fe94 530 /* Disable the timer */
75c794f0 531 outl(0, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
c995fe94
ADG
532 break;
533 } // Switch end
534 } else {
c995fe94 535 /* Timer not initialised see function */
75c794f0 536 DPRINTK ("Timer not initialised see function\n");
c995fe94
ADG
537 i_ReturnValue = -5;
538 }
539 } else {
c995fe94 540 /* Timer selection wrong */
c995fe94
ADG
541 DPRINTK("Timer selection wrong\n");
542 i_ReturnValue = -3;
543 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
544 } else {
c995fe94 545 /* The module is not a TIMER module */
c995fe94
ADG
546 DPRINTK("The module is not a TIMER module\n");
547 i_ReturnValue = -4;
548 }
549 } else {
c995fe94 550 /* Module number error */
c995fe94
ADG
551 DPRINTK("Module number error\n");
552 i_ReturnValue = -2;
553 }
554
555 return (i_ReturnValue);
556}
557
558/*
559+----------------------------------------------------------------------------+
560| Function Name : _INT_ i_APCI1710_ReadAllTimerValue |
561| (BYTE_ b_BoardHandle, |
562| BYTE_ b_ModulNbr, |
563| PULONG_ pul_TimerValueArray)
34c43922 564INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_subdevice *s,
90035c08 565 struct comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
566+----------------------------------------------------------------------------+
567| Task : Return the all timer values from selected timer |
568| module (b_ModulNbr). |
569+----------------------------------------------------------------------------+
570| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
571| APCI-1710 |
572| BYTE_ b_ModulNbr : Selected module number |
573| (0 to 3) |
574+----------------------------------------------------------------------------+
575| Output Parameters : PULONG_ pul_TimerValueArray : Timer value array. |
576| Element 0 contain the timer 0 value. |
577| Element 1 contain the timer 1 value. |
578| Element 2 contain the timer 2 value. |
579+----------------------------------------------------------------------------+
580| Return Value : 0: No error |
581| -1: The handle parameter of the board is wrong |
582| -2: Module selection wrong |
583| -3: The module is not a TIMER module |
584| -4: Timer 0 not initialised see function |
585| "i_APCI1710_InitTimer" |
586| -5: Timer 1 not initialised see function |
587| "i_APCI1710_InitTimer" |
588| -6: Timer 2 not initialised see function |
589| "i_APCI1710_InitTimer" |
590+----------------------------------------------------------------------------+
591*/
592
34c43922 593INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
90035c08 594 struct comedi_insn *insn, unsigned int *data)
c995fe94
ADG
595{
596 INT i_ReturnValue = 0;
597 BYTE b_ModulNbr, b_ReadType;
598 PULONG pul_TimerValueArray;
599
600 b_ModulNbr = CR_AREF(insn->chanspec);
601 b_ReadType = CR_CHAN(insn->chanspec);
602 pul_TimerValueArray = (PULONG) data;
603 i_ReturnValue = insn->n;
604
605 switch (b_ReadType) {
606 case APCI1710_TIMER_READINTERRUPT:
607
75c794f0
GKH
608 data[0] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].b_OldModuleMask;
609 data[1] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldInterruptMask;
610 data[2] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
c995fe94 611
75c794f0
GKH
612 /* Increment the read FIFO */
613 devpriv->s_InterruptParameters.ui_Read = (devpriv->s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
c995fe94
ADG
614
615 break;
616
617 case APCI1710_TIMER_READALLTIMER:
c995fe94 618 /* Test the module number */
c995fe94 619 if (b_ModulNbr < 4) {
c995fe94 620 /* Test if 82X54 timer */
75c794f0 621 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
c995fe94 622 /* Test if timer 0 iniutialised */
75c794f0 623 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[0].b_82X54Init == 1) {
c995fe94 624 /* Test if timer 1 iniutialised */
75c794f0 625 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[1].b_82X54Init == 1) {
c995fe94 626 /* Test if timer 2 iniutialised */
75c794f0 627 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[2].b_82X54Init == 1) {
c995fe94 628 /* Latch all counter */
75c794f0 629 outl(0x17, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
c995fe94 630
c995fe94 631 /* Read the timer 0 value */
75c794f0 632 pul_TimerValueArray[0] = inl(devpriv->s_BoardInfos.ui_Address + 0 + (64 * b_ModulNbr));
c995fe94 633
c995fe94 634 /* Read the timer 1 value */
75c794f0 635 pul_TimerValueArray[1] = inl(devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
c995fe94 636
c995fe94 637 /* Read the timer 2 value */
75c794f0 638 pul_TimerValueArray[2] = inl(devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr));
c995fe94 639 } else {
c995fe94 640 /* Timer 2 not initialised see function */
c995fe94
ADG
641 DPRINTK("Timer 2 not initialised see function\n");
642 i_ReturnValue = -6;
643 }
644 } else {
c995fe94 645 /* Timer 1 not initialised see function */
c995fe94
ADG
646 DPRINTK("Timer 1 not initialised see function\n");
647 i_ReturnValue = -5;
648 }
649 } else {
c995fe94 650 /* Timer 0 not initialised see function */
c995fe94
ADG
651 DPRINTK("Timer 0 not initialised see function\n");
652 i_ReturnValue = -4;
653 }
654 } else {
c995fe94 655 /* The module is not a TIMER module */
c995fe94
ADG
656 DPRINTK("The module is not a TIMER module\n");
657 i_ReturnValue = -3;
658 }
659 } else {
c995fe94 660 /* Module number error */
c995fe94
ADG
661 DPRINTK("Module number error\n");
662 i_ReturnValue = -2;
663 }
664
665 } // End of Switch
666 return (i_ReturnValue);
667}
668
669/*
670+----------------------------------------------------------------------------+
71b5f4f1 671| Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev,
90035c08 672struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
673+----------------------------------------------------------------------------+
674| Task : Read write functions for Timer |
675+----------------------------------------------------------------------------+
676| Input Parameters :
677+----------------------------------------------------------------------------+
678| Output Parameters : - |
679+----------------------------------------------------------------------------+
680| Return Value :
681+----------------------------------------------------------------------------+
682*/
683
34c43922 684INT i_APCI1710_InsnBitsTimer(struct comedi_device * dev, struct comedi_subdevice * s,
90035c08 685 struct comedi_insn * insn, unsigned int * data)
c995fe94
ADG
686{
687 BYTE b_BitsType;
688 INT i_ReturnValue = 0;
689 b_BitsType = data[0];
690
691 printk("\n82X54");
692
693 switch (b_BitsType) {
694 case APCI1710_TIMER_READVALUE:
695 i_ReturnValue = i_APCI1710_ReadTimerValue(dev,
75c794f0
GKH
696 (BYTE)CR_AREF(insn->chanspec),
697 (BYTE)CR_CHAN(insn->chanspec),
698 (PULONG) & data[0]);
c995fe94
ADG
699 break;
700
701 case APCI1710_TIMER_GETOUTPUTLEVEL:
702 i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev,
75c794f0
GKH
703 (BYTE)CR_AREF(insn->chanspec),
704 (BYTE)CR_CHAN(insn->chanspec),
705 (PBYTE) &data[0]);
c995fe94
ADG
706 break;
707
708 case APCI1710_TIMER_GETPROGRESSSTATUS:
709 i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev,
75c794f0
GKH
710 (BYTE)CR_AREF(insn->chanspec),
711 (BYTE)CR_CHAN(insn->chanspec),
712 (PBYTE)&data[0]);
c995fe94
ADG
713 break;
714
715 case APCI1710_TIMER_WRITEVALUE:
716 i_ReturnValue = i_APCI1710_WriteTimerValue(dev,
75c794f0
GKH
717 (BYTE)CR_AREF(insn->chanspec),
718 (BYTE)CR_CHAN(insn->chanspec),
719 (ULONG)data[1]);
c995fe94
ADG
720
721 break;
722
723 default:
724 printk("Bits Config Parameter Wrong\n");
725 i_ReturnValue = -1;
726 }
727
728 if (i_ReturnValue >= 0)
729 i_ReturnValue = insn->n;
730 return (i_ReturnValue);
731}
732
733/*
734+----------------------------------------------------------------------------+
735| Function Name : _INT_ i_APCI1710_ReadTimerValue |
736| (BYTE_ b_BoardHandle, |
737| BYTE_ b_ModulNbr, |
738| BYTE_ b_TimerNbr, |
739| PULONG_ pul_TimerValue) |
740+----------------------------------------------------------------------------+
741| Task : Return the timer value from selected digital timer |
742| (b_TimerNbr) from selected timer module (b_ModulNbr). |
743+----------------------------------------------------------------------------+
744| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
745| APCI-1710 |
746| BYTE_ b_ModulNbr : Selected module number |
747| (0 to 3) |
748| BYTE_ b_TimerNbr : Timer number to read |
749| (0 to 2) |
750+----------------------------------------------------------------------------+
751| Output Parameters : PULONG_ pul_TimerValue : Timer value |
752+----------------------------------------------------------------------------+
753| Return Value : 0: No error |
754| -1: The handle parameter of the board is wrong |
755| -2: Module selection wrong |
756| -3: Timer selection wrong |
757| -4: The module is not a TIMER module |
758| -5: Timer not initialised see function |
759| "i_APCI1710_InitTimer" |
760+----------------------------------------------------------------------------+
761*/
762
71b5f4f1 763INT i_APCI1710_ReadTimerValue(struct comedi_device * dev,
75c794f0
GKH
764 BYTE b_ModulNbr, BYTE b_TimerNbr,
765 PULONG pul_TimerValue)
c995fe94
ADG
766{
767 INT i_ReturnValue = 0;
768
c995fe94 769 /* Test the module number */
c995fe94 770 if (b_ModulNbr < 4) {
c995fe94 771 /* Test if 82X54 timer */
c995fe94 772 if ((devpriv->s_BoardInfos.
75c794f0
GKH
773 dw_MolduleConfiguration[b_ModulNbr] &
774 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
c995fe94 775 /* Test the timer number */
c995fe94 776 if (b_TimerNbr <= 2) {
c995fe94 777 /* Test if timer initialised */
c995fe94 778 if (devpriv->
75c794f0
GKH
779 s_ModuleInfo[b_ModulNbr].
780 s_82X54ModuleInfo.
781 s_82X54TimerInfo[b_TimerNbr].
782 b_82X54Init == 1) {
c995fe94 783 /* Latch the timer value */
c995fe94 784 outl((2 << b_TimerNbr) | 0xD0,
75c794f0
GKH
785 devpriv->s_BoardInfos.
786 ui_Address + 12 +
787 (64 * b_ModulNbr));
c995fe94 788
c995fe94 789 /* Read the counter value */
c995fe94 790 *pul_TimerValue =
75c794f0 791 inl(devpriv->s_BoardInfos.
c995fe94
ADG
792 ui_Address + (b_TimerNbr * 4) +
793 (64 * b_ModulNbr));
794 } else {
c995fe94 795 /* Timer not initialised see function */
c995fe94
ADG
796 DPRINTK("Timer not initialised see function\n");
797 i_ReturnValue = -5;
798 }
799 } else {
c995fe94 800 /* Timer selection wrong */
c995fe94
ADG
801 DPRINTK("Timer selection wrong\n");
802 i_ReturnValue = -3;
803 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
804 } else {
c995fe94 805 /* The module is not a TIMER module */
c995fe94
ADG
806 DPRINTK("The module is not a TIMER module\n");
807 i_ReturnValue = -4;
808 }
809 } else {
c995fe94 810 /* Module number error */
c995fe94
ADG
811 DPRINTK("Module number error\n");
812 i_ReturnValue = -2;
813 }
814
815 return (i_ReturnValue);
816}
817
818 /*
819 +----------------------------------------------------------------------------+
820 | Function Name : _INT_ i_APCI1710_GetTimerOutputLevel |
821 | (BYTE_ b_BoardHandle, |
822 | BYTE_ b_ModulNbr, |
823 | BYTE_ b_TimerNbr, |
824 | PBYTE_ pb_OutputLevel) |
825 +----------------------------------------------------------------------------+
826 | Task : Return the output signal level (pb_OutputLevel) from |
827 | selected digital timer (b_TimerNbr) from selected timer|
828 | module (b_ModulNbr). |
829 +----------------------------------------------------------------------------+
830 | Input Parameters : BYTE_ b_BoardHandle : Handle of board |
831 | APCI-1710 |
832 | BYTE_ b_ModulNbr : Selected module number |
833 | (0 to 3) |
834 | BYTE_ b_TimerNbr : Timer number to test |
835 | (0 to 2) |
836 +----------------------------------------------------------------------------+
837 | Output Parameters : PBYTE_ pb_OutputLevel : Output signal level |
838 | 0 : The output is low |
839 | 1 : The output is high |
840 +----------------------------------------------------------------------------+
841 | Return Value : 0: No error |
842 | -1: The handle parameter of the board is wrong |
843 | -2: Module selection wrong |
844 | -3: Timer selection wrong |
845 | -4: The module is not a TIMER module |
846 | -5: Timer not initialised see function |
847 | "i_APCI1710_InitTimer" |
848 +----------------------------------------------------------------------------+
849 */
850
71b5f4f1 851INT i_APCI1710_GetTimerOutputLevel(struct comedi_device * dev,
75c794f0
GKH
852 BYTE b_ModulNbr, BYTE b_TimerNbr,
853 PBYTE pb_OutputLevel)
c995fe94
ADG
854{
855 INT i_ReturnValue = 0;
856 DWORD dw_TimerStatus;
857
c995fe94 858 /* Test the module number */
c995fe94 859 if (b_ModulNbr < 4) {
c995fe94 860 /* Test if 82X54 timer */
75c794f0 861 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
c995fe94 862 /* Test the timer number */
c995fe94 863 if (b_TimerNbr <= 2) {
c995fe94 864 /* Test if timer initialised */
75c794f0 865 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
c995fe94 866 /* Latch the timer value */
75c794f0 867 outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
c995fe94 868
c995fe94 869 /* Read the timer status */
75c794f0 870 dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
c995fe94 871
75c794f0 872 *pb_OutputLevel = (BYTE) (((dw_TimerStatus >> 7) & 1) ^ devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel);
c995fe94 873 } else {
c995fe94 874 /* Timer not initialised see function */
c995fe94
ADG
875 DPRINTK("Timer not initialised see function\n");
876 i_ReturnValue = -5;
877 }
878 } else {
c995fe94 879 /* Timer selection wrong */
c995fe94
ADG
880 DPRINTK("Timer selection wrong\n");
881 i_ReturnValue = -3;
882 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
883 } else {
c995fe94 884 /* The module is not a TIMER module */
c995fe94
ADG
885 DPRINTK("The module is not a TIMER module\n");
886 i_ReturnValue = -4;
887 }
888 } else {
c995fe94 889 /* Module number error */
c995fe94
ADG
890 DPRINTK("Module number error\n");
891 i_ReturnValue = -2;
892 }
893
894 return (i_ReturnValue);
895}
896
897/*
898+----------------------------------------------------------------------------+
899| Function Name : _INT_ i_APCI1710_GetTimerProgressStatus |
900| (BYTE_ b_BoardHandle, |
901| BYTE_ b_ModulNbr, |
902| BYTE_ b_TimerNbr, |
903| PBYTE_ pb_TimerStatus) |
904+----------------------------------------------------------------------------+
905| Task : Return the progress status (pb_TimerStatus) from |
906| selected digital timer (b_TimerNbr) from selected timer|
907| module (b_ModulNbr). |
908+----------------------------------------------------------------------------+
909| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
910| APCI-1710 |
911| BYTE_ b_ModulNbr : Selected module number |
912| (0 to 3) |
913| BYTE_ b_TimerNbr : Timer number to test |
914| (0 to 2) |
915+----------------------------------------------------------------------------+
916| Output Parameters : PBYTE_ pb_TimerStatus : Output signal level |
917| 0 : Timer not in progress |
918| 1 : Timer in progress |
919+----------------------------------------------------------------------------+
920| Return Value : 0: No error |
921| -1: The handle parameter of the board is wrong |
922| -2: Module selection wrong |
923| -3: Timer selection wrong |
924| -4: The module is not a TIMER module |
925| -5: Timer not initialised see function |
926| "i_APCI1710_InitTimer" |
927+----------------------------------------------------------------------------+
928*/
929
71b5f4f1 930INT i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
75c794f0
GKH
931 BYTE b_ModulNbr, BYTE b_TimerNbr,
932 PBYTE pb_TimerStatus)
c995fe94
ADG
933{
934 INT i_ReturnValue = 0;
935 DWORD dw_TimerStatus;
936
c995fe94 937 /* Test the module number */
c995fe94 938 if (b_ModulNbr < 4) {
c995fe94 939 /* Test if 82X54 timer */
c995fe94 940
75c794f0 941 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
c995fe94 942 /* Test the timer number */
c995fe94 943 if (b_TimerNbr <= 2) {
c995fe94 944 /* Test if timer initialised */
75c794f0 945 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
c995fe94 946 /* Latch the timer value */
75c794f0 947 outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
c995fe94 948
c995fe94 949 /* Read the timer status */
75c794f0 950 dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
c995fe94 951
75c794f0
GKH
952 *pb_TimerStatus = (BYTE) ((dw_TimerStatus) >> 8) & 1;
953 printk("ProgressStatus : %d", *pb_TimerStatus);
c995fe94 954 } else {
c995fe94 955 /* Timer not initialised see function */
c995fe94
ADG
956 i_ReturnValue = -5;
957 }
958 } else {
c995fe94 959 /* Timer selection wrong */
c995fe94
ADG
960 i_ReturnValue = -3;
961 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
962 } else {
c995fe94 963 /* The module is not a TIMER module */
c995fe94
ADG
964
965 i_ReturnValue = -4;
966 }
967 } else {
c995fe94 968 /* Module number error */
c995fe94
ADG
969
970 i_ReturnValue = -2;
971 }
972
75c794f0 973 return i_ReturnValue;
c995fe94
ADG
974}
975
976/*
977+----------------------------------------------------------------------------+
978| Function Name : _INT_ i_APCI1710_WriteTimerValue |
979| (BYTE_ b_BoardHandle, |
980| BYTE_ b_ModulNbr, |
981| BYTE_ b_TimerNbr, |
982| ULONG_ ul_WriteValue) |
983+----------------------------------------------------------------------------+
984| Task : Write the value (ul_WriteValue) into the selected timer|
985| (b_TimerNbr) from selected timer module (b_ModulNbr). |
986| The action in depend of the time mode selection. |
987| See timer mode description table. |
988+----------------------------------------------------------------------------+
989| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
990| APCI-1710 |
991| BYTE_ b_ModulNbr : Selected module number |
992| (0 to 3) |
993| BYTE_ b_TimerNbr : Timer number to write |
994| (0 to 2) |
995| ULONG_ ul_WriteValue : Value to write |
996+----------------------------------------------------------------------------+
997| Output Parameters : - |
998+----------------------------------------------------------------------------+
999| Return Value : 0: No error |
1000| -1: The handle parameter of the board is wrong |
1001| -2: Module selection wrong |
1002| -3: Timer selection wrong |
1003| -4: The module is not a TIMER module |
1004| -5: Timer not initialised see function |
1005| "i_APCI1710_InitTimer" |
1006+----------------------------------------------------------------------------+
1007*/
1008
71b5f4f1 1009INT i_APCI1710_WriteTimerValue(struct comedi_device * dev,
75c794f0
GKH
1010 BYTE b_ModulNbr, BYTE b_TimerNbr,
1011 ULONG ul_WriteValue)
c995fe94
ADG
1012{
1013 INT i_ReturnValue = 0;
1014
c995fe94 1015 /* Test the module number */
c995fe94 1016 if (b_ModulNbr < 4) {
c995fe94 1017 /* Test if 82X54 timer */
75c794f0 1018 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
c995fe94 1019 /* Test the timer number */
c995fe94 1020 if (b_TimerNbr <= 2) {
c995fe94 1021 /* Test if timer initialised */
75c794f0 1022 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
c995fe94 1023 /* Write the value */
75c794f0 1024 outl(ul_WriteValue, devpriv->s_BoardInfos.ui_Address + (b_TimerNbr * 4) + (64 * b_ModulNbr));
c995fe94 1025 } else {
c995fe94 1026 /* Timer not initialised see function */
c995fe94
ADG
1027 DPRINTK("Timer not initialised see function\n");
1028 i_ReturnValue = -5;
1029 }
1030 } else {
c995fe94 1031 /* Timer selection wrong */
c995fe94
ADG
1032 DPRINTK("Timer selection wrong\n");
1033 i_ReturnValue = -3;
1034 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
1035 } else {
c995fe94 1036 /* The module is not a TIMER module */
c995fe94
ADG
1037 DPRINTK("The module is not a TIMER module\n");
1038 i_ReturnValue = -4;
1039 }
1040 } else {
c995fe94 1041 /* Module number error */
c995fe94
ADG
1042 DPRINTK("Module number error\n");
1043 i_ReturnValue = -2;
1044 }
1045
75c794f0 1046 return i_ReturnValue;
c995fe94 1047}