Commit | Line | Data |
---|---|---|
c995fe94 ADG |
1 | /** |
2 | @verbatim | |
3 | ||
4 | Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. | |
5 | ||
356cdbcb BP |
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 | |
c995fe94 ADG |
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 : APCI-1500 | Compiler : GCC | | |
33 | | Module name : hwdrv_apci1500.c| Version : 2.96 | | |
34 | +-------------------------------+---------------------------------------+ | |
35 | | Project manager: Eric Stolz | Date : 02/12/2002 | | |
36 | +-------------------------------+---------------------------------------+ | |
37 | | Description : Hardware Layer Acces For APCI-1500 | | |
38 | +-----------------------------------------------------------------------+ | |
39 | | UPDATES | | |
40 | +----------+-----------+------------------------------------------------+ | |
41 | | Date | Author | Description of updates | | |
42 | +----------+-----------+------------------------------------------------+ | |
43 | | | | | | |
44 | | | | | | |
45 | | | | | | |
46 | +----------+-----------+------------------------------------------------+ | |
47 | */ | |
48 | #include "hwdrv_apci1500.h" | |
49 | ||
50 | int i_TimerCounter1Init = 0; | |
51 | int i_TimerCounter2Init = 0; | |
52 | int i_WatchdogCounter3Init = 0; | |
53 | int i_Event1Status = 0, i_Event2Status = 0; | |
54 | int i_TimerCounterWatchdogInterrupt = 0; | |
55 | int i_Logic = 0, i_CounterLogic = 0; | |
56 | int i_InterruptMask = 0; | |
57 | int i_InputChannel = 0; | |
58 | int i_TimerCounter1Enabled = 0, i_TimerCounter2Enabled = | |
59 | 0, i_WatchdogCounter3Enabled = 0; | |
60 | ||
61 | /* | |
62 | +----------------------------------------------------------------------------+ | |
63 | | Function Name : int i_APCI1500_ConfigDigitalInputEvent | | |
34c43922 | 64 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
90035c08 | 65 | | struct comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
66 | +----------------------------------------------------------------------------+ |
67 | | Task : An event can be generated for each port. | | |
68 | | The first event is related to the first 8 channels | | |
69 | | (port 1) and the second to the following 6 channels | | |
70 | | (port 2). An interrupt is generated when one or both | | |
71 | | events have occurred | | |
72 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 73 | | Input Parameters : struct comedi_device *dev : Driver handle | |
790c5541 | 74 | | unsigned int *data : Data Pointer contains | |
c995fe94 ADG |
75 | | configuration parameters as below | |
76 | | | | |
77 | | data[0] :Number of the input port on | | |
78 | | which the event will take place | | |
79 | | (1 or 2) | |
356cdbcb | 80 | | data[1] : The event logic for port 1 has | |
c995fe94 ADG |
81 | | three possibilities | |
82 | | :0 APCI1500_AND :This logic | | |
83 | | links | | |
84 | | the inputs | | |
85 | | with an AND | | |
86 | | logic. | | |
87 | | 1 APCI1500_OR :This logic | | |
88 | | links | | |
89 | | the inputs | | |
90 | | with a | | |
91 | | OR logic. | | |
92 | | 2 APCI1500_OR_PRIORITY | | |
93 | | :This logic | | |
94 | | links | | |
95 | | the inputs | | |
96 | | with a | | |
97 | | priority | | |
98 | | OR logic. | | |
99 | | Input 1 | | |
100 | | has the | | |
101 | | highest | | |
102 | | priority | | |
103 | | level and | | |
104 | | input 8 | | |
105 | | the smallest| | |
106 | | For the second port the user has| | |
107 | | 1 possibility: | | |
108 | | APCI1500_OR :This logic | | |
109 | | links | | |
110 | | the inputs | | |
111 | | with a | | |
112 | | polarity | | |
113 | | OR logic | | |
114 | | data[2] : These 8-character word for port1| | |
115 | | and 6-character word for port 2 | | |
116 | | give the mask of the event. | | |
117 | | Each place gives the state | | |
118 | | of the input channels and can | | |
119 | | have one of these six characters| | |
120 | | | | |
121 | | 0 : This input must be on 0 | | |
122 | | 1 : This input must be on 1 | | |
123 | | 2 : This input reacts to | | |
124 | | a falling edge | | |
125 | | 3 : This input reacts to a | | |
126 | | rising edge | | |
127 | | 4 : This input reacts to both edges | | |
128 | | | |
129 | | 5 : This input is not | | |
130 | | used for event | | |
131 | +----------------------------------------------------------------------------+ | |
132 | | Output Parameters : -- | | |
133 | +----------------------------------------------------------------------------+ | |
134 | | Return Value : TRUE : No error occur | | |
135 | | : FALSE : Error occur. Return the error | | |
136 | | | | |
137 | +----------------------------------------------------------------------------+ | |
138 | */ | |
139 | ||
da91b269 BP |
140 | int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev, |
141 | struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) | |
c995fe94 ADG |
142 | { |
143 | int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0; | |
144 | int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0; | |
145 | int i_PatternTransitionCount = 0, i_RegValue; | |
146 | int i; | |
147 | ||
148 | /*************************************************/ | |
149 | /* Selects the master interrupt control register */ | |
150 | /*************************************************/ | |
151 | outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, | |
152 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
153 | /**********************************************/ | |
154 | /* Disables the main interrupt on the board */ | |
155 | /**********************************************/ | |
156 | outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
157 | ||
158 | if (data[0] == 1) { | |
159 | i_MaxChannel = 8; | |
c47375f3 | 160 | } /* if (data[0] == 1) */ |
c995fe94 ADG |
161 | else { |
162 | if (data[0] == 2) { | |
163 | i_MaxChannel = 6; | |
c47375f3 | 164 | } /* if(data[0]==2) */ |
c995fe94 ADG |
165 | else { |
166 | printk("\nThe specified port event does not exist\n"); | |
167 | return -EINVAL; | |
c47375f3 BP |
168 | } /* else if(data[0]==2) */ |
169 | } /* else if (data[0] == 1) */ | |
c995fe94 ADG |
170 | switch (data[1]) { |
171 | case 0: | |
172 | data[1] = APCI1500_AND; | |
173 | break; | |
174 | case 1: | |
175 | data[1] = APCI1500_OR; | |
176 | break; | |
177 | case 2: | |
178 | data[1] = APCI1500_OR_PRIORITY; | |
179 | break; | |
180 | default: | |
181 | printk("\nThe specified interrupt logic does not exist\n"); | |
182 | return -EINVAL; | |
c47375f3 | 183 | } /* switch(data[1]); */ |
c995fe94 ADG |
184 | |
185 | i_Logic = data[1]; | |
186 | for (i_Count = i_MaxChannel, i = 0; i_Count > 0; i_Count--, i++) { | |
187 | i_EventMask = data[2 + i]; | |
188 | switch (i_EventMask) { | |
189 | case 0: | |
190 | i_PatternMask = | |
191 | i_PatternMask | (1 << (i_MaxChannel - i_Count)); | |
192 | break; | |
193 | case 1: | |
194 | i_PatternMask = | |
195 | i_PatternMask | (1 << (i_MaxChannel - i_Count)); | |
196 | i_PatternPolarity = | |
197 | i_PatternPolarity | (1 << (i_MaxChannel - | |
198 | i_Count)); | |
199 | break; | |
200 | case 2: | |
201 | i_PatternMask = | |
202 | i_PatternMask | (1 << (i_MaxChannel - i_Count)); | |
203 | i_PatternTransition = | |
204 | i_PatternTransition | (1 << (i_MaxChannel - | |
205 | i_Count)); | |
206 | break; | |
207 | case 3: | |
208 | i_PatternMask = | |
209 | i_PatternMask | (1 << (i_MaxChannel - i_Count)); | |
210 | i_PatternPolarity = | |
211 | i_PatternPolarity | (1 << (i_MaxChannel - | |
212 | i_Count)); | |
213 | i_PatternTransition = | |
214 | i_PatternTransition | (1 << (i_MaxChannel - | |
215 | i_Count)); | |
216 | break; | |
217 | case 4: | |
218 | i_PatternTransition = | |
219 | i_PatternTransition | (1 << (i_MaxChannel - | |
220 | i_Count)); | |
221 | break; | |
222 | case 5: | |
223 | break; | |
224 | default: | |
225 | printk("\nThe option indicated in the event mask does not exist\n"); | |
226 | return -EINVAL; | |
c47375f3 BP |
227 | } /* switch(i_EventMask) */ |
228 | } /* for (i_Count = i_MaxChannel; i_Count >0;i_Count --) */ | |
c995fe94 ADG |
229 | |
230 | if (data[0] == 1) { | |
231 | /****************************/ | |
232 | /* Test the interrupt logic */ | |
233 | /****************************/ | |
234 | ||
235 | if (data[1] == APCI1500_AND || | |
236 | data[1] == APCI1500_OR || | |
237 | data[1] == APCI1500_OR_PRIORITY) { | |
238 | /**************************************/ | |
239 | /* Tests if a transition was declared */ | |
240 | /* for a OR PRIORITY logic */ | |
241 | /**************************************/ | |
242 | ||
243 | if (data[1] == APCI1500_OR_PRIORITY | |
244 | && i_PatternTransition != 0) { | |
245 | /********************************************/ | |
246 | /* Transition error on an OR PRIORITY logic */ | |
247 | /********************************************/ | |
248 | printk("\nTransition error on an OR PRIORITY logic\n"); | |
249 | return -EINVAL; | |
c47375f3 | 250 | } /* if (data[1]== APCI1500_OR_PRIORITY && i_PatternTransition != 0) */ |
c995fe94 ADG |
251 | |
252 | /*************************************/ | |
253 | /* Tests if more than one transition */ | |
254 | /* was declared for an AND logic */ | |
255 | /*************************************/ | |
256 | ||
257 | if (data[1] == APCI1500_AND) { | |
258 | for (i_Count = 0; i_Count < 8; i_Count++) { | |
259 | i_PatternTransitionCount = | |
260 | i_PatternTransitionCount + | |
261 | ((i_PatternTransition >> | |
262 | i_Count) & 0x1); | |
263 | ||
c47375f3 | 264 | } /* for (i_Count = 0; i_Count < 8; i_Count++) */ |
c995fe94 ADG |
265 | |
266 | if (i_PatternTransitionCount > 1) { | |
267 | /****************************************/ | |
268 | /* Transition error on an AND logic */ | |
269 | /****************************************/ | |
270 | printk("\n Transition error on an AND logic\n"); | |
271 | return -EINVAL; | |
c47375f3 BP |
272 | } /* if (i_PatternTransitionCount > 1) */ |
273 | } /* if (data[1]== APCI1500_AND) */ | |
c995fe94 ADG |
274 | |
275 | /*****************************************************************/ | |
276 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
277 | /*****************************************************************/ | |
278 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
279 | devpriv->iobase + | |
280 | APCI1500_Z8536_CONTROL_REGISTER); | |
281 | /******************/ | |
282 | /* Disable Port A */ | |
283 | /******************/ | |
284 | outb(0xF0, | |
285 | devpriv->iobase + | |
286 | APCI1500_Z8536_CONTROL_REGISTER); | |
287 | /**********************************************/ | |
288 | /* Selects the polarity register of port 1 */ | |
289 | /**********************************************/ | |
290 | outb(APCI1500_RW_PORT_A_PATTERN_POLARITY, | |
291 | devpriv->iobase + | |
292 | APCI1500_Z8536_CONTROL_REGISTER); | |
293 | outb(i_PatternPolarity, | |
294 | devpriv->iobase + | |
295 | APCI1500_Z8536_CONTROL_REGISTER); | |
296 | ||
297 | /*********************************************/ | |
298 | /* Selects the pattern mask register of */ | |
299 | /* port 1 */ | |
300 | /*********************************************/ | |
301 | outb(APCI1500_RW_PORT_A_PATTERN_MASK, | |
302 | devpriv->iobase + | |
303 | APCI1500_Z8536_CONTROL_REGISTER); | |
304 | outb(i_PatternMask, | |
305 | devpriv->iobase + | |
306 | APCI1500_Z8536_CONTROL_REGISTER); | |
307 | /********************************************/ | |
308 | /* Selects the pattern transition register */ | |
309 | /* of port 1 */ | |
310 | /********************************************/ | |
311 | outb(APCI1500_RW_PORT_A_PATTERN_TRANSITION, | |
312 | devpriv->iobase + | |
313 | APCI1500_Z8536_CONTROL_REGISTER); | |
314 | outb(i_PatternTransition, | |
315 | devpriv->iobase + | |
316 | APCI1500_Z8536_CONTROL_REGISTER); | |
317 | ||
318 | /******************************************/ | |
319 | /* Selects the mode specification mask */ | |
320 | /* register of port 1 */ | |
321 | /******************************************/ | |
322 | outb(APCI1500_RW_PORT_A_SPECIFICATION, | |
323 | devpriv->iobase + | |
324 | APCI1500_Z8536_CONTROL_REGISTER); | |
325 | i_RegValue = | |
326 | inb(devpriv->iobase + | |
327 | APCI1500_Z8536_CONTROL_REGISTER); | |
328 | ||
329 | /******************************************/ | |
330 | /* Selects the mode specification mask */ | |
331 | /* register of port 1 */ | |
332 | /******************************************/ | |
333 | outb(APCI1500_RW_PORT_A_SPECIFICATION, | |
334 | devpriv->iobase + | |
335 | APCI1500_Z8536_CONTROL_REGISTER); | |
336 | ||
337 | /**********************/ | |
338 | /* Port A new mode */ | |
339 | /**********************/ | |
340 | ||
341 | i_RegValue = (i_RegValue & 0xF9) | data[1] | 0x9; | |
342 | outb(i_RegValue, | |
343 | devpriv->iobase + | |
344 | APCI1500_Z8536_CONTROL_REGISTER); | |
345 | ||
346 | i_Event1Status = 1; | |
347 | ||
348 | /*****************************************************************/ | |
349 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
350 | /*****************************************************************/ | |
351 | ||
352 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
353 | devpriv->iobase + | |
354 | APCI1500_Z8536_CONTROL_REGISTER); | |
355 | /*****************/ | |
356 | /* Enable Port A */ | |
357 | /*****************/ | |
358 | outb(0xF4, | |
359 | devpriv->iobase + | |
360 | APCI1500_Z8536_CONTROL_REGISTER); | |
361 | ||
c47375f3 | 362 | } /* if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY) */ |
c995fe94 ADG |
363 | else { |
364 | printk("\nThe choice for interrupt logic does not exist\n"); | |
365 | return -EINVAL; | |
c47375f3 BP |
366 | } /* else }// if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY) */ |
367 | } /* if (data[0]== 1) */ | |
c995fe94 ADG |
368 | |
369 | /************************************/ | |
370 | /* Test if event setting for port 2 */ | |
371 | /************************************/ | |
372 | ||
373 | if (data[0] == 2) { | |
374 | /************************/ | |
375 | /* Test the event logic */ | |
376 | /************************/ | |
377 | ||
378 | if (data[1] == APCI1500_OR) { | |
379 | /*****************************************************************/ | |
380 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
381 | /*****************************************************************/ | |
382 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
383 | devpriv->iobase + | |
384 | APCI1500_Z8536_CONTROL_REGISTER); | |
385 | /******************/ | |
386 | /* Disable Port B */ | |
387 | /******************/ | |
388 | outb(0x74, | |
389 | devpriv->iobase + | |
390 | APCI1500_Z8536_CONTROL_REGISTER); | |
391 | /****************************************/ | |
392 | /* Selects the mode specification mask */ | |
393 | /* register of port B */ | |
394 | /****************************************/ | |
395 | outb(APCI1500_RW_PORT_B_SPECIFICATION, | |
396 | devpriv->iobase + | |
397 | APCI1500_Z8536_CONTROL_REGISTER); | |
398 | i_RegValue = | |
399 | inb(devpriv->iobase + | |
400 | APCI1500_Z8536_CONTROL_REGISTER); | |
401 | ||
402 | /******************************************/ | |
403 | /* Selects the mode specification mask */ | |
404 | /* register of port B */ | |
405 | /******************************************/ | |
406 | outb(APCI1500_RW_PORT_B_SPECIFICATION, | |
407 | devpriv->iobase + | |
408 | APCI1500_Z8536_CONTROL_REGISTER); | |
409 | i_RegValue = i_RegValue & 0xF9; | |
410 | outb(i_RegValue, | |
411 | devpriv->iobase + | |
412 | APCI1500_Z8536_CONTROL_REGISTER); | |
413 | ||
414 | /**********************************/ | |
415 | /* Selects error channels 1 and 2 */ | |
416 | /**********************************/ | |
417 | ||
418 | i_PatternMask = (i_PatternMask | 0xC0); | |
419 | i_PatternPolarity = (i_PatternPolarity | 0xC0); | |
420 | i_PatternTransition = (i_PatternTransition | 0xC0); | |
421 | ||
422 | /**********************************************/ | |
423 | /* Selects the polarity register of port 2 */ | |
424 | /**********************************************/ | |
425 | outb(APCI1500_RW_PORT_B_PATTERN_POLARITY, | |
426 | devpriv->iobase + | |
427 | APCI1500_Z8536_CONTROL_REGISTER); | |
428 | outb(i_PatternPolarity, | |
429 | devpriv->iobase + | |
430 | APCI1500_Z8536_CONTROL_REGISTER); | |
431 | /**********************************************/ | |
432 | /* Selects the pattern transition register */ | |
433 | /* of port 2 */ | |
434 | /**********************************************/ | |
435 | outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION, | |
436 | devpriv->iobase + | |
437 | APCI1500_Z8536_CONTROL_REGISTER); | |
438 | outb(i_PatternTransition, | |
439 | devpriv->iobase + | |
440 | APCI1500_Z8536_CONTROL_REGISTER); | |
441 | /**********************************************/ | |
442 | /* Selects the pattern Mask register */ | |
443 | /* of port 2 */ | |
444 | /**********************************************/ | |
445 | ||
446 | outb(APCI1500_RW_PORT_B_PATTERN_MASK, | |
447 | devpriv->iobase + | |
448 | APCI1500_Z8536_CONTROL_REGISTER); | |
449 | outb(i_PatternMask, | |
450 | devpriv->iobase + | |
451 | APCI1500_Z8536_CONTROL_REGISTER); | |
452 | ||
453 | /******************************************/ | |
454 | /* Selects the mode specification mask */ | |
455 | /* register of port 2 */ | |
456 | /******************************************/ | |
457 | outb(APCI1500_RW_PORT_B_SPECIFICATION, | |
458 | devpriv->iobase + | |
459 | APCI1500_Z8536_CONTROL_REGISTER); | |
460 | i_RegValue = | |
461 | inb(devpriv->iobase + | |
462 | APCI1500_Z8536_CONTROL_REGISTER); | |
463 | /******************************************/ | |
464 | /* Selects the mode specification mask */ | |
465 | /* register of port 2 */ | |
466 | /******************************************/ | |
467 | outb(APCI1500_RW_PORT_B_SPECIFICATION, | |
468 | devpriv->iobase + | |
469 | APCI1500_Z8536_CONTROL_REGISTER); | |
470 | i_RegValue = (i_RegValue & 0xF9) | 4; | |
471 | outb(i_RegValue, | |
472 | devpriv->iobase + | |
473 | APCI1500_Z8536_CONTROL_REGISTER); | |
474 | ||
475 | i_Event2Status = 1; | |
476 | /*****************************************************************/ | |
477 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
478 | /*****************************************************************/ | |
479 | ||
480 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
481 | devpriv->iobase + | |
482 | APCI1500_Z8536_CONTROL_REGISTER); | |
483 | /*****************/ | |
484 | /* Enable Port B */ | |
485 | /*****************/ | |
486 | ||
487 | outb(0xF4, | |
488 | devpriv->iobase + | |
489 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 490 | } /* if (data[1] == APCI1500_OR) */ |
c995fe94 ADG |
491 | else { |
492 | printk("\nThe choice for interrupt logic does not exist\n"); | |
493 | return -EINVAL; | |
c47375f3 BP |
494 | } /* elseif (data[1] == APCI1500_OR) */ |
495 | } /* if(data[0]==2) */ | |
c995fe94 ADG |
496 | |
497 | return insn->n; | |
498 | } | |
499 | ||
500 | /* | |
501 | +----------------------------------------------------------------------------+ | |
502 | | Function Name : int i_APCI1500_StartStopInputEvent | | |
34c43922 | 503 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
90035c08 | 504 | | struct comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
505 | +----------------------------------------------------------------------------+ |
506 | | Task : Allows or disallows a port event | | |
507 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 508 | | Input Parameters : struct comedi_device *dev : Driver handle | |
117102b0 | 509 | | unsigned int ui_Channel : Channel number to read | |
790c5541 | 510 | | unsigned int *data : Data Pointer to read status | |
356cdbcb BP |
511 | | data[0] :0 Start input event |
512 | | 1 Stop input event | |
513 | | data[1] :No of port (1 or 2) | |
c995fe94 ADG |
514 | +----------------------------------------------------------------------------+ |
515 | | Output Parameters : -- | | |
516 | +----------------------------------------------------------------------------+ | |
517 | | Return Value : TRUE : No error occur | | |
518 | | : FALSE : Error occur. Return the error | | |
519 | | | | |
520 | +----------------------------------------------------------------------------+ | |
521 | */ | |
da91b269 BP |
522 | int i_APCI1500_StartStopInputEvent(struct comedi_device *dev, struct comedi_subdevice *s, |
523 | struct comedi_insn *insn, unsigned int *data) | |
c995fe94 ADG |
524 | { |
525 | int i_Event1InterruptStatus = 0, i_Event2InterruptStatus = | |
526 | 0, i_RegValue; | |
527 | switch (data[0]) { | |
528 | case START: | |
529 | /*************************/ | |
530 | /* Tests the port number */ | |
531 | /*************************/ | |
532 | ||
533 | if (data[1] == 1 || data[1] == 2) { | |
534 | /***************************/ | |
535 | /* Test if port 1 selected */ | |
536 | /***************************/ | |
537 | ||
538 | if (data[1] == 1) { | |
539 | /*****************************/ | |
540 | /* Test if event initialised */ | |
541 | /*****************************/ | |
542 | if (i_Event1Status == 1) { | |
543 | /*****************************************************************/ | |
544 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
545 | /*****************************************************************/ | |
546 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
547 | /******************/ | |
548 | /* Disable Port A */ | |
549 | /******************/ | |
550 | outb(0xF0, | |
551 | devpriv->iobase + | |
552 | APCI1500_Z8536_CONTROL_REGISTER); | |
553 | /***************************************************/ | |
554 | /* Selects the command and status register of */ | |
555 | /* port 1 */ | |
556 | /***************************************************/ | |
557 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
558 | /*************************************/ | |
559 | /* Allows the pattern interrupt */ | |
560 | /*************************************/ | |
561 | outb(0xC0, | |
562 | devpriv->iobase + | |
563 | APCI1500_Z8536_CONTROL_REGISTER); | |
564 | /*****************************************************************/ | |
565 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
566 | /*****************************************************************/ | |
567 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
568 | /*****************/ | |
569 | /* Enable Port A */ | |
570 | /*****************/ | |
571 | outb(0xF4, | |
572 | devpriv->iobase + | |
573 | APCI1500_Z8536_CONTROL_REGISTER); | |
574 | i_Event1InterruptStatus = 1; | |
575 | outb(APCI1500_RW_PORT_A_SPECIFICATION, | |
576 | devpriv->iobase + | |
577 | APCI1500_Z8536_CONTROL_REGISTER); | |
578 | i_RegValue = | |
579 | inb(devpriv->iobase + | |
580 | APCI1500_Z8536_CONTROL_REGISTER); | |
581 | ||
582 | /* Selects the master interrupt control register */ | |
583 | /*************************************************/ | |
584 | outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
585 | /**********************************************/ | |
586 | /* Authorizes the main interrupt on the board */ | |
587 | /**********************************************/ | |
588 | outb(0xD0, | |
589 | devpriv->iobase + | |
590 | APCI1500_Z8536_CONTROL_REGISTER); | |
591 | ||
c47375f3 | 592 | } /* if(i_Event1Status==1) */ |
c995fe94 ADG |
593 | else { |
594 | printk("\nEvent 1 not initialised\n"); | |
595 | return -EINVAL; | |
c47375f3 BP |
596 | } /* else if(i_Event1Status==1) */ |
597 | } /* if (data[1]==1) */ | |
c995fe94 ADG |
598 | if (data[1] == 2) { |
599 | ||
600 | if (i_Event2Status == 1) { | |
601 | /*****************************************************************/ | |
602 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
603 | /*****************************************************************/ | |
604 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
605 | /******************/ | |
606 | /* Disable Port B */ | |
607 | /******************/ | |
608 | outb(0x74, | |
609 | devpriv->iobase + | |
610 | APCI1500_Z8536_CONTROL_REGISTER); | |
611 | /***************************************************/ | |
612 | /* Selects the command and status register of */ | |
613 | /* port 2 */ | |
614 | /***************************************************/ | |
615 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
616 | /*************************************/ | |
617 | /* Allows the pattern interrupt */ | |
618 | /*************************************/ | |
619 | outb(0xC0, | |
620 | devpriv->iobase + | |
621 | APCI1500_Z8536_CONTROL_REGISTER); | |
622 | /*****************************************************************/ | |
623 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
624 | /*****************************************************************/ | |
625 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
626 | /*****************/ | |
627 | /* Enable Port B */ | |
628 | /*****************/ | |
629 | outb(0xF4, | |
630 | devpriv->iobase + | |
631 | APCI1500_Z8536_CONTROL_REGISTER); | |
632 | ||
633 | /* Selects the master interrupt control register */ | |
634 | /*************************************************/ | |
635 | outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
636 | /**********************************************/ | |
637 | /* Authorizes the main interrupt on the board */ | |
638 | /**********************************************/ | |
639 | outb(0xD0, | |
640 | devpriv->iobase + | |
641 | APCI1500_Z8536_CONTROL_REGISTER); | |
642 | i_Event2InterruptStatus = 1; | |
c47375f3 | 643 | } /* if(i_Event2Status==1) */ |
c995fe94 ADG |
644 | else { |
645 | printk("\nEvent 2 not initialised\n"); | |
646 | return -EINVAL; | |
c47375f3 BP |
647 | } /* else if(i_Event2Status==1) */ |
648 | } /* if(data[1]==2) */ | |
649 | } /* if (data[1] == 1 || data[0] == 2) */ | |
c995fe94 ADG |
650 | else { |
651 | printk("\nThe port parameter is in error\n"); | |
652 | return -EINVAL; | |
c47375f3 | 653 | } /* else if (data[1] == 1 || data[0] == 2) */ |
c995fe94 ADG |
654 | |
655 | break; | |
656 | ||
657 | case STOP: | |
658 | /*************************/ | |
659 | /* Tests the port number */ | |
660 | /*************************/ | |
661 | ||
662 | if (data[1] == 1 || data[1] == 2) { | |
663 | /***************************/ | |
664 | /* Test if port 1 selected */ | |
665 | /***************************/ | |
666 | ||
667 | if (data[1] == 1) { | |
668 | /*****************************/ | |
669 | /* Test if event initialised */ | |
670 | /*****************************/ | |
671 | if (i_Event1Status == 1) { | |
672 | /*****************************************************************/ | |
673 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
674 | /*****************************************************************/ | |
675 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
676 | /******************/ | |
677 | /* Disable Port A */ | |
678 | /******************/ | |
679 | outb(0xF0, | |
680 | devpriv->iobase + | |
681 | APCI1500_Z8536_CONTROL_REGISTER); | |
682 | /***************************************************/ | |
683 | /* Selects the command and status register of */ | |
684 | /* port 1 */ | |
685 | /***************************************************/ | |
686 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
687 | /*************************************/ | |
688 | /* Inhibits the pattern interrupt */ | |
689 | /*************************************/ | |
690 | outb(0xE0, | |
691 | devpriv->iobase + | |
692 | APCI1500_Z8536_CONTROL_REGISTER); | |
693 | /*****************************************************************/ | |
694 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
695 | /*****************************************************************/ | |
696 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
697 | /*****************/ | |
698 | /* Enable Port A */ | |
699 | /*****************/ | |
700 | outb(0xF4, | |
701 | devpriv->iobase + | |
702 | APCI1500_Z8536_CONTROL_REGISTER); | |
703 | i_Event1InterruptStatus = 0; | |
c47375f3 | 704 | } /* if(i_Event1Status==1) */ |
c995fe94 ADG |
705 | else { |
706 | printk("\nEvent 1 not initialised\n"); | |
707 | return -EINVAL; | |
c47375f3 BP |
708 | } /* else if(i_Event1Status==1) */ |
709 | } /* if (data[1]==1) */ | |
c995fe94 ADG |
710 | if (data[1] == 2) { |
711 | /*****************************/ | |
712 | /* Test if event initialised */ | |
713 | /*****************************/ | |
714 | if (i_Event2Status == 1) { | |
715 | /*****************************************************************/ | |
716 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
717 | /*****************************************************************/ | |
718 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
719 | /******************/ | |
720 | /* Disable Port B */ | |
721 | /******************/ | |
722 | outb(0x74, | |
723 | devpriv->iobase + | |
724 | APCI1500_Z8536_CONTROL_REGISTER); | |
725 | /***************************************************/ | |
726 | /* Selects the command and status register of */ | |
727 | /* port 2 */ | |
728 | /***************************************************/ | |
729 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
730 | /*************************************/ | |
731 | /* Inhibits the pattern interrupt */ | |
732 | /*************************************/ | |
733 | outb(0xE0, | |
734 | devpriv->iobase + | |
735 | APCI1500_Z8536_CONTROL_REGISTER); | |
736 | /*****************************************************************/ | |
737 | /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */ | |
738 | /*****************************************************************/ | |
739 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
740 | /*****************/ | |
741 | /* Enable Port B */ | |
742 | /*****************/ | |
743 | outb(0xF4, | |
744 | devpriv->iobase + | |
745 | APCI1500_Z8536_CONTROL_REGISTER); | |
746 | i_Event2InterruptStatus = 0; | |
c47375f3 | 747 | } /* if(i_Event2Status==1) */ |
c995fe94 ADG |
748 | else { |
749 | printk("\nEvent 2 not initialised\n"); | |
750 | return -EINVAL; | |
c47375f3 BP |
751 | } /* else if(i_Event2Status==1) */ |
752 | } /* if(data[1]==2) */ | |
c995fe94 | 753 | |
c47375f3 | 754 | } /* if (data[1] == 1 || data[1] == 2) */ |
c995fe94 ADG |
755 | else { |
756 | printk("\nThe port parameter is in error\n"); | |
757 | return -EINVAL; | |
c47375f3 | 758 | } /* else if (data[1] == 1 || data[1] == 2) */ |
c995fe94 ADG |
759 | break; |
760 | default: | |
761 | printk("\nThe option of START/STOP logic does not exist\n"); | |
762 | return -EINVAL; | |
c47375f3 | 763 | } /* switch(data[0]) */ |
c995fe94 ADG |
764 | |
765 | return insn->n; | |
766 | } | |
767 | ||
768 | /* | |
769 | +----------------------------------------------------------------------------+ | |
770 | | Function Name : int i_APCI1500_Initialisation | | |
34c43922 | 771 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
90035c08 | 772 | | struct comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
773 | +----------------------------------------------------------------------------+ |
774 | | Task : Return the status of the digital input | | |
775 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 776 | | Input Parameters : struct comedi_device *dev : Driver handle | |
117102b0 | 777 | | unsigned int ui_Channel : Channel number to read | |
790c5541 | 778 | | unsigned int *data : Data Pointer to read status | |
c995fe94 ADG |
779 | +----------------------------------------------------------------------------+ |
780 | | Output Parameters : -- | | |
781 | +----------------------------------------------------------------------------+ | |
782 | | Return Value : TRUE : No error occur | | |
783 | | : FALSE : Error occur. Return the error | | |
784 | | | | |
785 | +----------------------------------------------------------------------------+ | |
786 | */ | |
da91b269 BP |
787 | int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice *s, |
788 | struct comedi_insn *insn, unsigned int *data) | |
c995fe94 ADG |
789 | { |
790 | int i_DummyRead = 0; | |
791 | /******************/ | |
792 | /* Software reset */ | |
793 | /******************/ | |
794 | i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
795 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
796 | i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
797 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
798 | outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
799 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
800 | ||
801 | /*****************************************************/ | |
802 | /* Selects the master configuration control register */ | |
803 | /*****************************************************/ | |
804 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
805 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
806 | outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
807 | ||
808 | /*****************************************************/ | |
809 | /* Selects the mode specification register of port A */ | |
810 | /*****************************************************/ | |
811 | outb(APCI1500_RW_PORT_A_SPECIFICATION, | |
812 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
813 | outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
814 | ||
815 | /* Selects the data path polarity register of port A */ | |
816 | outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY, | |
817 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
818 | /* High level of port A means 1 */ | |
819 | outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
820 | ||
821 | /* Selects the data direction register of port A */ | |
822 | outb(APCI1500_RW_PORT_A_DATA_DIRECTION, | |
823 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
824 | /* All bits used as inputs */ | |
825 | outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
826 | /* Selects the command and status register of port A */ | |
827 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, | |
828 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
829 | /* Deletes IP and IUS */ | |
830 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
831 | /* Selects the command and status register of port A */ | |
832 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, | |
833 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
834 | /* Deactivates the interrupt management of port A: */ | |
835 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
836 | /* Selects the handshake specification register of port A */ | |
837 | outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION, | |
838 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
839 | /* Deletes the register */ | |
840 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
841 | ||
842 | /*****************************************************/ | |
843 | /* Selects the mode specification register of port B */ | |
844 | /*****************************************************/ | |
845 | outb(APCI1500_RW_PORT_B_SPECIFICATION, | |
846 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
847 | outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
848 | /* Selects the data path polarity register of port B */ | |
849 | outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY, | |
850 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
851 | /* A high level of port B means 1 */ | |
852 | outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
853 | /* Selects the data direction register of port B */ | |
854 | outb(APCI1500_RW_PORT_B_DATA_DIRECTION, | |
855 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
856 | /* All bits used as inputs */ | |
857 | outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
858 | /* Selects the command and status register of port B */ | |
859 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
860 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
861 | /* Deletes IP and IUS */ | |
862 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
863 | /* Selects the command and status register of port B */ | |
864 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
865 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
866 | /* Deactivates the interrupt management of port B: */ | |
867 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
868 | /* Selects the handshake specification register of port B */ | |
869 | outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION, | |
870 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
871 | /* Deletes the register */ | |
872 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
873 | ||
874 | /*****************************************************/ | |
875 | /* Selects the data path polarity register of port C */ | |
876 | /*****************************************************/ | |
877 | outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY, | |
878 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
879 | /* High level of port C means 1 */ | |
880 | outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
881 | /* Selects the data direction register of port C */ | |
882 | outb(APCI1500_RW_PORT_C_DATA_DIRECTION, | |
883 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
884 | /* All bits used as inputs except channel 1 */ | |
885 | outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
886 | /* Selects the special IO register of port C */ | |
887 | outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL, | |
888 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
889 | /* Deletes it */ | |
890 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
891 | /******************************************************/ | |
892 | /* Selects the command and status register of timer 1 */ | |
893 | /******************************************************/ | |
894 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
895 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
896 | /* Deletes IP and IUS */ | |
897 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
898 | /* Selects the command and status register of timer 1 */ | |
899 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
900 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
901 | /* Deactivates the interrupt management of timer 1 */ | |
902 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
903 | /******************************************************/ | |
904 | /* Selects the command and status register of timer 2 */ | |
905 | /******************************************************/ | |
906 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
907 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
908 | /* Deletes IP and IUS */ | |
909 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
910 | /* Selects the command and status register of timer 2 */ | |
911 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
912 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
913 | /* Deactivates Timer 2 interrupt management: */ | |
914 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
915 | /******************************************************/ | |
916 | /* Selects the command and status register of timer 3 */ | |
917 | /******************************************************/ | |
918 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
919 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
920 | /* Deletes IP and IUS */ | |
921 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
922 | /* Selects the command and status register of Timer 3 */ | |
923 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
924 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
925 | /* Deactivates interrupt management of timer 3: */ | |
926 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
927 | /*************************************************/ | |
928 | /* Selects the master interrupt control register */ | |
929 | /*************************************************/ | |
930 | outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, | |
931 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
932 | /* Deletes all interrupts */ | |
933 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
934 | return insn->n; | |
935 | } | |
936 | ||
937 | /* | |
938 | +----------------------------------------------------------------------------+ | |
939 | | Function Name : int i_APCI1500_ReadMoreDigitalInput | | |
34c43922 | 940 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
90035c08 | 941 | | struct comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
942 | +----------------------------------------------------------------------------+ |
943 | | Task : Return the status of the Requested digital inputs | | |
944 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 945 | | Input Parameters : struct comedi_device *dev : Driver handle | |
117102b0 BP |
946 | | unsigned int ui_NoOfChannels : No Of Channels To be Read | |
947 | | unsigned int *data : Data Pointer | |
356cdbcb BP |
948 | | data[0] : 0 Read a single channel |
949 | | 1 read a port value | |
950 | | data[1] : port value | |
c995fe94 ADG |
951 | +----------------------------------------------------------------------------+ |
952 | | Output Parameters : -- data[0] :The read status value | |
953 | +----------------------------------------------------------------------------+ | |
954 | | Return Value : TRUE : No error occur | | |
955 | | : FALSE : Error occur. Return the error | | |
956 | | | | |
957 | +----------------------------------------------------------------------------+ | |
958 | */ | |
959 | ||
da91b269 BP |
960 | int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s, |
961 | struct comedi_insn *insn, unsigned int *data) | |
c995fe94 | 962 | { |
117102b0 BP |
963 | unsigned int ui_PortValue = data[1]; |
964 | unsigned int ui_Mask = 0; | |
965 | unsigned int ui_Channel; | |
966 | unsigned int ui_TmpValue = 0; | |
c995fe94 ADG |
967 | ui_Channel = CR_CHAN(insn->chanspec); |
968 | ||
969 | switch (data[0]) { | |
970 | case 0: | |
dc8af068 | 971 | if (ui_Channel <= 15) { |
c995fe94 | 972 | ui_TmpValue = |
117102b0 | 973 | (unsigned int) inw(devpriv->i_IobaseAddon + |
c995fe94 ADG |
974 | APCI1500_DIGITAL_IP); |
975 | *data = (ui_TmpValue >> ui_Channel) & 0x1; | |
c47375f3 | 976 | } /* if(ui_Channel >= 0 && ui_Channel <=15) */ |
c995fe94 ADG |
977 | else { |
978 | printk("\nThe channel specification are in error\n"); | |
c47375f3 BP |
979 | return -EINVAL; /* "sorry channel spec wrong " */ |
980 | } /* else if(ui_Channel >= 0 && ui_Channel <=15) */ | |
c995fe94 ADG |
981 | break; |
982 | case 1: | |
983 | ||
117102b0 | 984 | *data = (unsigned int) inw(devpriv->i_IobaseAddon + |
c995fe94 ADG |
985 | APCI1500_DIGITAL_IP); |
986 | switch (ui_Channel) { | |
987 | case 2: | |
988 | ui_Mask = 3; | |
989 | *data = (*data >> (2 * ui_PortValue)) & ui_Mask; | |
990 | break; | |
991 | case 4: | |
992 | ui_Mask = 15; | |
993 | *data = (*data >> (4 * ui_PortValue)) & ui_Mask; | |
994 | break; | |
995 | case 8: | |
996 | ui_Mask = 255; | |
997 | *data = (*data >> (8 * ui_PortValue)) & ui_Mask; | |
998 | break; | |
999 | case 15: | |
1000 | break; | |
1001 | ||
1002 | default: | |
1003 | printk("\nSpecified channel cannot be read \n"); | |
c47375f3 | 1004 | return -EINVAL; /* "sorry channel spec wrong " */ |
c995fe94 | 1005 | break; |
c47375f3 | 1006 | } /* switch(ui_Channel) */ |
c995fe94 ADG |
1007 | break; |
1008 | default: | |
1009 | printk("\nThe specified functionality does not exist\n"); | |
1010 | return -EINVAL; | |
c47375f3 | 1011 | } /* switch(data[0]) */ |
c995fe94 ADG |
1012 | return insn->n; |
1013 | } | |
1014 | ||
1015 | /* | |
1016 | +----------------------------------------------------------------------------+ | |
1017 | | Function Name : int i_APCI1500_ConfigDigitalOutputErrorInterrupt | |
356cdbcb BP |
1018 | | (struct comedi_device *dev,struct comedi_subdevice *s struct comedi_insn |
1019 | | *insn,unsigned int *data) | | |
c995fe94 ADG |
1020 | | | |
1021 | +----------------------------------------------------------------------------+ | |
1022 | | Task : Configures the digital output memory and the digital | |
356cdbcb | 1023 | | output error interrupt | |
c995fe94 | 1024 | +----------------------------------------------------------------------------+ |
71b5f4f1 | 1025 | | Input Parameters : struct comedi_device *dev : Driver handle | |
790c5541 | 1026 | | unsigned int *data : Data Pointer contains | |
c995fe94 | 1027 | | configuration parameters as below | |
34c43922 | 1028 | | struct comedi_subdevice *s, :pointer to subdevice structure |
356cdbcb | 1029 | | struct comedi_insn *insn :pointer to insn structure | |
c995fe94 ADG |
1030 | | data[0] :1:Memory on | |
1031 | | 0:Memory off | | |
356cdbcb | 1032 | | data[1] :1 Enable the voltage error interrupt |
c995fe94 ADG |
1033 | | :0 Disable the voltage error interrupt | |
1034 | | | | |
1035 | +----------------------------------------------------------------------------+ | |
1036 | | Output Parameters : -- | | |
1037 | +----------------------------------------------------------------------------+ | |
1038 | | Return Value : TRUE : No error occur | | |
1039 | | : FALSE : Error occur. Return the error | | |
1040 | | | | |
1041 | +----------------------------------------------------------------------------+ | |
1042 | */ | |
da91b269 BP |
1043 | int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev, |
1044 | struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) | |
c995fe94 ADG |
1045 | { |
1046 | devpriv->b_OutputMemoryStatus = data[0]; | |
1047 | return insn->n; | |
1048 | } | |
1049 | ||
1050 | /* | |
1051 | +----------------------------------------------------------------------------+ | |
1052 | | Function Name : int i_APCI1500_WriteDigitalOutput | | |
34c43922 | 1053 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
90035c08 | 1054 | | struct comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
1055 | +----------------------------------------------------------------------------+ |
1056 | | Task : Writes port value To the selected port | | |
1057 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 1058 | | Input Parameters : struct comedi_device *dev : Driver handle | |
117102b0 BP |
1059 | | unsigned int ui_NoOfChannels : No Of Channels To Write | |
1060 | | unsigned int *data : Data Pointer to read status | | |
c995fe94 ADG |
1061 | +----------------------------------------------------------------------------+ |
1062 | | Output Parameters : -- | | |
1063 | +----------------------------------------------------------------------------+ | |
1064 | | Return Value : TRUE : No error occur | | |
1065 | | : FALSE : Error occur. Return the error | | |
1066 | | | | |
1067 | +----------------------------------------------------------------------------+ | |
1068 | */ | |
1069 | ||
da91b269 BP |
1070 | int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s, |
1071 | struct comedi_insn *insn, unsigned int *data) | |
c995fe94 | 1072 | { |
117102b0 BP |
1073 | static unsigned int ui_Temp = 0; |
1074 | unsigned int ui_Temp1; | |
c995fe94 | 1075 | |
c47375f3 | 1076 | unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */ |
c995fe94 ADG |
1077 | |
1078 | if (!devpriv->b_OutputMemoryStatus) { | |
1079 | ui_Temp = 0; | |
1080 | ||
c47375f3 | 1081 | } /* if(!devpriv->b_OutputMemoryStatus ) */ |
c995fe94 ADG |
1082 | if (data[3] == 0) { |
1083 | if (data[1] == 0) { | |
1084 | data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; | |
1085 | outw(data[0], | |
1086 | devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP); | |
c47375f3 | 1087 | } /* if(data[1]==0) */ |
c995fe94 ADG |
1088 | else { |
1089 | if (data[1] == 1) { | |
1090 | switch (ui_NoOfChannel) { | |
1091 | ||
1092 | case 2: | |
1093 | data[0] = | |
1094 | (data[0] << (2 * | |
1095 | data[2])) | ui_Temp; | |
1096 | break; | |
1097 | ||
1098 | case 4: | |
1099 | data[0] = | |
1100 | (data[0] << (4 * | |
1101 | data[2])) | ui_Temp; | |
1102 | break; | |
1103 | ||
1104 | case 8: | |
1105 | data[0] = | |
1106 | (data[0] << (8 * | |
1107 | data[2])) | ui_Temp; | |
1108 | break; | |
1109 | ||
1110 | case 15: | |
1111 | data[0] = data[0] | ui_Temp; | |
1112 | break; | |
1113 | ||
1114 | default: | |
1115 | comedi_error(dev, " chan spec wrong"); | |
c47375f3 | 1116 | return -EINVAL; /* "sorry channel spec wrong " */ |
c995fe94 | 1117 | |
c47375f3 | 1118 | } /* switch(ui_NoOfChannels) */ |
c995fe94 ADG |
1119 | |
1120 | outw(data[0], | |
1121 | devpriv->i_IobaseAddon + | |
1122 | APCI1500_DIGITAL_OP); | |
c47375f3 | 1123 | } /* if(data[1]==1) */ |
c995fe94 ADG |
1124 | else { |
1125 | printk("\nSpecified channel not supported\n"); | |
c47375f3 BP |
1126 | } /* else if(data[1]==1) */ |
1127 | } /* elseif(data[1]==0) */ | |
1128 | } /* if(data[3]==0) */ | |
c995fe94 ADG |
1129 | else { |
1130 | if (data[3] == 1) { | |
1131 | if (data[1] == 0) { | |
1132 | data[0] = ~data[0] & 0x1; | |
1133 | ui_Temp1 = 1; | |
1134 | ui_Temp1 = ui_Temp1 << ui_NoOfChannel; | |
1135 | ui_Temp = ui_Temp | ui_Temp1; | |
1136 | data[0] = | |
1137 | (data[0] << ui_NoOfChannel) ^ | |
1138 | 0xffffffff; | |
1139 | data[0] = data[0] & ui_Temp; | |
1140 | outw(data[0], | |
1141 | devpriv->i_IobaseAddon + | |
1142 | APCI1500_DIGITAL_OP); | |
c47375f3 | 1143 | } /* if(data[1]==0) */ |
c995fe94 ADG |
1144 | else { |
1145 | if (data[1] == 1) { | |
1146 | switch (ui_NoOfChannel) { | |
1147 | ||
1148 | case 2: | |
1149 | data[0] = ~data[0] & 0x3; | |
1150 | ui_Temp1 = 3; | |
1151 | ui_Temp1 = | |
1152 | ui_Temp1 << 2 * data[2]; | |
1153 | ui_Temp = ui_Temp | ui_Temp1; | |
1154 | data[0] = | |
1155 | ((data[0] << (2 * | |
1156 | data | |
1157 | [2])) ^ | |
1158 | 0xffffffff) & ui_Temp; | |
1159 | break; | |
1160 | ||
1161 | case 4: | |
1162 | data[0] = ~data[0] & 0xf; | |
1163 | ui_Temp1 = 15; | |
1164 | ui_Temp1 = | |
1165 | ui_Temp1 << 4 * data[2]; | |
1166 | ui_Temp = ui_Temp | ui_Temp1; | |
1167 | data[0] = | |
1168 | ((data[0] << (4 * | |
1169 | data | |
1170 | [2])) ^ | |
1171 | 0xffffffff) & ui_Temp; | |
1172 | break; | |
1173 | ||
1174 | case 8: | |
1175 | data[0] = ~data[0] & 0xff; | |
1176 | ui_Temp1 = 255; | |
1177 | ui_Temp1 = | |
1178 | ui_Temp1 << 8 * data[2]; | |
1179 | ui_Temp = ui_Temp | ui_Temp1; | |
1180 | data[0] = | |
1181 | ((data[0] << (8 * | |
1182 | data | |
1183 | [2])) ^ | |
1184 | 0xffffffff) & ui_Temp; | |
1185 | break; | |
1186 | ||
1187 | case 15: | |
1188 | break; | |
1189 | ||
1190 | default: | |
1191 | comedi_error(dev, | |
1192 | " chan spec wrong"); | |
c47375f3 | 1193 | return -EINVAL; /* "sorry channel spec wrong " */ |
c995fe94 | 1194 | |
c47375f3 | 1195 | } /* switch(ui_NoOfChannels) */ |
c995fe94 ADG |
1196 | |
1197 | outw(data[0], | |
1198 | devpriv->i_IobaseAddon + | |
1199 | APCI1500_DIGITAL_OP); | |
c47375f3 | 1200 | } /* if(data[1]==1) */ |
c995fe94 ADG |
1201 | else { |
1202 | printk("\nSpecified channel not supported\n"); | |
c47375f3 BP |
1203 | } /* else if(data[1]==1) */ |
1204 | } /* elseif(data[1]==0) */ | |
1205 | } /* if(data[3]==1); */ | |
c995fe94 ADG |
1206 | else { |
1207 | printk("\nSpecified functionality does not exist\n"); | |
1208 | return -EINVAL; | |
c47375f3 BP |
1209 | } /* if else data[3]==1) */ |
1210 | } /* if else data[3]==0) */ | |
c995fe94 | 1211 | ui_Temp = data[0]; |
dae0dc30 | 1212 | return insn->n; |
c995fe94 ADG |
1213 | } |
1214 | ||
1215 | /* | |
1216 | +----------------------------------------------------------------------------+ | |
1217 | | Function Name : int i_APCI1500_ConfigCounterTimerWatchdog(comedi_device | |
356cdbcb | 1218 | | *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)| |
c995fe94 ADG |
1219 | | | |
1220 | +----------------------------------------------------------------------------+ | |
1221 | | Task : Configures The Watchdog | | |
1222 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 1223 | | Input Parameters : struct comedi_device *dev : Driver handle | |
34c43922 | 1224 | | struct comedi_subdevice *s, :pointer to subdevice structure |
356cdbcb | 1225 | | struct comedi_insn *insn :pointer to insn structure | |
790c5541 | 1226 | | unsigned int *data : Data Pointer to read status data[0] : 2 APCI1500_1_8_KHZ |
c995fe94 ADG |
1227 | | 1 APCI1500_3_6_KHZ | |
1228 | | 0 APCI1500_115_KHZ | |
356cdbcb BP |
1229 | | data[1] : 0 Counter1/Timer1 |
1230 | | 1 Counter2/Timer2 | |
1231 | | 2 Counter3/Watchdog | |
1232 | | data[2] : 0 Counter | |
1233 | | 1 Timer/Watchdog | |
1234 | | data[3] : This parameter has | | |
c995fe94 ADG |
1235 | | two meanings. | |
1236 | | - If the counter/timer | | |
1237 | | is used as a counter | | |
1238 | | the limit value of | | |
1239 | | the counter is given | | |
1240 | | | | |
1241 | | - If the counter/timer | | |
1242 | | is used as a timer, | | |
1243 | | the divider factor | | |
1244 | | for the output is | | |
1245 | | given. | |
356cdbcb BP |
1246 | | data[4] : 0 APCI1500_CONTINUOUS |
1247 | | 1 APCI1500_SINGLE | |
1248 | | data[5] : 0 Software Trigger | |
1249 | | 1 Hardware Trigger | |
1250 | | | |
1251 | | data[6] :0 Software gate | |
1252 | | 1 Hardware gate | |
1253 | | data[7] :0 Interrupt Disable | |
1254 | | 1 Interrupt Enable | |
c995fe94 ADG |
1255 | +----------------------------------------------------------------------------+ |
1256 | | Output Parameters : -- | | |
1257 | +----------------------------------------------------------------------------+ | |
1258 | | Return Value : TRUE : No error occur | | |
1259 | | : FALSE : Error occur. Return the error | | |
1260 | | | | |
1261 | +----------------------------------------------------------------------------+ | |
1262 | */ | |
1263 | ||
da91b269 BP |
1264 | int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev, |
1265 | struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) | |
c995fe94 ADG |
1266 | { |
1267 | int i_TimerCounterMode, i_MasterConfiguration; | |
1268 | ||
1269 | devpriv->tsk_Current = current; | |
1270 | ||
c47375f3 | 1271 | /* Selection of the input clock */ |
c995fe94 ADG |
1272 | if (data[0] == 0 || data[0] == 1 || data[0] == 2) { |
1273 | outw(data[0], devpriv->i_IobaseAddon + APCI1500_CLK_SELECT); | |
c47375f3 | 1274 | } /* if(data[0]==0||data[0]==1||data[0]==2) */ |
c995fe94 ADG |
1275 | else { |
1276 | if (data[0] != 3) { | |
1277 | printk("\nThe option for input clock selection does not exist\n"); | |
1278 | return -EINVAL; | |
c47375f3 BP |
1279 | } /* if(data[0]!=3) */ |
1280 | } /* elseif(data[0]==0||data[0]==1||data[0]==2) */ | |
1281 | /* Select the counter/timer */ | |
c995fe94 ADG |
1282 | switch (data[1]) { |
1283 | case COUNTER1: | |
c47375f3 | 1284 | /* selecting counter or timer */ |
c995fe94 ADG |
1285 | switch (data[2]) { |
1286 | case 0: | |
1287 | data[2] = APCI1500_COUNTER; | |
1288 | break; | |
1289 | case 1: | |
1290 | data[2] = APCI1500_TIMER; | |
1291 | break; | |
1292 | default: | |
1293 | printk("\nThis choice is not a timer nor a counter\n"); | |
1294 | return -EINVAL; | |
c47375f3 | 1295 | } /* switch(data[2]) */ |
c995fe94 | 1296 | |
c47375f3 | 1297 | /* Selecting single or continuous mode */ |
c995fe94 ADG |
1298 | switch (data[4]) { |
1299 | case 0: | |
1300 | data[4] = APCI1500_CONTINUOUS; | |
1301 | break; | |
1302 | case 1: | |
1303 | data[4] = APCI1500_SINGLE; | |
1304 | break; | |
1305 | default: | |
1306 | printk("\nThis option for single/continuous mode does not exist\n"); | |
1307 | return -EINVAL; | |
c47375f3 | 1308 | } /* switch(data[4]) */ |
c995fe94 ADG |
1309 | |
1310 | i_TimerCounterMode = data[2] | data[4] | 7; | |
1311 | /*************************/ | |
1312 | /* Test the reload value */ | |
1313 | /*************************/ | |
1314 | ||
1315 | if ((data[3] >= 0) && (data[3] <= 65535)) { | |
1316 | if (data[7] == APCI1500_ENABLE | |
1317 | || data[7] == APCI1500_DISABLE) { | |
1318 | ||
1319 | /************************************************/ | |
1320 | /* Selects the mode register of timer/counter 1 */ | |
1321 | /************************************************/ | |
1322 | outb(APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION, | |
1323 | devpriv->iobase + | |
1324 | APCI1500_Z8536_CONTROL_REGISTER); | |
1325 | /***********************/ | |
1326 | /* Writes the new mode */ | |
1327 | /***********************/ | |
1328 | outb(i_TimerCounterMode, | |
1329 | devpriv->iobase + | |
1330 | APCI1500_Z8536_CONTROL_REGISTER); | |
1331 | ||
1332 | /****************************************************/ | |
1333 | /* Selects the constant register of timer/counter 1 */ | |
1334 | /****************************************************/ | |
1335 | ||
1336 | outb(APCI1500_RW_CPT_TMR1_TIME_CST_LOW, | |
1337 | devpriv->iobase + | |
1338 | APCI1500_Z8536_CONTROL_REGISTER); | |
1339 | ||
1340 | /*************************/ | |
1341 | /* Writes the low value */ | |
1342 | /*************************/ | |
1343 | ||
1344 | outb(data[3], | |
1345 | devpriv->iobase + | |
1346 | APCI1500_Z8536_CONTROL_REGISTER); | |
1347 | ||
1348 | /****************************************************/ | |
1349 | /* Selects the constant register of timer/counter 1 */ | |
1350 | /****************************************************/ | |
1351 | ||
1352 | outb(APCI1500_RW_CPT_TMR1_TIME_CST_HIGH, | |
1353 | devpriv->iobase + | |
1354 | APCI1500_Z8536_CONTROL_REGISTER); | |
1355 | ||
1356 | /**************************/ | |
1357 | /* Writes the high value */ | |
1358 | /**************************/ | |
1359 | ||
1360 | data[3] = data[3] >> 8; | |
1361 | outb(data[3], | |
1362 | devpriv->iobase + | |
1363 | APCI1500_Z8536_CONTROL_REGISTER); | |
1364 | ||
1365 | /*********************************************/ | |
1366 | /* Selects the master configuration register */ | |
1367 | /*********************************************/ | |
1368 | ||
1369 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
1370 | devpriv->iobase + | |
1371 | APCI1500_Z8536_CONTROL_REGISTER); | |
1372 | ||
1373 | /**********************/ | |
1374 | /* Reads the register */ | |
1375 | /**********************/ | |
1376 | ||
1377 | i_MasterConfiguration = | |
1378 | inb(devpriv->iobase + | |
1379 | APCI1500_Z8536_CONTROL_REGISTER); | |
1380 | ||
1381 | /********************************************************/ | |
1382 | /* Enables timer/counter 1 and triggers timer/counter 1 */ | |
1383 | /********************************************************/ | |
1384 | ||
1385 | i_MasterConfiguration = | |
1386 | i_MasterConfiguration | 0x40; | |
1387 | ||
1388 | /*********************************************/ | |
1389 | /* Selects the master configuration register */ | |
1390 | /*********************************************/ | |
1391 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
1392 | devpriv->iobase + | |
1393 | APCI1500_Z8536_CONTROL_REGISTER); | |
1394 | ||
1395 | /********************************/ | |
1396 | /* Writes the new configuration */ | |
1397 | /********************************/ | |
1398 | outb(i_MasterConfiguration, | |
1399 | devpriv->iobase + | |
1400 | APCI1500_Z8536_CONTROL_REGISTER); | |
1401 | /****************************************/ | |
1402 | /* Selects the commands register of */ | |
1403 | /* timer/counter 1 */ | |
1404 | /****************************************/ | |
1405 | ||
1406 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
1407 | devpriv->iobase + | |
1408 | APCI1500_Z8536_CONTROL_REGISTER); | |
1409 | ||
1410 | /***************************/ | |
1411 | /* Disable timer/counter 1 */ | |
1412 | /***************************/ | |
1413 | ||
1414 | outb(0x0, | |
1415 | devpriv->iobase + | |
1416 | APCI1500_Z8536_CONTROL_REGISTER); | |
1417 | /****************************************/ | |
1418 | /* Selects the commands register of */ | |
1419 | /* timer/counter 1 */ | |
1420 | /****************************************/ | |
1421 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
1422 | devpriv->iobase + | |
1423 | APCI1500_Z8536_CONTROL_REGISTER); | |
1424 | ||
1425 | /***************************/ | |
1426 | /* Trigger timer/counter 1 */ | |
1427 | /***************************/ | |
1428 | outb(0x2, | |
1429 | devpriv->iobase + | |
1430 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 1431 | } /* if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */ |
c995fe94 ADG |
1432 | else { |
1433 | printk("\nError in selection of interrupt enable or disable\n"); | |
1434 | return -EINVAL; | |
c47375f3 BP |
1435 | } /* elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */ |
1436 | } /* if ((data[3]>= 0) && (data[3] <= 65535)) */ | |
c995fe94 ADG |
1437 | else { |
1438 | printk("\nError in selection of reload value\n"); | |
1439 | return -EINVAL; | |
c47375f3 | 1440 | } /* else if ((data[3]>= 0) && (data[3] <= 65535)) */ |
c995fe94 ADG |
1441 | i_TimerCounterWatchdogInterrupt = data[7]; |
1442 | i_TimerCounter1Init = 1; | |
1443 | break; | |
1444 | ||
c47375f3 | 1445 | case COUNTER2: /* selecting counter or timer */ |
c995fe94 ADG |
1446 | switch (data[2]) { |
1447 | case 0: | |
1448 | data[2] = APCI1500_COUNTER; | |
1449 | break; | |
1450 | case 1: | |
1451 | data[2] = APCI1500_TIMER; | |
1452 | break; | |
1453 | default: | |
1454 | printk("\nThis choice is not a timer nor a counter\n"); | |
1455 | return -EINVAL; | |
c47375f3 | 1456 | } /* switch(data[2]) */ |
c995fe94 | 1457 | |
c47375f3 | 1458 | /* Selecting single or continuous mode */ |
c995fe94 ADG |
1459 | switch (data[4]) { |
1460 | case 0: | |
1461 | data[4] = APCI1500_CONTINUOUS; | |
1462 | break; | |
1463 | case 1: | |
1464 | data[4] = APCI1500_SINGLE; | |
1465 | break; | |
1466 | default: | |
1467 | printk("\nThis option for single/continuous mode does not exist\n"); | |
1468 | return -EINVAL; | |
c47375f3 | 1469 | } /* switch(data[4]) */ |
c995fe94 | 1470 | |
c47375f3 | 1471 | /* Selecting software or hardware trigger */ |
c995fe94 ADG |
1472 | switch (data[5]) { |
1473 | case 0: | |
1474 | data[5] = APCI1500_SOFTWARE_TRIGGER; | |
1475 | break; | |
1476 | case 1: | |
1477 | data[5] = APCI1500_HARDWARE_TRIGGER; | |
1478 | break; | |
1479 | default: | |
1480 | printk("\nThis choice for software or hardware trigger does not exist\n"); | |
1481 | return -EINVAL; | |
c47375f3 | 1482 | } /* switch(data[5]) */ |
c995fe94 | 1483 | |
c47375f3 | 1484 | /* Selecting software or hardware gate */ |
c995fe94 ADG |
1485 | switch (data[6]) { |
1486 | case 0: | |
1487 | data[6] = APCI1500_SOFTWARE_GATE; | |
1488 | break; | |
1489 | case 1: | |
1490 | data[6] = APCI1500_HARDWARE_GATE; | |
1491 | break; | |
1492 | default: | |
1493 | printk("\nThis choice for software or hardware gate does not exist\n"); | |
1494 | return -EINVAL; | |
c47375f3 | 1495 | } /* switch(data[6]) */ |
c995fe94 ADG |
1496 | |
1497 | i_TimerCounterMode = data[2] | data[4] | data[5] | data[6] | 7; | |
1498 | ||
1499 | /*************************/ | |
1500 | /* Test the reload value */ | |
1501 | /*************************/ | |
1502 | ||
1503 | if ((data[3] >= 0) && (data[3] <= 65535)) { | |
1504 | if (data[7] == APCI1500_ENABLE | |
1505 | || data[7] == APCI1500_DISABLE) { | |
1506 | ||
1507 | /************************************************/ | |
1508 | /* Selects the mode register of timer/counter 2 */ | |
1509 | /************************************************/ | |
1510 | outb(APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION, | |
1511 | devpriv->iobase + | |
1512 | APCI1500_Z8536_CONTROL_REGISTER); | |
1513 | /***********************/ | |
1514 | /* Writes the new mode */ | |
1515 | /***********************/ | |
1516 | outb(i_TimerCounterMode, | |
1517 | devpriv->iobase + | |
1518 | APCI1500_Z8536_CONTROL_REGISTER); | |
1519 | ||
1520 | /****************************************************/ | |
1521 | /* Selects the constant register of timer/counter 2 */ | |
1522 | /****************************************************/ | |
1523 | ||
1524 | outb(APCI1500_RW_CPT_TMR2_TIME_CST_LOW, | |
1525 | devpriv->iobase + | |
1526 | APCI1500_Z8536_CONTROL_REGISTER); | |
1527 | ||
1528 | /*************************/ | |
1529 | /* Writes the low value */ | |
1530 | /*************************/ | |
1531 | ||
1532 | outb(data[3], | |
1533 | devpriv->iobase + | |
1534 | APCI1500_Z8536_CONTROL_REGISTER); | |
1535 | ||
1536 | /****************************************************/ | |
1537 | /* Selects the constant register of timer/counter 2 */ | |
1538 | /****************************************************/ | |
1539 | ||
1540 | outb(APCI1500_RW_CPT_TMR2_TIME_CST_HIGH, | |
1541 | devpriv->iobase + | |
1542 | APCI1500_Z8536_CONTROL_REGISTER); | |
1543 | ||
1544 | /**************************/ | |
1545 | /* Writes the high value */ | |
1546 | /**************************/ | |
1547 | ||
1548 | data[3] = data[3] >> 8; | |
1549 | outb(data[3], | |
1550 | devpriv->iobase + | |
1551 | APCI1500_Z8536_CONTROL_REGISTER); | |
1552 | ||
1553 | /*********************************************/ | |
1554 | /* Selects the master configuration register */ | |
1555 | /*********************************************/ | |
1556 | ||
1557 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
1558 | devpriv->iobase + | |
1559 | APCI1500_Z8536_CONTROL_REGISTER); | |
1560 | ||
1561 | /**********************/ | |
1562 | /* Reads the register */ | |
1563 | /**********************/ | |
1564 | ||
1565 | i_MasterConfiguration = | |
1566 | inb(devpriv->iobase + | |
1567 | APCI1500_Z8536_CONTROL_REGISTER); | |
1568 | ||
1569 | /********************************************************/ | |
1570 | /* Enables timer/counter 2 and triggers timer/counter 2 */ | |
1571 | /********************************************************/ | |
1572 | ||
1573 | i_MasterConfiguration = | |
1574 | i_MasterConfiguration | 0x20; | |
1575 | ||
1576 | /*********************************************/ | |
1577 | /* Selects the master configuration register */ | |
1578 | /*********************************************/ | |
1579 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
1580 | devpriv->iobase + | |
1581 | APCI1500_Z8536_CONTROL_REGISTER); | |
1582 | ||
1583 | /********************************/ | |
1584 | /* Writes the new configuration */ | |
1585 | /********************************/ | |
1586 | outb(i_MasterConfiguration, | |
1587 | devpriv->iobase + | |
1588 | APCI1500_Z8536_CONTROL_REGISTER); | |
1589 | /****************************************/ | |
1590 | /* Selects the commands register of */ | |
1591 | /* timer/counter 2 */ | |
1592 | /****************************************/ | |
1593 | ||
1594 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
1595 | devpriv->iobase + | |
1596 | APCI1500_Z8536_CONTROL_REGISTER); | |
1597 | ||
1598 | /***************************/ | |
1599 | /* Disable timer/counter 2 */ | |
1600 | /***************************/ | |
1601 | ||
1602 | outb(0x0, | |
1603 | devpriv->iobase + | |
1604 | APCI1500_Z8536_CONTROL_REGISTER); | |
1605 | /****************************************/ | |
1606 | /* Selects the commands register of */ | |
1607 | /* timer/counter 2 */ | |
1608 | /****************************************/ | |
1609 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
1610 | devpriv->iobase + | |
1611 | APCI1500_Z8536_CONTROL_REGISTER); | |
1612 | ||
1613 | /***************************/ | |
1614 | /* Trigger timer/counter 1 */ | |
1615 | /***************************/ | |
1616 | outb(0x2, | |
1617 | devpriv->iobase + | |
1618 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 1619 | } /* if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */ |
c995fe94 ADG |
1620 | else { |
1621 | printk("\nError in selection of interrupt enable or disable\n"); | |
1622 | return -EINVAL; | |
c47375f3 BP |
1623 | } /* elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */ |
1624 | } /* if ((data[3]>= 0) && (data[3] <= 65535)) */ | |
c995fe94 ADG |
1625 | else { |
1626 | printk("\nError in selection of reload value\n"); | |
1627 | return -EINVAL; | |
c47375f3 | 1628 | } /* else if ((data[3]>= 0) && (data[3] <= 65535)) */ |
c995fe94 ADG |
1629 | i_TimerCounterWatchdogInterrupt = data[7]; |
1630 | i_TimerCounter2Init = 1; | |
1631 | break; | |
1632 | ||
c47375f3 | 1633 | case COUNTER3: /* selecting counter or watchdog */ |
c995fe94 ADG |
1634 | switch (data[2]) { |
1635 | case 0: | |
1636 | data[2] = APCI1500_COUNTER; | |
1637 | break; | |
1638 | case 1: | |
1639 | data[2] = APCI1500_WATCHDOG; | |
1640 | break; | |
1641 | default: | |
1642 | printk("\nThis choice is not a watchdog nor a counter\n"); | |
1643 | return -EINVAL; | |
c47375f3 | 1644 | } /* switch(data[2]) */ |
c995fe94 | 1645 | |
c47375f3 | 1646 | /* Selecting single or continuous mode */ |
c995fe94 ADG |
1647 | switch (data[4]) { |
1648 | case 0: | |
1649 | data[4] = APCI1500_CONTINUOUS; | |
1650 | break; | |
1651 | case 1: | |
1652 | data[4] = APCI1500_SINGLE; | |
1653 | break; | |
1654 | default: | |
1655 | printk("\nThis option for single/continuous mode does not exist\n"); | |
1656 | return -EINVAL; | |
c47375f3 | 1657 | } /* switch(data[4]) */ |
c995fe94 | 1658 | |
c47375f3 | 1659 | /* Selecting software or hardware gate */ |
c995fe94 ADG |
1660 | switch (data[6]) { |
1661 | case 0: | |
1662 | data[6] = APCI1500_SOFTWARE_GATE; | |
1663 | break; | |
1664 | case 1: | |
1665 | data[6] = APCI1500_HARDWARE_GATE; | |
1666 | break; | |
1667 | default: | |
1668 | printk("\nThis choice for software or hardware gate does not exist\n"); | |
1669 | return -EINVAL; | |
c47375f3 | 1670 | } /* switch(data[6]) */ |
c995fe94 ADG |
1671 | |
1672 | /*****************************/ | |
1673 | /* Test if used for watchdog */ | |
1674 | /*****************************/ | |
1675 | ||
1676 | if (data[2] == APCI1500_WATCHDOG) { | |
1677 | /*****************************/ | |
1678 | /* - Enables the output line */ | |
1679 | /* - Enables retrigger */ | |
1680 | /* - Pulses output */ | |
1681 | /*****************************/ | |
1682 | i_TimerCounterMode = data[2] | data[4] | 0x54; | |
c47375f3 | 1683 | } /* if (data[2] == APCI1500_WATCHDOG) */ |
c995fe94 ADG |
1684 | else { |
1685 | i_TimerCounterMode = data[2] | data[4] | data[6] | 7; | |
c47375f3 | 1686 | } /* elseif (data[2] == APCI1500_WATCHDOG) */ |
c995fe94 ADG |
1687 | /*************************/ |
1688 | /* Test the reload value */ | |
1689 | /*************************/ | |
1690 | ||
1691 | if ((data[3] >= 0) && (data[3] <= 65535)) { | |
1692 | if (data[7] == APCI1500_ENABLE | |
1693 | || data[7] == APCI1500_DISABLE) { | |
1694 | ||
1695 | /************************************************/ | |
1696 | /* Selects the mode register of watchdog/counter 3 */ | |
1697 | /************************************************/ | |
1698 | outb(APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION, | |
1699 | devpriv->iobase + | |
1700 | APCI1500_Z8536_CONTROL_REGISTER); | |
1701 | /***********************/ | |
1702 | /* Writes the new mode */ | |
1703 | /***********************/ | |
1704 | outb(i_TimerCounterMode, | |
1705 | devpriv->iobase + | |
1706 | APCI1500_Z8536_CONTROL_REGISTER); | |
1707 | ||
1708 | /****************************************************/ | |
1709 | /* Selects the constant register of watchdog/counter 3 */ | |
1710 | /****************************************************/ | |
1711 | ||
1712 | outb(APCI1500_RW_CPT_TMR3_TIME_CST_LOW, | |
1713 | devpriv->iobase + | |
1714 | APCI1500_Z8536_CONTROL_REGISTER); | |
1715 | ||
1716 | /*************************/ | |
1717 | /* Writes the low value */ | |
1718 | /*************************/ | |
1719 | ||
1720 | outb(data[3], | |
1721 | devpriv->iobase + | |
1722 | APCI1500_Z8536_CONTROL_REGISTER); | |
1723 | ||
1724 | /****************************************************/ | |
1725 | /* Selects the constant register of watchdog/counter 3 */ | |
1726 | /****************************************************/ | |
1727 | ||
1728 | outb(APCI1500_RW_CPT_TMR3_TIME_CST_HIGH, | |
1729 | devpriv->iobase + | |
1730 | APCI1500_Z8536_CONTROL_REGISTER); | |
1731 | ||
1732 | /**************************/ | |
1733 | /* Writes the high value */ | |
1734 | /**************************/ | |
1735 | ||
1736 | data[3] = data[3] >> 8; | |
1737 | outb(data[3], | |
1738 | devpriv->iobase + | |
1739 | APCI1500_Z8536_CONTROL_REGISTER); | |
1740 | ||
1741 | /*********************************************/ | |
1742 | /* Selects the master configuration register */ | |
1743 | /*********************************************/ | |
1744 | ||
1745 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
1746 | devpriv->iobase + | |
1747 | APCI1500_Z8536_CONTROL_REGISTER); | |
1748 | ||
1749 | /**********************/ | |
1750 | /* Reads the register */ | |
1751 | /**********************/ | |
1752 | ||
1753 | i_MasterConfiguration = | |
1754 | inb(devpriv->iobase + | |
1755 | APCI1500_Z8536_CONTROL_REGISTER); | |
1756 | ||
1757 | /********************************************************/ | |
1758 | /* Enables watchdog/counter 3 and triggers watchdog/counter 3 */ | |
1759 | /********************************************************/ | |
1760 | ||
1761 | i_MasterConfiguration = | |
1762 | i_MasterConfiguration | 0x10; | |
1763 | ||
1764 | /*********************************************/ | |
1765 | /* Selects the master configuration register */ | |
1766 | /*********************************************/ | |
1767 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
1768 | devpriv->iobase + | |
1769 | APCI1500_Z8536_CONTROL_REGISTER); | |
1770 | ||
1771 | /********************************/ | |
1772 | /* Writes the new configuration */ | |
1773 | /********************************/ | |
1774 | outb(i_MasterConfiguration, | |
1775 | devpriv->iobase + | |
1776 | APCI1500_Z8536_CONTROL_REGISTER); | |
1777 | ||
1778 | /********************/ | |
1779 | /* Test if COUNTER */ | |
1780 | /********************/ | |
1781 | if (data[2] == APCI1500_COUNTER) { | |
1782 | ||
1783 | /*************************************/ | |
1784 | /* Selects the command register of */ | |
1785 | /* watchdog/counter 3 */ | |
1786 | /*************************************/ | |
1787 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
1788 | devpriv->iobase + | |
1789 | APCI1500_Z8536_CONTROL_REGISTER); | |
1790 | /*************************************************/ | |
1791 | /* Disable the watchdog/counter 3 and starts it */ | |
1792 | /*************************************************/ | |
1793 | outb(0x0, | |
1794 | devpriv->iobase + | |
1795 | APCI1500_Z8536_CONTROL_REGISTER); | |
1796 | ||
1797 | /*************************************/ | |
1798 | /* Selects the command register of */ | |
1799 | /* watchdog/counter 3 */ | |
1800 | /*************************************/ | |
1801 | ||
1802 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
1803 | devpriv->iobase + | |
1804 | APCI1500_Z8536_CONTROL_REGISTER); | |
1805 | /*************************************************/ | |
1806 | /* Trigger the watchdog/counter 3 and starts it */ | |
1807 | /*************************************************/ | |
1808 | outb(0x2, | |
1809 | devpriv->iobase + | |
1810 | APCI1500_Z8536_CONTROL_REGISTER); | |
1811 | ||
c47375f3 | 1812 | } /* elseif(data[2]==APCI1500_COUNTER) */ |
c995fe94 | 1813 | |
c47375f3 | 1814 | } /* if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */ |
c995fe94 ADG |
1815 | else { |
1816 | printk("\nError in selection of interrupt enable or disable\n"); | |
1817 | return -EINVAL; | |
c47375f3 BP |
1818 | } /* elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE) */ |
1819 | } /* if ((data[3]>= 0) && (data[3] <= 65535)) */ | |
c995fe94 ADG |
1820 | else { |
1821 | printk("\nError in selection of reload value\n"); | |
1822 | return -EINVAL; | |
c47375f3 | 1823 | } /* else if ((data[3]>= 0) && (data[3] <= 65535)) */ |
c995fe94 ADG |
1824 | i_TimerCounterWatchdogInterrupt = data[7]; |
1825 | i_WatchdogCounter3Init = 1; | |
1826 | break; | |
1827 | ||
1828 | default: | |
1829 | printk("\nThe specified counter\timer option does not exist\n"); | |
c47375f3 | 1830 | } /* switch(data[1]) */ |
c995fe94 ADG |
1831 | i_CounterLogic = data[2]; |
1832 | return insn->n; | |
1833 | } | |
1834 | ||
1835 | /* | |
1836 | +----------------------------------------------------------------------------+ | |
1837 | | Function Name : int i_APCI1500_StartStopTriggerTimerCounterWatchdog | | |
34c43922 | 1838 | | (struct comedi_device *dev,struct comedi_subdevice *s, |
356cdbcb | 1839 | | struct comedi_insn *insn,unsigned int *data); | |
c995fe94 ADG |
1840 | +----------------------------------------------------------------------------+ |
1841 | | Task : Start / Stop or trigger the timer counter or Watchdog | | |
1842 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 1843 | | Input Parameters : struct comedi_device *dev : Driver handle | |
34c43922 | 1844 | | struct comedi_subdevice *s, :pointer to subdevice structure |
356cdbcb | 1845 | | struct comedi_insn *insn :pointer to insn structure | |
790c5541 | 1846 | | unsigned int *data : Data Pointer to read status | |
356cdbcb BP |
1847 | | data[0] : 0 Counter1/Timer1 |
1848 | | 1 Counter2/Timer2 | |
1849 | | 2 Counter3/Watchdog | |
1850 | | data[1] : 0 start | |
1851 | | 1 stop | |
1852 | | 2 Trigger | |
1853 | | data[2] : 0 Counter | |
1854 | | 1 Timer/Watchdog | |
c995fe94 ADG |
1855 | +----------------------------------------------------------------------------+ |
1856 | | Output Parameters : -- | | |
1857 | +----------------------------------------------------------------------------+ | |
1858 | | Return Value : TRUE : No error occur | | |
1859 | | : FALSE : Error occur. Return the error | | |
1860 | | | | |
1861 | +----------------------------------------------------------------------------+ | |
1862 | */ | |
da91b269 BP |
1863 | int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev, |
1864 | struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) | |
c995fe94 ADG |
1865 | { |
1866 | int i_CommandAndStatusValue; | |
1867 | ||
1868 | switch (data[0]) { | |
1869 | case COUNTER1: | |
1870 | switch (data[1]) { | |
1871 | case START: | |
1872 | if (i_TimerCounter1Init == 1) { | |
1873 | if (i_TimerCounterWatchdogInterrupt == 1) { | |
c47375f3 BP |
1874 | i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */ |
1875 | } /* if(i_TimerCounterWatchdogInterrupt==1) */ | |
c995fe94 | 1876 | else { |
c47375f3 BP |
1877 | i_CommandAndStatusValue = 0xE4; /* disable the interrupt */ |
1878 | } /* elseif(i_TimerCounterWatchdogInterrupt==1) */ | |
c995fe94 ADG |
1879 | /**************************/ |
1880 | /* Starts timer/counter 1 */ | |
1881 | /**************************/ | |
1882 | i_TimerCounter1Enabled = 1; | |
1883 | /********************************************/ | |
1884 | /* Selects the commands and status register */ | |
1885 | /********************************************/ | |
1886 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
1887 | devpriv->iobase + | |
1888 | APCI1500_Z8536_CONTROL_REGISTER); | |
1889 | outb(i_CommandAndStatusValue, | |
1890 | devpriv->iobase + | |
1891 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 1892 | } /* if( i_TimerCounter1Init==1) */ |
c995fe94 ADG |
1893 | else { |
1894 | printk("\nCounter/Timer1 not configured\n"); | |
1895 | return -EINVAL; | |
1896 | } | |
1897 | break; | |
1898 | ||
1899 | case STOP: | |
1900 | ||
1901 | /**************************/ | |
1902 | /* Stop timer/counter 1 */ | |
1903 | /**************************/ | |
1904 | ||
1905 | /********************************************/ | |
1906 | /* Selects the commands and status register */ | |
1907 | /********************************************/ | |
1908 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
1909 | devpriv->iobase + | |
1910 | APCI1500_Z8536_CONTROL_REGISTER); | |
1911 | outb(0x00, | |
1912 | devpriv->iobase + | |
1913 | APCI1500_Z8536_CONTROL_REGISTER); | |
1914 | i_TimerCounter1Enabled = 0; | |
1915 | break; | |
1916 | ||
1917 | case TRIGGER: | |
1918 | if (i_TimerCounter1Init == 1) { | |
1919 | if (i_TimerCounter1Enabled == 1) { | |
1920 | /************************/ | |
1921 | /* Set Trigger and gate */ | |
1922 | /************************/ | |
1923 | ||
1924 | i_CommandAndStatusValue = 0x6; | |
c47375f3 | 1925 | } /* if( i_TimerCounter1Enabled==1) */ |
c995fe94 ADG |
1926 | else { |
1927 | /***************/ | |
1928 | /* Set Trigger */ | |
1929 | /***************/ | |
1930 | ||
1931 | i_CommandAndStatusValue = 0x2; | |
c47375f3 | 1932 | } /* elseif(i_TimerCounter1Enabled==1) */ |
c995fe94 ADG |
1933 | |
1934 | /********************************************/ | |
1935 | /* Selects the commands and status register */ | |
1936 | /********************************************/ | |
1937 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
1938 | devpriv->iobase + | |
1939 | APCI1500_Z8536_CONTROL_REGISTER); | |
1940 | outb(i_CommandAndStatusValue, | |
1941 | devpriv->iobase + | |
1942 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 1943 | } /* if( i_TimerCounter1Init==1) */ |
c995fe94 ADG |
1944 | else { |
1945 | printk("\nCounter/Timer1 not configured\n"); | |
1946 | return -EINVAL; | |
1947 | } | |
1948 | break; | |
1949 | ||
1950 | default: | |
1951 | printk("\nThe specified option for start/stop/trigger does not exist\n"); | |
1952 | return -EINVAL; | |
c47375f3 | 1953 | } /* switch(data[1]) */ |
c995fe94 ADG |
1954 | break; |
1955 | ||
1956 | case COUNTER2: | |
1957 | switch (data[1]) { | |
1958 | case START: | |
1959 | if (i_TimerCounter2Init == 1) { | |
1960 | if (i_TimerCounterWatchdogInterrupt == 1) { | |
c47375f3 BP |
1961 | i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */ |
1962 | } /* if(i_TimerCounterWatchdogInterrupt==1) */ | |
c995fe94 | 1963 | else { |
c47375f3 BP |
1964 | i_CommandAndStatusValue = 0xE4; /* disable the interrupt */ |
1965 | } /* elseif(i_TimerCounterWatchdogInterrupt==1) */ | |
c995fe94 ADG |
1966 | /**************************/ |
1967 | /* Starts timer/counter 2 */ | |
1968 | /**************************/ | |
1969 | i_TimerCounter2Enabled = 1; | |
1970 | /********************************************/ | |
1971 | /* Selects the commands and status register */ | |
1972 | /********************************************/ | |
1973 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
1974 | devpriv->iobase + | |
1975 | APCI1500_Z8536_CONTROL_REGISTER); | |
1976 | outb(i_CommandAndStatusValue, | |
1977 | devpriv->iobase + | |
1978 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 1979 | } /* if( i_TimerCounter2Init==1) */ |
c995fe94 ADG |
1980 | else { |
1981 | printk("\nCounter/Timer2 not configured\n"); | |
1982 | return -EINVAL; | |
1983 | } | |
1984 | break; | |
1985 | ||
1986 | case STOP: | |
1987 | ||
1988 | /**************************/ | |
1989 | /* Stop timer/counter 2 */ | |
1990 | /**************************/ | |
1991 | ||
1992 | /********************************************/ | |
1993 | /* Selects the commands and status register */ | |
1994 | /********************************************/ | |
1995 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
1996 | devpriv->iobase + | |
1997 | APCI1500_Z8536_CONTROL_REGISTER); | |
1998 | outb(0x00, | |
1999 | devpriv->iobase + | |
2000 | APCI1500_Z8536_CONTROL_REGISTER); | |
2001 | i_TimerCounter2Enabled = 0; | |
2002 | break; | |
2003 | case TRIGGER: | |
2004 | if (i_TimerCounter2Init == 1) { | |
2005 | if (i_TimerCounter2Enabled == 1) { | |
2006 | /************************/ | |
2007 | /* Set Trigger and gate */ | |
2008 | /************************/ | |
2009 | ||
2010 | i_CommandAndStatusValue = 0x6; | |
c47375f3 | 2011 | } /* if( i_TimerCounter2Enabled==1) */ |
c995fe94 ADG |
2012 | else { |
2013 | /***************/ | |
2014 | /* Set Trigger */ | |
2015 | /***************/ | |
2016 | ||
2017 | i_CommandAndStatusValue = 0x2; | |
c47375f3 | 2018 | } /* elseif(i_TimerCounter2Enabled==1) */ |
c995fe94 ADG |
2019 | |
2020 | /********************************************/ | |
2021 | /* Selects the commands and status register */ | |
2022 | /********************************************/ | |
2023 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
2024 | devpriv->iobase + | |
2025 | APCI1500_Z8536_CONTROL_REGISTER); | |
2026 | outb(i_CommandAndStatusValue, | |
2027 | devpriv->iobase + | |
2028 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 2029 | } /* if( i_TimerCounter2Init==1) */ |
c995fe94 ADG |
2030 | else { |
2031 | printk("\nCounter/Timer2 not configured\n"); | |
2032 | return -EINVAL; | |
2033 | } | |
2034 | break; | |
2035 | default: | |
2036 | printk("\nThe specified option for start/stop/trigger does not exist\n"); | |
2037 | return -EINVAL; | |
c47375f3 | 2038 | } /* switch(data[1]) */ |
c995fe94 ADG |
2039 | break; |
2040 | case COUNTER3: | |
2041 | switch (data[1]) { | |
2042 | case START: | |
2043 | if (i_WatchdogCounter3Init == 1) { | |
2044 | ||
2045 | if (i_TimerCounterWatchdogInterrupt == 1) { | |
c47375f3 BP |
2046 | i_CommandAndStatusValue = 0xC4; /* Enable the interrupt */ |
2047 | } /* if(i_TimerCounterWatchdogInterrupt==1) */ | |
c995fe94 | 2048 | else { |
c47375f3 BP |
2049 | i_CommandAndStatusValue = 0xE4; /* disable the interrupt */ |
2050 | } /* elseif(i_TimerCounterWatchdogInterrupt==1) */ | |
c995fe94 ADG |
2051 | /**************************/ |
2052 | /* Starts Watchdog/counter 3 */ | |
2053 | /**************************/ | |
2054 | i_WatchdogCounter3Enabled = 1; | |
2055 | /********************************************/ | |
2056 | /* Selects the commands and status register */ | |
2057 | /********************************************/ | |
2058 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2059 | devpriv->iobase + | |
2060 | APCI1500_Z8536_CONTROL_REGISTER); | |
2061 | outb(i_CommandAndStatusValue, | |
2062 | devpriv->iobase + | |
2063 | APCI1500_Z8536_CONTROL_REGISTER); | |
2064 | ||
c47375f3 | 2065 | } /* if( i_WatchdogCounter3init==1) */ |
c995fe94 ADG |
2066 | else { |
2067 | printk("\nWatchdog/Counter3 not configured\n"); | |
2068 | return -EINVAL; | |
2069 | } | |
2070 | break; | |
2071 | ||
2072 | case STOP: | |
2073 | ||
2074 | /**************************/ | |
2075 | /* Stop Watchdog/counter 3 */ | |
2076 | /**************************/ | |
2077 | ||
2078 | /********************************************/ | |
2079 | /* Selects the commands and status register */ | |
2080 | /********************************************/ | |
2081 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2082 | devpriv->iobase + | |
2083 | APCI1500_Z8536_CONTROL_REGISTER); | |
2084 | outb(0x00, | |
2085 | devpriv->iobase + | |
2086 | APCI1500_Z8536_CONTROL_REGISTER); | |
2087 | i_WatchdogCounter3Enabled = 0; | |
2088 | break; | |
2089 | ||
2090 | case TRIGGER: | |
2091 | switch (data[2]) { | |
c47375f3 | 2092 | case 0: /* triggering counter 3 */ |
c995fe94 ADG |
2093 | if (i_WatchdogCounter3Init == 1) { |
2094 | if (i_WatchdogCounter3Enabled == 1) { | |
2095 | /************************/ | |
2096 | /* Set Trigger and gate */ | |
2097 | /************************/ | |
2098 | ||
2099 | i_CommandAndStatusValue = 0x6; | |
c47375f3 | 2100 | } /* if( i_WatchdogCounter3Enabled==1) */ |
c995fe94 ADG |
2101 | else { |
2102 | /***************/ | |
2103 | /* Set Trigger */ | |
2104 | /***************/ | |
2105 | ||
2106 | i_CommandAndStatusValue = 0x2; | |
c47375f3 | 2107 | } /* elseif(i_WatchdogCounter3Enabled==1) */ |
c995fe94 ADG |
2108 | |
2109 | /********************************************/ | |
2110 | /* Selects the commands and status register */ | |
2111 | /********************************************/ | |
2112 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2113 | devpriv->iobase + | |
2114 | APCI1500_Z8536_CONTROL_REGISTER); | |
2115 | outb(i_CommandAndStatusValue, | |
2116 | devpriv->iobase + | |
2117 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 2118 | } /* if( i_WatchdogCounter3Init==1) */ |
c995fe94 ADG |
2119 | else { |
2120 | printk("\nCounter3 not configured\n"); | |
2121 | return -EINVAL; | |
2122 | } | |
2123 | break; | |
2124 | case 1: | |
c47375f3 | 2125 | /* triggering Watchdog 3 */ |
c995fe94 ADG |
2126 | if (i_WatchdogCounter3Init == 1) { |
2127 | ||
2128 | /********************************************/ | |
2129 | /* Selects the commands and status register */ | |
2130 | /********************************************/ | |
2131 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2132 | devpriv->iobase + | |
2133 | APCI1500_Z8536_CONTROL_REGISTER); | |
2134 | outb(0x6, | |
2135 | devpriv->iobase + | |
2136 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 2137 | } /* if( i_WatchdogCounter3Init==1) */ |
c995fe94 ADG |
2138 | else { |
2139 | printk("\nWatchdog 3 not configured\n"); | |
2140 | return -EINVAL; | |
2141 | } | |
2142 | break; | |
2143 | default: | |
2144 | printk("\nWrong choice of watchdog/counter3\n"); | |
2145 | return -EINVAL; | |
c47375f3 | 2146 | } /* switch(data[2]) */ |
c995fe94 ADG |
2147 | break; |
2148 | default: | |
2149 | printk("\nThe specified option for start/stop/trigger does not exist\n"); | |
2150 | return -EINVAL; | |
c47375f3 | 2151 | } /* switch(data[1]) */ |
c995fe94 ADG |
2152 | break; |
2153 | default: | |
2154 | printk("\nThe specified choice for counter/watchdog/timer does not exist\n"); | |
2155 | return -EINVAL; | |
c47375f3 | 2156 | } /* switch(data[0]) */ |
c995fe94 ADG |
2157 | return insn->n; |
2158 | } | |
2159 | ||
2160 | /* | |
2161 | +----------------------------------------------------------------------------+ | |
2162 | | Function Name : int i_APCI1500_ReadCounterTimerWatchdog | | |
90035c08 | 2163 | | (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, |
356cdbcb | 2164 | | unsigned int *data); | |
c995fe94 ADG |
2165 | +----------------------------------------------------------------------------+ |
2166 | | Task : Read The Watchdog | | |
2167 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 2168 | | Input Parameters : struct comedi_device *dev : Driver handle | |
34c43922 | 2169 | | struct comedi_subdevice *s, :pointer to subdevice structure |
356cdbcb | 2170 | | struct comedi_insn *insn :pointer to insn structure | |
790c5541 | 2171 | | unsigned int *data : Data Pointer to read status | |
356cdbcb BP |
2172 | | data[0] : 0 Counter1/Timer1 |
2173 | | 1 Counter2/Timer2 | |
2174 | | 2 Counter3/Watchdog | |
2175 | | | |
c995fe94 ADG |
2176 | +----------------------------------------------------------------------------+ |
2177 | | Output Parameters : -- | | |
2178 | +----------------------------------------------------------------------------+ | |
2179 | | Return Value : TRUE : No error occur | | |
2180 | | : FALSE : Error occur. Return the error | | |
2181 | | | | |
2182 | +----------------------------------------------------------------------------+ | |
2183 | */ | |
2184 | ||
da91b269 BP |
2185 | int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev, |
2186 | struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) | |
c995fe94 ADG |
2187 | { |
2188 | int i_CommandAndStatusValue; | |
2189 | switch (data[0]) { | |
2190 | case COUNTER1: | |
c47375f3 | 2191 | /* Read counter/timer1 */ |
c995fe94 ADG |
2192 | if (i_TimerCounter1Init == 1) { |
2193 | if (i_TimerCounter1Enabled == 1) { | |
2194 | /************************/ | |
2195 | /* Set RCC and gate */ | |
2196 | /************************/ | |
2197 | ||
2198 | i_CommandAndStatusValue = 0xC; | |
c47375f3 | 2199 | } /* if( i_TimerCounter1Init==1) */ |
c995fe94 ADG |
2200 | else { |
2201 | /***************/ | |
2202 | /* Set RCC */ | |
2203 | /***************/ | |
2204 | ||
2205 | i_CommandAndStatusValue = 0x8; | |
c47375f3 | 2206 | } /* elseif(i_TimerCounter1Init==1) */ |
c995fe94 ADG |
2207 | |
2208 | /********************************************/ | |
2209 | /* Selects the commands and status register */ | |
2210 | /********************************************/ | |
2211 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
2212 | devpriv->iobase + | |
2213 | APCI1500_Z8536_CONTROL_REGISTER); | |
2214 | outb(i_CommandAndStatusValue, | |
2215 | devpriv->iobase + | |
2216 | APCI1500_Z8536_CONTROL_REGISTER); | |
2217 | ||
2218 | /***************************************/ | |
2219 | /* Selects the counter register (high) */ | |
2220 | /***************************************/ | |
2221 | outb(APCI1500_R_CPT_TMR1_VALUE_HIGH, | |
2222 | devpriv->iobase + | |
2223 | APCI1500_Z8536_CONTROL_REGISTER); | |
2224 | data[0] = | |
2225 | inb(devpriv->iobase + | |
2226 | APCI1500_Z8536_CONTROL_REGISTER); | |
2227 | data[0] = data[0] << 8; | |
2228 | data[0] = data[0] & 0xff00; | |
2229 | outb(APCI1500_R_CPT_TMR1_VALUE_LOW, | |
2230 | devpriv->iobase + | |
2231 | APCI1500_Z8536_CONTROL_REGISTER); | |
2232 | data[0] = | |
2233 | data[0] | inb(devpriv->iobase + | |
2234 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 2235 | } /* if( i_TimerCounter1Init==1) */ |
c995fe94 ADG |
2236 | else { |
2237 | printk("\nTimer/Counter1 not configured\n"); | |
2238 | return -EINVAL; | |
c47375f3 | 2239 | } /* elseif( i_TimerCounter1Init==1) */ |
c995fe94 ADG |
2240 | break; |
2241 | case COUNTER2: | |
c47375f3 | 2242 | /* Read counter/timer2 */ |
c995fe94 ADG |
2243 | if (i_TimerCounter2Init == 1) { |
2244 | if (i_TimerCounter2Enabled == 1) { | |
2245 | /************************/ | |
2246 | /* Set RCC and gate */ | |
2247 | /************************/ | |
2248 | ||
2249 | i_CommandAndStatusValue = 0xC; | |
c47375f3 | 2250 | } /* if( i_TimerCounter2Init==1) */ |
c995fe94 ADG |
2251 | else { |
2252 | /***************/ | |
2253 | /* Set RCC */ | |
2254 | /***************/ | |
2255 | ||
2256 | i_CommandAndStatusValue = 0x8; | |
c47375f3 | 2257 | } /* elseif(i_TimerCounter2Init==1) */ |
c995fe94 ADG |
2258 | |
2259 | /********************************************/ | |
2260 | /* Selects the commands and status register */ | |
2261 | /********************************************/ | |
2262 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
2263 | devpriv->iobase + | |
2264 | APCI1500_Z8536_CONTROL_REGISTER); | |
2265 | outb(i_CommandAndStatusValue, | |
2266 | devpriv->iobase + | |
2267 | APCI1500_Z8536_CONTROL_REGISTER); | |
2268 | ||
2269 | /***************************************/ | |
2270 | /* Selects the counter register (high) */ | |
2271 | /***************************************/ | |
2272 | outb(APCI1500_R_CPT_TMR2_VALUE_HIGH, | |
2273 | devpriv->iobase + | |
2274 | APCI1500_Z8536_CONTROL_REGISTER); | |
2275 | data[0] = | |
2276 | inb(devpriv->iobase + | |
2277 | APCI1500_Z8536_CONTROL_REGISTER); | |
2278 | data[0] = data[0] << 8; | |
2279 | data[0] = data[0] & 0xff00; | |
2280 | outb(APCI1500_R_CPT_TMR2_VALUE_LOW, | |
2281 | devpriv->iobase + | |
2282 | APCI1500_Z8536_CONTROL_REGISTER); | |
2283 | data[0] = | |
2284 | data[0] | inb(devpriv->iobase + | |
2285 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 2286 | } /* if( i_TimerCounter2Init==1) */ |
c995fe94 ADG |
2287 | else { |
2288 | printk("\nTimer/Counter2 not configured\n"); | |
2289 | return -EINVAL; | |
c47375f3 | 2290 | } /* elseif( i_TimerCounter2Init==1) */ |
c995fe94 ADG |
2291 | break; |
2292 | case COUNTER3: | |
c47375f3 | 2293 | /* Read counter/watchdog2 */ |
c995fe94 ADG |
2294 | if (i_WatchdogCounter3Init == 1) { |
2295 | if (i_WatchdogCounter3Enabled == 1) { | |
2296 | /************************/ | |
2297 | /* Set RCC and gate */ | |
2298 | /************************/ | |
2299 | ||
2300 | i_CommandAndStatusValue = 0xC; | |
c47375f3 | 2301 | } /* if( i_TimerCounter2Init==1) */ |
c995fe94 ADG |
2302 | else { |
2303 | /***************/ | |
2304 | /* Set RCC */ | |
2305 | /***************/ | |
2306 | ||
2307 | i_CommandAndStatusValue = 0x8; | |
c47375f3 | 2308 | } /* elseif(i_WatchdogCounter3Init==1) */ |
c995fe94 ADG |
2309 | |
2310 | /********************************************/ | |
2311 | /* Selects the commands and status register */ | |
2312 | /********************************************/ | |
2313 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2314 | devpriv->iobase + | |
2315 | APCI1500_Z8536_CONTROL_REGISTER); | |
2316 | outb(i_CommandAndStatusValue, | |
2317 | devpriv->iobase + | |
2318 | APCI1500_Z8536_CONTROL_REGISTER); | |
2319 | ||
2320 | /***************************************/ | |
2321 | /* Selects the counter register (high) */ | |
2322 | /***************************************/ | |
2323 | outb(APCI1500_R_CPT_TMR3_VALUE_HIGH, | |
2324 | devpriv->iobase + | |
2325 | APCI1500_Z8536_CONTROL_REGISTER); | |
2326 | data[0] = | |
2327 | inb(devpriv->iobase + | |
2328 | APCI1500_Z8536_CONTROL_REGISTER); | |
2329 | data[0] = data[0] << 8; | |
2330 | data[0] = data[0] & 0xff00; | |
2331 | outb(APCI1500_R_CPT_TMR3_VALUE_LOW, | |
2332 | devpriv->iobase + | |
2333 | APCI1500_Z8536_CONTROL_REGISTER); | |
2334 | data[0] = | |
2335 | data[0] | inb(devpriv->iobase + | |
2336 | APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 2337 | } /* if( i_WatchdogCounter3Init==1) */ |
c995fe94 ADG |
2338 | else { |
2339 | printk("\nWatchdogCounter3 not configured\n"); | |
2340 | return -EINVAL; | |
c47375f3 | 2341 | } /* elseif( i_WatchdogCounter3Init==1) */ |
c995fe94 ADG |
2342 | break; |
2343 | default: | |
2344 | printk("\nThe choice of timer/counter/watchdog does not exist\n"); | |
2345 | return -EINVAL; | |
c47375f3 | 2346 | } /* switch(data[0]) */ |
c995fe94 ADG |
2347 | |
2348 | return insn->n; | |
2349 | } | |
2350 | ||
2351 | /* | |
2352 | +----------------------------------------------------------------------------+ | |
2353 | | Function Name : int i_APCI1500_ReadInterruptMask | | |
90035c08 | 2354 | | (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, |
356cdbcb | 2355 | | unsigned int *data); | |
c995fe94 ADG |
2356 | +----------------------------------------------------------------------------+ |
2357 | | Task : Read the interrupt mask | | |
2358 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 2359 | | Input Parameters : struct comedi_device *dev : Driver handle | |
34c43922 | 2360 | | struct comedi_subdevice *s, :pointer to subdevice structure |
356cdbcb | 2361 | | struct comedi_insn *insn :pointer to insn structure | |
790c5541 | 2362 | | unsigned int *data : Data Pointer to read status | |
c995fe94 ADG |
2363 | |
2364 | ||
2365 | +----------------------------------------------------------------------------+ | |
2366 | | Output Parameters : -- data[0]:The interrupt mask value data[1]:Channel no | |
2367 | +----------------------------------------------------------------------------+ | |
2368 | | Return Value : TRUE : No error occur | | |
2369 | | : FALSE : Error occur. Return the error | | |
2370 | | | | |
2371 | +----------------------------------------------------------------------------+ | |
2372 | */ | |
da91b269 BP |
2373 | int i_APCI1500_ReadInterruptMask(struct comedi_device *dev, struct comedi_subdevice *s, |
2374 | struct comedi_insn *insn, unsigned int *data) | |
c995fe94 ADG |
2375 | { |
2376 | data[0] = i_InterruptMask; | |
2377 | data[1] = i_InputChannel; | |
2378 | i_InterruptMask = 0; | |
2379 | return insn->n; | |
2380 | } | |
2381 | ||
2382 | /* | |
2383 | +----------------------------------------------------------------------------+ | |
2384 | | Function Name : int i_APCI1500_ConfigureInterrupt | | |
90035c08 | 2385 | | (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn, |
356cdbcb | 2386 | | unsigned int *data); | |
c995fe94 ADG |
2387 | +----------------------------------------------------------------------------+ |
2388 | | Task : Configures the interrupt registers | | |
2389 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 2390 | | Input Parameters : struct comedi_device *dev : Driver handle | |
34c43922 | 2391 | | struct comedi_subdevice *s, :pointer to subdevice structure |
356cdbcb | 2392 | | struct comedi_insn *insn :pointer to insn structure | |
790c5541 | 2393 | | unsigned int *data : Data Pointer | |
356cdbcb | 2394 | | |
c995fe94 ADG |
2395 | |
2396 | +----------------------------------------------------------------------------+ | |
2397 | | Output Parameters : -- | |
2398 | +----------------------------------------------------------------------------+ | |
2399 | | Return Value : TRUE : No error occur | | |
2400 | | : FALSE : Error occur. Return the error | | |
2401 | | | | |
2402 | +----------------------------------------------------------------------------+ | |
2403 | */ | |
da91b269 BP |
2404 | int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev, struct comedi_subdevice *s, |
2405 | struct comedi_insn *insn, unsigned int *data) | |
c995fe94 | 2406 | { |
117102b0 | 2407 | unsigned int ui_Status; |
c995fe94 ADG |
2408 | int i_RegValue; |
2409 | int i_Constant; | |
2410 | devpriv->tsk_Current = current; | |
2411 | outl(0x0, devpriv->i_IobaseAmcc + 0x38); | |
2412 | if (data[0] == 1) { | |
2413 | i_Constant = 0xC0; | |
c47375f3 | 2414 | } /* if(data[0]==1) */ |
c995fe94 ADG |
2415 | else { |
2416 | if (data[0] == 0) { | |
2417 | i_Constant = 0x00; | |
c47375f3 | 2418 | } /* if{data[0]==0) */ |
c995fe94 ADG |
2419 | else { |
2420 | printk("\nThe parameter passed to driver is in error for enabling the voltage interrupt\n"); | |
2421 | return -EINVAL; | |
c47375f3 BP |
2422 | } /* else if(data[0]==0) */ |
2423 | } /* elseif(data[0]==1) */ | |
c995fe94 ADG |
2424 | |
2425 | /*****************************************************/ | |
2426 | /* Selects the mode specification register of port B */ | |
2427 | /*****************************************************/ | |
2428 | outb(APCI1500_RW_PORT_B_SPECIFICATION, | |
2429 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2430 | i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2431 | outb(APCI1500_RW_PORT_B_SPECIFICATION, | |
2432 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2433 | /*********************************************/ | |
2434 | /* Writes the new configuration (APCI1500_OR) */ | |
2435 | /*********************************************/ | |
2436 | i_RegValue = (i_RegValue & 0xF9) | APCI1500_OR; | |
2437 | ||
2438 | outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2439 | /*****************************************************/ | |
2440 | /* Selects the command and status register of port B */ | |
2441 | /*****************************************************/ | |
2442 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
2443 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2444 | /*****************************************/ | |
2445 | /* Authorises the interrupt on the board */ | |
2446 | /*****************************************/ | |
2447 | outb(0xC0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2448 | /***************************************************/ | |
2449 | /* Selects the pattern polarity register of port B */ | |
2450 | /***************************************************/ | |
2451 | outb(APCI1500_RW_PORT_B_PATTERN_POLARITY, | |
2452 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2453 | outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2454 | /*****************************************************/ | |
2455 | /* Selects the pattern transition register of port B */ | |
2456 | /*****************************************************/ | |
2457 | outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION, | |
2458 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2459 | outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2460 | /***********************************************/ | |
2461 | /* Selects the pattern mask register of port B */ | |
2462 | /***********************************************/ | |
2463 | outb(APCI1500_RW_PORT_B_PATTERN_MASK, | |
2464 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2465 | outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2466 | ||
2467 | /*****************************************************/ | |
2468 | /* Selects the command and status register of port A */ | |
2469 | /*****************************************************/ | |
2470 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, | |
2471 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2472 | i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2473 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, | |
2474 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2475 | /***********************************/ | |
2476 | /* Deletes the interrupt of port A */ | |
2477 | /***********************************/ | |
2478 | ||
2479 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2480 | outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2481 | /*****************************************************/ | |
2482 | /* Selects the command and status register of port B */ | |
2483 | /*****************************************************/ | |
2484 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
2485 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2486 | i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2487 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
2488 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2489 | /***********************************/ | |
2490 | /* Deletes the interrupt of port B */ | |
2491 | /***********************************/ | |
2492 | ||
2493 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2494 | outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2495 | ||
2496 | /*****************************************************/ | |
2497 | /* Selects the command and status register of timer 1 */ | |
2498 | /*****************************************************/ | |
2499 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
2500 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2501 | i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2502 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
2503 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2504 | /***********************************/ | |
2505 | /* Deletes the interrupt of timer 1 */ | |
2506 | /***********************************/ | |
2507 | ||
2508 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2509 | outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2510 | ||
2511 | /*****************************************************/ | |
2512 | /* Selects the command and status register of timer 2 */ | |
2513 | /*****************************************************/ | |
2514 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
2515 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2516 | i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2517 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
2518 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2519 | /***********************************/ | |
2520 | /* Deletes the interrupt of timer 2 */ | |
2521 | /***********************************/ | |
2522 | ||
2523 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2524 | outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2525 | ||
2526 | /*****************************************************/ | |
2527 | /* Selects the command and status register of timer 3 */ | |
2528 | /*****************************************************/ | |
2529 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2530 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2531 | i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2532 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2533 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2534 | /***********************************/ | |
2535 | /* Deletes the interrupt of timer 3 */ | |
2536 | /***********************************/ | |
2537 | ||
2538 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2539 | outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2540 | ||
2541 | /*************************************************/ | |
2542 | /* Selects the master interrupt control register */ | |
2543 | /*************************************************/ | |
2544 | outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, | |
2545 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2546 | /**********************************************/ | |
2547 | /* Authorizes the main interrupt on the board */ | |
2548 | /**********************************************/ | |
2549 | outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2550 | ||
2551 | /***************************/ | |
2552 | /* Enables the PCI interrupt */ | |
2553 | /*****************************/ | |
2554 | outl(0x3000, devpriv->i_IobaseAmcc + 0x38); | |
2555 | ui_Status = inl(devpriv->i_IobaseAmcc + 0x10); | |
2556 | ui_Status = inl(devpriv->i_IobaseAmcc + 0x38); | |
2557 | outl(0x23000, devpriv->i_IobaseAmcc + 0x38); | |
2558 | ||
2559 | return insn->n; | |
2560 | } | |
2561 | ||
2562 | /* | |
2563 | +----------------------------------------------------------------------------+ | |
2564 | | Function Name : static void v_APCI1500_Interrupt | | |
2565 | | (int irq , void *d) | | |
2566 | +----------------------------------------------------------------------------+ | |
2567 | | Task : Interrupt handler | | |
2568 | +----------------------------------------------------------------------------+ | |
2569 | | Input Parameters : int irq : irq number | | |
2570 | | void *d : void pointer | | |
2571 | +----------------------------------------------------------------------------+ | |
2572 | | Output Parameters : -- | | |
2573 | +----------------------------------------------------------------------------+ | |
2574 | | Return Value : TRUE : No error occur | | |
2575 | | : FALSE : Error occur. Return the error | | |
2576 | | | | |
2577 | +----------------------------------------------------------------------------+ | |
2578 | */ | |
3019b410 | 2579 | static void v_APCI1500_Interrupt(int irq, void *d) |
c995fe94 ADG |
2580 | { |
2581 | ||
71b5f4f1 | 2582 | struct comedi_device *dev = d; |
117102b0 | 2583 | unsigned int ui_InterruptStatus = 0; |
c995fe94 ADG |
2584 | int i_RegValue = 0; |
2585 | i_InterruptMask = 0; | |
2586 | ||
2587 | /***********************************/ | |
2588 | /* Read the board interrupt status */ | |
2589 | /***********************************/ | |
2590 | ui_InterruptStatus = inl(devpriv->i_IobaseAmcc + 0x38); | |
2591 | ||
2592 | /***************************************/ | |
2593 | /* Test if board generated a interrupt */ | |
2594 | /***************************************/ | |
2595 | if ((ui_InterruptStatus & 0x800000) == 0x800000) { | |
2596 | /************************/ | |
2597 | /* Disable all Interrupt */ | |
2598 | /************************/ | |
2599 | /*************************************************/ | |
2600 | /* Selects the master interrupt control register */ | |
2601 | /*************************************************/ | |
c47375f3 | 2602 | /* outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER); */ |
c995fe94 ADG |
2603 | /**********************************************/ |
2604 | /* Disables the main interrupt on the board */ | |
2605 | /**********************************************/ | |
c47375f3 | 2606 | /* outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER); */ |
c995fe94 ADG |
2607 | |
2608 | /*****************************************************/ | |
2609 | /* Selects the command and status register of port A */ | |
2610 | /*****************************************************/ | |
2611 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, | |
2612 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2613 | i_RegValue = | |
2614 | inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2615 | if ((i_RegValue & 0x60) == 0x60) { | |
2616 | /*****************************************************/ | |
2617 | /* Selects the command and status register of port A */ | |
2618 | /*****************************************************/ | |
2619 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, | |
2620 | devpriv->iobase + | |
2621 | APCI1500_Z8536_CONTROL_REGISTER); | |
2622 | /***********************************/ | |
2623 | /* Deletes the interrupt of port A */ | |
2624 | /***********************************/ | |
2625 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2626 | outb(i_RegValue, | |
2627 | devpriv->iobase + | |
2628 | APCI1500_Z8536_CONTROL_REGISTER); | |
2629 | i_InterruptMask = i_InterruptMask | 1; | |
2630 | if (i_Logic == APCI1500_OR_PRIORITY) { | |
2631 | outb(APCI1500_RW_PORT_A_SPECIFICATION, | |
2632 | devpriv->iobase + | |
2633 | APCI1500_Z8536_CONTROL_REGISTER); | |
2634 | i_RegValue = | |
2635 | inb(devpriv->iobase + | |
2636 | APCI1500_Z8536_CONTROL_REGISTER); | |
2637 | ||
2638 | /***************************************************/ | |
2639 | /* Selects the interrupt vector register of port A */ | |
2640 | /***************************************************/ | |
2641 | outb(APCI1500_RW_PORT_A_INTERRUPT_CONTROL, | |
2642 | devpriv->iobase + | |
2643 | APCI1500_Z8536_CONTROL_REGISTER); | |
2644 | i_RegValue = | |
2645 | inb(devpriv->iobase + | |
2646 | APCI1500_Z8536_CONTROL_REGISTER); | |
2647 | ||
2648 | i_InputChannel = 1 + (i_RegValue >> 1); | |
2649 | ||
c47375f3 | 2650 | } /* if(i_Logic==APCI1500_OR_PRIORITY) */ |
c995fe94 ADG |
2651 | else { |
2652 | i_InputChannel = 0; | |
c47375f3 BP |
2653 | } /* elseif(i_Logic==APCI1500_OR_PRIORITY) */ |
2654 | } /* if ((i_RegValue & 0x60) == 0x60) */ | |
c995fe94 ADG |
2655 | |
2656 | /*****************************************************/ | |
2657 | /* Selects the command and status register of port B */ | |
2658 | /*****************************************************/ | |
2659 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
2660 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2661 | i_RegValue = | |
2662 | inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2663 | if ((i_RegValue & 0x60) == 0x60) { | |
2664 | /*****************************************************/ | |
2665 | /* Selects the command and status register of port B */ | |
2666 | /*****************************************************/ | |
2667 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
2668 | devpriv->iobase + | |
2669 | APCI1500_Z8536_CONTROL_REGISTER); | |
2670 | /***********************************/ | |
2671 | /* Deletes the interrupt of port B */ | |
2672 | /***********************************/ | |
2673 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2674 | outb(i_RegValue, | |
2675 | devpriv->iobase + | |
2676 | APCI1500_Z8536_CONTROL_REGISTER); | |
2677 | printk("\n\n\n"); | |
2678 | /****************/ | |
2679 | /* Reads port B */ | |
2680 | /****************/ | |
2681 | i_RegValue = | |
117102b0 | 2682 | inb((unsigned int) devpriv->iobase + |
c995fe94 ADG |
2683 | APCI1500_Z8536_PORT_B); |
2684 | ||
2685 | i_RegValue = i_RegValue & 0xC0; | |
2686 | /**************************************/ | |
2687 | /* Tests if this is an external error */ | |
2688 | /**************************************/ | |
2689 | ||
2690 | if (i_RegValue) { | |
c47375f3 | 2691 | /* Disable the interrupt */ |
c995fe94 ADG |
2692 | /*****************************************************/ |
2693 | /* Selects the command and status register of port B */ | |
2694 | /*****************************************************/ | |
2695 | outl(0x0, devpriv->i_IobaseAmcc + 0x38); | |
2696 | ||
2697 | if (i_RegValue & 0x80) { | |
2698 | i_InterruptMask = | |
2699 | i_InterruptMask | 0x40; | |
c47375f3 | 2700 | } /* if (i_RegValue & 0x80) */ |
c995fe94 ADG |
2701 | |
2702 | if (i_RegValue & 0x40) { | |
2703 | i_InterruptMask = | |
2704 | i_InterruptMask | 0x80; | |
c47375f3 BP |
2705 | } /* if (i_RegValue & 0x40) */ |
2706 | } /* if (i_RegValue) */ | |
c995fe94 ADG |
2707 | else { |
2708 | i_InterruptMask = i_InterruptMask | 2; | |
c47375f3 BP |
2709 | } /* if (i_RegValue) */ |
2710 | } /* if ((i_RegValue & 0x60) == 0x60) */ | |
c995fe94 ADG |
2711 | |
2712 | /*****************************************************/ | |
2713 | /* Selects the command and status register of timer 1 */ | |
2714 | /*****************************************************/ | |
2715 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
2716 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2717 | i_RegValue = | |
2718 | inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2719 | if ((i_RegValue & 0x60) == 0x60) { | |
2720 | /*****************************************************/ | |
2721 | /* Selects the command and status register of timer 1 */ | |
2722 | /*****************************************************/ | |
2723 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
2724 | devpriv->iobase + | |
2725 | APCI1500_Z8536_CONTROL_REGISTER); | |
2726 | /***********************************/ | |
2727 | /* Deletes the interrupt of timer 1 */ | |
2728 | /***********************************/ | |
2729 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2730 | outb(i_RegValue, | |
2731 | devpriv->iobase + | |
2732 | APCI1500_Z8536_CONTROL_REGISTER); | |
2733 | i_InterruptMask = i_InterruptMask | 4; | |
c47375f3 | 2734 | } /* if ((i_RegValue & 0x60) == 0x60) */ |
c995fe94 ADG |
2735 | /*****************************************************/ |
2736 | /* Selects the command and status register of timer 2 */ | |
2737 | /*****************************************************/ | |
2738 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
2739 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2740 | i_RegValue = | |
2741 | inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2742 | if ((i_RegValue & 0x60) == 0x60) { | |
2743 | /*****************************************************/ | |
2744 | /* Selects the command and status register of timer 2 */ | |
2745 | /*****************************************************/ | |
2746 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
2747 | devpriv->iobase + | |
2748 | APCI1500_Z8536_CONTROL_REGISTER); | |
2749 | /***********************************/ | |
2750 | /* Deletes the interrupt of timer 2 */ | |
2751 | /***********************************/ | |
2752 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2753 | outb(i_RegValue, | |
2754 | devpriv->iobase + | |
2755 | APCI1500_Z8536_CONTROL_REGISTER); | |
2756 | i_InterruptMask = i_InterruptMask | 8; | |
c47375f3 | 2757 | } /* if ((i_RegValue & 0x60) == 0x60) */ |
c995fe94 ADG |
2758 | |
2759 | /*****************************************************/ | |
2760 | /* Selects the command and status register of timer 3 */ | |
2761 | /*****************************************************/ | |
2762 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2763 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2764 | i_RegValue = | |
2765 | inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2766 | if ((i_RegValue & 0x60) == 0x60) { | |
2767 | /*****************************************************/ | |
2768 | /* Selects the command and status register of timer 3 */ | |
2769 | /*****************************************************/ | |
2770 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2771 | devpriv->iobase + | |
2772 | APCI1500_Z8536_CONTROL_REGISTER); | |
2773 | /***********************************/ | |
2774 | /* Deletes the interrupt of timer 3 */ | |
2775 | /***********************************/ | |
2776 | i_RegValue = (i_RegValue & 0x0F) | 0x20; | |
2777 | outb(i_RegValue, | |
2778 | devpriv->iobase + | |
2779 | APCI1500_Z8536_CONTROL_REGISTER); | |
2780 | if (i_CounterLogic == APCI1500_COUNTER) { | |
2781 | i_InterruptMask = i_InterruptMask | 0x10; | |
c47375f3 | 2782 | } /* if(i_CounterLogic==APCI1500_COUNTER) */ |
c995fe94 ADG |
2783 | else { |
2784 | i_InterruptMask = i_InterruptMask | 0x20; | |
2785 | } | |
c47375f3 | 2786 | } /* if ((i_RegValue & 0x60) == 0x60) */ |
c995fe94 | 2787 | |
c47375f3 | 2788 | send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */ |
c995fe94 ADG |
2789 | /***********************/ |
2790 | /* Enable all Interrupts */ | |
2791 | /***********************/ | |
2792 | ||
2793 | /*************************************************/ | |
2794 | /* Selects the master interrupt control register */ | |
2795 | /*************************************************/ | |
2796 | outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, | |
2797 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2798 | /**********************************************/ | |
2799 | /* Authorizes the main interrupt on the board */ | |
2800 | /**********************************************/ | |
2801 | outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 2802 | } /* if ((ui_InterruptStatus & 0x800000) == 0x800000) */ |
c995fe94 ADG |
2803 | else { |
2804 | printk("\nInterrupt from unknown source\n"); | |
2805 | ||
c47375f3 | 2806 | } /* else if ((ui_InterruptStatus & 0x800000) == 0x800000) */ |
c995fe94 ADG |
2807 | return; |
2808 | } | |
2809 | ||
2810 | /* | |
2811 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 2812 | | Function Name : int i_APCI1500_Reset(struct comedi_device *dev) | | |
c995fe94 ADG |
2813 | +----------------------------------------------------------------------------+ |
2814 | | Task :resets all the registers | | |
2815 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 2816 | | Input Parameters : struct comedi_device *dev |
c995fe94 ADG |
2817 | +----------------------------------------------------------------------------+ |
2818 | | Output Parameters : -- | | |
2819 | +----------------------------------------------------------------------------+ | |
2820 | | Return Value : | | |
2821 | | | | |
2822 | +----------------------------------------------------------------------------+ | |
2823 | */ | |
2824 | ||
da91b269 | 2825 | int i_APCI1500_Reset(struct comedi_device *dev) |
c995fe94 ADG |
2826 | { |
2827 | int i_DummyRead = 0; | |
2828 | i_TimerCounter1Init = 0; | |
2829 | i_TimerCounter2Init = 0; | |
2830 | i_WatchdogCounter3Init = 0; | |
2831 | i_Event1Status = 0; | |
2832 | i_Event2Status = 0; | |
2833 | i_TimerCounterWatchdogInterrupt = 0; | |
2834 | i_Logic = 0; | |
2835 | i_CounterLogic = 0; | |
2836 | i_InterruptMask = 0; | |
2837 | i_InputChannel = 0;; | |
2838 | i_TimerCounter1Enabled = 0; | |
2839 | i_TimerCounter2Enabled = 0; | |
2840 | i_WatchdogCounter3Enabled = 0; | |
2841 | ||
2842 | /******************/ | |
2843 | /* Software reset */ | |
2844 | /******************/ | |
2845 | i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2846 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2847 | i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2848 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2849 | outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2850 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2851 | ||
2852 | /*****************************************************/ | |
2853 | /* Selects the master configuration control register */ | |
2854 | /*****************************************************/ | |
2855 | outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, | |
2856 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2857 | outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2858 | ||
2859 | /*****************************************************/ | |
2860 | /* Selects the mode specification register of port A */ | |
2861 | /*****************************************************/ | |
2862 | outb(APCI1500_RW_PORT_A_SPECIFICATION, | |
2863 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2864 | outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2865 | ||
2866 | /* Selects the data path polarity register of port A */ | |
2867 | outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY, | |
2868 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2869 | /* High level of port A means 1 */ | |
2870 | outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2871 | ||
2872 | /* Selects the data direction register of port A */ | |
2873 | outb(APCI1500_RW_PORT_A_DATA_DIRECTION, | |
2874 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2875 | /* All bits used as inputs */ | |
2876 | outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2877 | /* Selects the command and status register of port A */ | |
2878 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, | |
2879 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2880 | /* Deletes IP and IUS */ | |
2881 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2882 | /* Selects the command and status register of port A */ | |
2883 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, | |
2884 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2885 | /* Deactivates the interrupt management of port A: */ | |
2886 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2887 | /* Selects the handshake specification register of port A */ | |
2888 | outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION, | |
2889 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2890 | /* Deletes the register */ | |
2891 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2892 | ||
2893 | /*****************************************************/ | |
2894 | /* Selects the mode specification register of port B */ | |
2895 | /*****************************************************/ | |
2896 | outb(APCI1500_RW_PORT_B_SPECIFICATION, | |
2897 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2898 | outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2899 | /* Selects the data path polarity register of port B */ | |
2900 | outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY, | |
2901 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2902 | /* A high level of port B means 1 */ | |
2903 | outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2904 | /* Selects the data direction register of port B */ | |
2905 | outb(APCI1500_RW_PORT_B_DATA_DIRECTION, | |
2906 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2907 | /* All bits used as inputs */ | |
2908 | outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2909 | /* Selects the command and status register of port B */ | |
2910 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
2911 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2912 | /* Deletes IP and IUS */ | |
2913 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2914 | /* Selects the command and status register of port B */ | |
2915 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
2916 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2917 | /* Deactivates the interrupt management of port B: */ | |
2918 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2919 | /* Selects the handshake specification register of port B */ | |
2920 | outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION, | |
2921 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2922 | /* Deletes the register */ | |
2923 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2924 | ||
2925 | /*****************************************************/ | |
2926 | /* Selects the data path polarity register of port C */ | |
2927 | /*****************************************************/ | |
2928 | outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY, | |
2929 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2930 | /* High level of port C means 1 */ | |
2931 | outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2932 | /* Selects the data direction register of port C */ | |
2933 | outb(APCI1500_RW_PORT_C_DATA_DIRECTION, | |
2934 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2935 | /* All bits used as inputs except channel 1 */ | |
2936 | outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2937 | /* Selects the special IO register of port C */ | |
2938 | outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL, | |
2939 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2940 | /* Deletes it */ | |
2941 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2942 | /******************************************************/ | |
2943 | /* Selects the command and status register of timer 1 */ | |
2944 | /******************************************************/ | |
2945 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
2946 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2947 | /* Deletes IP and IUS */ | |
2948 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2949 | /* Selects the command and status register of timer 1 */ | |
2950 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
2951 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2952 | /* Deactivates the interrupt management of timer 1 */ | |
2953 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2954 | /******************************************************/ | |
2955 | /* Selects the command and status register of timer 2 */ | |
2956 | /******************************************************/ | |
2957 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
2958 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2959 | /* Deletes IP and IUS */ | |
2960 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2961 | /* Selects the command and status register of timer 2 */ | |
2962 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
2963 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2964 | /* Deactivates Timer 2 interrupt management: */ | |
2965 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2966 | /******************************************************/ | |
2967 | /* Selects the command and status register of timer 3 */ | |
2968 | /******************************************************/ | |
2969 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2970 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2971 | /* Deletes IP and IUS */ | |
2972 | outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2973 | /* Selects the command and status register of Timer 3 */ | |
2974 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
2975 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2976 | /* Deactivates interrupt management of timer 3: */ | |
2977 | outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2978 | /*************************************************/ | |
2979 | /* Selects the master interrupt control register */ | |
2980 | /*************************************************/ | |
2981 | outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, | |
2982 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2983 | /* Deletes all interrupts */ | |
2984 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
c47375f3 | 2985 | /* reset all the digital outputs */ |
c995fe94 ADG |
2986 | outw(0x0, devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP); |
2987 | /*******************************/ | |
2988 | /* Disable the board interrupt */ | |
2989 | /*******************************/ | |
2990 | /*************************************************/ | |
2991 | /* Selects the master interrupt control register */ | |
2992 | /*************************************************/ | |
2993 | outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, | |
2994 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2995 | /****************************/ | |
2996 | /* Deactivates all interrupts */ | |
2997 | /******************************/ | |
2998 | outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
2999 | /*****************************************************/ | |
3000 | /* Selects the command and status register of port A */ | |
3001 | /*****************************************************/ | |
3002 | outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, | |
3003 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3004 | /****************************/ | |
3005 | /* Deactivates all interrupts */ | |
3006 | /******************************/ | |
3007 | outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3008 | /*****************************************************/ | |
3009 | /* Selects the command and status register of port B */ | |
3010 | /*****************************************************/ | |
3011 | outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, | |
3012 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3013 | /****************************/ | |
3014 | /* Deactivates all interrupts */ | |
3015 | /******************************/ | |
3016 | outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3017 | /*****************************************************/ | |
3018 | /* Selects the command and status register of timer 1 */ | |
3019 | /*****************************************************/ | |
3020 | outb(APCI1500_RW_CPT_TMR1_CMD_STATUS, | |
3021 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3022 | /****************************/ | |
3023 | /* Deactivates all interrupts */ | |
3024 | /******************************/ | |
3025 | outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3026 | /*****************************************************/ | |
3027 | /* Selects the command and status register of timer 2 */ | |
3028 | /*****************************************************/ | |
3029 | outb(APCI1500_RW_CPT_TMR2_CMD_STATUS, | |
3030 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3031 | /****************************/ | |
3032 | /* Deactivates all interrupts */ | |
3033 | /******************************/ | |
3034 | outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3035 | /*****************************************************/ | |
3036 | /* Selects the command and status register of timer 3*/ | |
3037 | /*****************************************************/ | |
3038 | outb(APCI1500_RW_CPT_TMR3_CMD_STATUS, | |
3039 | devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3040 | /****************************/ | |
3041 | /* Deactivates all interrupts */ | |
3042 | /******************************/ | |
3043 | outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER); | |
3044 | return 0; | |
3045 | } |