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 | ||
6 | ADDI-DATA GmbH | |
7 | Dieselstrasse 3 | |
8 | D-77833 Ottersweier | |
9 | Tel: +19(0)7223/9493-0 | |
10 | Fax: +49(0)7223/9493-92 | |
11 | http://www.addi-data-com | |
12 | info@addi-data.com | |
13 | ||
14 | This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. | |
15 | ||
16 | This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 | ||
20 | You shoud also find the complete GPL in the COPYING file accompanying this source code. | |
21 | ||
22 | @endverbatim | |
23 | */ | |
24 | /*. | |
25 | ||
26 | +-----------------------------------------------------------------------+ | |
27 | | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | | |
28 | +-----------------------------------------------------------------------+ | |
29 | | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | | |
30 | | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | | |
31 | +-------------------------------+---------------------------------------+ | |
32 | | Project : APCI-3501 | Compiler : GCC | | |
33 | | Module name : hwdrv_apci3501.c| Version : 2.96 | | |
34 | +-------------------------------+---------------------------------------+ | |
35 | | Project manager: Eric Stolz | Date : 02/12/2002 | | |
36 | +-------------------------------+---------------------------------------+ | |
37 | | Description : Hardware Layer Acces For APCI-3501 | | |
38 | +-----------------------------------------------------------------------+ | |
39 | | UPDATES | | |
40 | +----------+-----------+------------------------------------------------+ | |
41 | | Date | Author | Description of updates | | |
42 | +----------+-----------+------------------------------------------------+ | |
43 | | | | | | |
44 | | | | | | |
45 | | | | | | |
46 | +----------+-----------+------------------------------------------------+ | |
47 | */ | |
48 | ||
49 | /* | |
50 | +----------------------------------------------------------------------------+ | |
51 | | Included files | | |
52 | +----------------------------------------------------------------------------+ | |
53 | */ | |
54 | #include "hwdrv_apci3501.h" | |
55 | ||
56 | /* | |
57 | +----------------------------------------------------------------------------+ | |
58 | | Function Name : int i_APCI3501_ReadDigitalInput | | |
34c43922 | 59 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
790c5541 | 60 | | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
61 | +----------------------------------------------------------------------------+ |
62 | | Task : Read value of the selected channel or port | | |
63 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 64 | | Input Parameters : struct comedi_device *dev : Driver handle | |
c995fe94 ADG |
65 | | UINT ui_NoOfChannels : No Of Channels To read | |
66 | | UINT *data : Data Pointer to read status | | |
67 | +----------------------------------------------------------------------------+ | |
68 | | Output Parameters : -- | | |
69 | +----------------------------------------------------------------------------+ | |
70 | | Return Value : TRUE : No error occur | | |
71 | | : FALSE : Error occur. Return the error | | |
72 | | | | |
73 | +----------------------------------------------------------------------------+ | |
74 | */ | |
75 | ||
34c43922 | 76 | INT i_APCI3501_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s, |
790c5541 | 77 | comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
78 | { |
79 | UINT ui_Temp; | |
80 | UINT ui_NoOfChannel; | |
81 | ui_NoOfChannel = CR_CHAN(insn->chanspec); | |
82 | ui_Temp = data[0]; | |
83 | *data = inl(devpriv->iobase + APCI3501_DIGITAL_IP); | |
84 | if (ui_Temp == 0) { | |
85 | *data = (*data >> ui_NoOfChannel) & 0x1; | |
86 | } //if (ui_Temp==0) | |
87 | else { | |
88 | if (ui_Temp == 1) { | |
89 | ||
90 | *data = *data & 0x3; | |
91 | } //if (ui_Temp==1) | |
92 | else { | |
93 | printk("\nSpecified channel not supported \n"); | |
94 | } //elseif (ui_Temp==1) | |
95 | } //elseif (ui_Temp==0) | |
96 | return insn->n; | |
97 | } | |
98 | ||
99 | /* | |
100 | +----------------------------------------------------------------------------+ | |
101 | | Function Name : int i_APCI3501_ConfigDigitalOutput | | |
34c43922 | 102 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
790c5541 | 103 | | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
104 | +----------------------------------------------------------------------------+ |
105 | | Task : Configures The Digital Output Subdevice. | | |
106 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 107 | | Input Parameters : struct comedi_device *dev : Driver handle | |
c995fe94 ADG |
108 | | UINT *data : Data Pointer contains | |
109 | | configuration parameters as below | | |
110 | | | | |
111 | | data[1] : 1 Enable VCC Interrupt | | |
112 | | 0 Disable VCC Interrupt | | |
113 | | data[2] : 1 Enable CC Interrupt | | |
114 | | 0 Disable CC Interrupt | | |
115 | | | | |
116 | +----------------------------------------------------------------------------+ | |
117 | | Output Parameters : -- | | |
118 | +----------------------------------------------------------------------------+ | |
119 | | Return Value : TRUE : No error occur | | |
120 | | : FALSE : Error occur. Return the error | | |
121 | | | | |
122 | +----------------------------------------------------------------------------+ | |
123 | */ | |
34c43922 | 124 | int i_APCI3501_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s, |
790c5541 | 125 | comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
126 | { |
127 | ||
128 | if ((data[0] != 0) && (data[0] != 1)) { | |
129 | comedi_error(dev, | |
130 | "Not a valid Data !!! ,Data should be 1 or 0\n"); | |
131 | return -EINVAL; | |
132 | } //if ( (data[0]!=0) && (data[0]!=1) ) | |
133 | if (data[0]) { | |
134 | devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; | |
135 | } // if (data[0]) | |
136 | else { | |
137 | devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; | |
138 | } //else if (data[0]) | |
139 | return insn->n; | |
140 | } | |
141 | ||
142 | /* | |
143 | +----------------------------------------------------------------------------+ | |
144 | | Function Name : int i_APCI3501_WriteDigitalOutput | | |
34c43922 | 145 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
790c5541 | 146 | | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
147 | +----------------------------------------------------------------------------+ |
148 | | Task : writes To the digital Output Subdevice | | |
149 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 150 | | Input Parameters : struct comedi_device *dev : Driver handle | |
34c43922 | 151 | | struct comedi_subdevice *s : Subdevice Pointer | |
c995fe94 | 152 | | comedi_insn *insn : Insn Structure Pointer | |
790c5541 | 153 | | unsigned int *data : Data Pointer contains | |
c995fe94 ADG |
154 | | configuration parameters as below | |
155 | | | | |
156 | +----------------------------------------------------------------------------+ | |
157 | | Output Parameters : -- | | |
158 | +----------------------------------------------------------------------------+ | |
159 | | Return Value : TRUE : No error occur | | |
160 | | : FALSE : Error occur. Return the error | | |
161 | | | | |
162 | +----------------------------------------------------------------------------+ | |
163 | */ | |
34c43922 | 164 | INT i_APCI3501_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s, |
790c5541 | 165 | comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
166 | { |
167 | UINT ui_Temp, ui_Temp1; | |
168 | UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel | |
169 | if (devpriv->b_OutputMemoryStatus) { | |
170 | ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP); | |
171 | } //if(devpriv->b_OutputMemoryStatus ) | |
172 | else { | |
173 | ui_Temp = 0; | |
174 | } //if(devpriv->b_OutputMemoryStatus ) | |
175 | if (data[3] == 0) { | |
176 | if (data[1] == 0) { | |
177 | data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; | |
178 | outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP); | |
179 | } //if(data[1]==0) | |
180 | else { | |
181 | if (data[1] == 1) { | |
182 | data[0] = (data[0] << (2 * data[2])) | ui_Temp; | |
183 | outl(data[0], | |
184 | devpriv->iobase + APCI3501_DIGITAL_OP); | |
185 | } // if(data[1]==1) | |
186 | else { | |
187 | printk("\nSpecified channel not supported\n"); | |
188 | } //else if(data[1]==1) | |
189 | } //elseif(data[1]==0) | |
190 | } //if(data[3]==0) | |
191 | else { | |
192 | if (data[3] == 1) { | |
193 | if (data[1] == 0) { | |
194 | data[0] = ~data[0] & 0x1; | |
195 | ui_Temp1 = 1; | |
196 | ui_Temp1 = ui_Temp1 << ui_NoOfChannel; | |
197 | ui_Temp = ui_Temp | ui_Temp1; | |
198 | data[0] = | |
199 | (data[0] << ui_NoOfChannel) ^ | |
200 | 0xffffffff; | |
201 | data[0] = data[0] & ui_Temp; | |
202 | outl(data[0], | |
203 | devpriv->iobase + APCI3501_DIGITAL_OP); | |
204 | } //if(data[1]==0) | |
205 | else { | |
206 | if (data[1] == 1) { | |
207 | data[0] = ~data[0] & 0x3; | |
208 | ui_Temp1 = 3; | |
209 | ui_Temp1 = ui_Temp1 << 2 * data[2]; | |
210 | ui_Temp = ui_Temp | ui_Temp1; | |
211 | data[0] = | |
212 | ((data[0] << (2 * | |
213 | data[2])) ^ | |
214 | 0xffffffff) & ui_Temp; | |
215 | outl(data[0], | |
216 | devpriv->iobase + | |
217 | APCI3501_DIGITAL_OP); | |
218 | } // if(data[1]==1) | |
219 | else { | |
220 | printk("\nSpecified channel not supported\n"); | |
221 | } //else if(data[1]==1) | |
222 | } //elseif(data[1]==0) | |
223 | } //if(data[3]==1); | |
224 | else { | |
225 | printk("\nSpecified functionality does not exist\n"); | |
226 | return -EINVAL; | |
227 | } //if else data[3]==1) | |
228 | } //if else data[3]==0) | |
229 | return insn->n; | |
230 | } | |
231 | ||
232 | /* | |
233 | +----------------------------------------------------------------------------+ | |
234 | | Function Name : int i_APCI3501_ReadDigitalOutput | | |
34c43922 | 235 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
790c5541 | 236 | | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
237 | +----------------------------------------------------------------------------+ |
238 | | Task : Read value of the selected channel or port | | |
239 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 240 | | Input Parameters : struct comedi_device *dev : Driver handle | |
c995fe94 ADG |
241 | | UINT ui_NoOfChannels : No Of Channels To read | |
242 | | UINT *data : Data Pointer to read status | | |
243 | +----------------------------------------------------------------------------+ | |
244 | | Output Parameters : -- | | |
245 | +----------------------------------------------------------------------------+ | |
246 | | Return Value : TRUE : No error occur | | |
247 | | : FALSE : Error occur. Return the error | | |
248 | | | | |
249 | +----------------------------------------------------------------------------+ | |
250 | */ | |
34c43922 | 251 | INT i_APCI3501_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s, |
790c5541 | 252 | comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
253 | { |
254 | UINT ui_Temp; | |
255 | UINT ui_NoOfChannel; | |
256 | ||
257 | ui_NoOfChannel = CR_CHAN(insn->chanspec); | |
258 | ui_Temp = data[0]; | |
259 | *data = inl(devpriv->iobase + APCI3501_DIGITAL_OP); | |
260 | if (ui_Temp == 0) { | |
261 | *data = (*data >> ui_NoOfChannel) & 0x1; | |
262 | } // if (ui_Temp==0) | |
263 | else { | |
264 | if (ui_Temp == 1) { | |
265 | *data = *data & 0x3; | |
266 | ||
267 | } // if (ui_Temp==1) | |
268 | else { | |
269 | printk("\nSpecified channel not supported \n"); | |
270 | } // else if (ui_Temp==1) | |
271 | } // else if (ui_Temp==0) | |
272 | return insn->n; | |
273 | } | |
274 | ||
275 | /* | |
276 | +----------------------------------------------------------------------------+ | |
277 | | Function Name : int i_APCI3501_ConfigAnalogOutput | | |
34c43922 | 278 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
790c5541 | 279 | | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
280 | +----------------------------------------------------------------------------+ |
281 | | Task : Configures The Analog Output Subdevice | | |
282 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 283 | | Input Parameters : struct comedi_device *dev : Driver handle | |
34c43922 | 284 | | struct comedi_subdevice *s : Subdevice Pointer | |
c995fe94 | 285 | | comedi_insn *insn : Insn Structure Pointer | |
790c5541 | 286 | | unsigned int *data : Data Pointer contains | |
c995fe94 ADG |
287 | | configuration parameters as below | |
288 | | | | |
289 | | data[0] : Voltage Mode | | |
290 | | 0:Mode 0 | | |
291 | | 1:Mode 1 | | |
292 | | | | |
293 | +----------------------------------------------------------------------------+ | |
294 | | Output Parameters : -- | | |
295 | +----------------------------------------------------------------------------+ | |
296 | | Return Value : TRUE : No error occur | | |
297 | | : FALSE : Error occur. Return the error | | |
298 | | | | |
299 | +----------------------------------------------------------------------------+ | |
300 | */ | |
34c43922 | 301 | INT i_APCI3501_ConfigAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s, |
790c5541 | 302 | comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
303 | { |
304 | outl(data[0], | |
305 | devpriv->iobase + APCI3501_ANALOG_OUTPUT + | |
306 | APCI3501_AO_VOLT_MODE); | |
307 | ||
308 | if (data[0]) { | |
309 | devpriv->b_InterruptMode = MODE1; | |
310 | } else { | |
311 | devpriv->b_InterruptMode = MODE0; | |
312 | } | |
313 | return insn->n; | |
314 | } | |
315 | ||
316 | /* | |
317 | +----------------------------------------------------------------------------+ | |
318 | | Function Name : int i_APCI3501_WriteAnalogOutput | | |
34c43922 | 319 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
790c5541 | 320 | | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
321 | +----------------------------------------------------------------------------+ |
322 | | Task : Writes To the Selected Anlog Output Channel | | |
323 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 324 | | Input Parameters : struct comedi_device *dev : Driver handle | |
34c43922 | 325 | | struct comedi_subdevice *s : Subdevice Pointer | |
c995fe94 | 326 | | comedi_insn *insn : Insn Structure Pointer | |
790c5541 | 327 | | unsigned int *data : Data Pointer contains | |
c995fe94 ADG |
328 | | configuration parameters as below | |
329 | | | | |
330 | | | | |
331 | +----------------------------------------------------------------------------+ | |
332 | | Output Parameters : -- | | |
333 | +----------------------------------------------------------------------------+ | |
334 | | Return Value : TRUE : No error occur | | |
335 | | : FALSE : Error occur. Return the error | | |
336 | | | | |
337 | +----------------------------------------------------------------------------+ | |
338 | */ | |
34c43922 | 339 | INT i_APCI3501_WriteAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s, |
790c5541 | 340 | comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
341 | { |
342 | ULONG ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0;; | |
343 | ||
344 | ul_Channel_no = CR_CHAN(insn->chanspec); | |
345 | ||
346 | if (devpriv->b_InterruptMode == MODE1) { | |
347 | ul_Polarity = 0x80000000; | |
348 | if ((*data < 0) || (*data > 16384)) { | |
349 | printk("\nIn WriteAnalogOutput :: Not Valid Data\n"); | |
350 | } | |
351 | ||
352 | } // end if(devpriv->b_InterruptMode==MODE1) | |
353 | else { | |
354 | ul_Polarity = 0; | |
355 | if ((*data < 0) || (*data > 8192)) { | |
356 | printk("\nIn WriteAnalogOutput :: Not Valid Data\n"); | |
357 | } | |
358 | ||
359 | } // end else | |
360 | ||
361 | if ((ul_Channel_no < 0) || (ul_Channel_no > 7)) { | |
362 | printk("\nIn WriteAnalogOutput :: Not Valid Channel\n"); | |
363 | } // end if((ul_Channel_no<0)||(ul_Channel_no>7)) | |
364 | ||
365 | ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT); | |
366 | ||
367 | while (ul_DAC_Ready == 0) { | |
368 | ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT); | |
369 | ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1; | |
370 | } | |
371 | ||
372 | if (ul_DAC_Ready) { | |
373 | // Output the Value on the output channels. | |
374 | ul_Command1 = | |
375 | (ULONG) ((ULONG) (ul_Channel_no & 0xFF) | | |
376 | (ULONG) ((*data << 0x8) & 0x7FFFFF00L) | | |
377 | (ULONG) (ul_Polarity)); | |
378 | outl(ul_Command1, | |
379 | devpriv->iobase + APCI3501_ANALOG_OUTPUT + | |
380 | APCI3501_AO_PROG); | |
381 | } | |
382 | ||
383 | return insn->n; | |
384 | } | |
385 | ||
386 | /* | |
387 | +----------------------------------------------------------------------------+ | |
388 | | Function Name : int i_APCI3501_ConfigTimerCounterWatchdog | | |
34c43922 | 389 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
790c5541 | 390 | | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
391 | +----------------------------------------------------------------------------+ |
392 | | Task : Configures The Timer , Counter or Watchdog | | |
393 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 394 | | Input Parameters : struct comedi_device *dev : Driver handle | |
c995fe94 ADG |
395 | | UINT *data : Data Pointer contains | |
396 | | configuration parameters as below | | |
397 | | | | |
398 | | data[0] : 0 Configure As Timer | | |
399 | | 1 Configure As Counter | | |
400 | | 2 Configure As Watchdog | | |
401 | | data[1] : 1 Enable Interrupt | | |
402 | | 0 Disable Interrupt | | |
403 | | data[2] : Time Unit | | |
404 | | data[3] : Reload Value | | |
405 | +----------------------------------------------------------------------------+ | |
406 | | Output Parameters : -- | | |
407 | +----------------------------------------------------------------------------+ | |
408 | | Return Value : TRUE : No error occur | | |
409 | | : FALSE : Error occur. Return the error | | |
410 | | | | |
411 | +----------------------------------------------------------------------------+ | |
412 | */ | |
71b5f4f1 | 413 | INT i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device * dev, |
34c43922 | 414 | struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
415 | { |
416 | ULONG ul_Command1 = 0; | |
417 | devpriv->tsk_Current = current; | |
418 | if (data[0] == ADDIDATA_WATCHDOG) { | |
419 | ||
420 | devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG; | |
421 | //Disable the watchdog | |
422 | outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Wa | |
423 | ||
424 | if (data[1] == 1) { | |
425 | //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES | |
426 | outl(0x02, | |
427 | devpriv->iobase + APCI3501_WATCHDOG + | |
428 | APCI3501_TCW_PROG); | |
429 | } else { | |
430 | outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt | |
431 | } | |
432 | ||
433 | //Loading the Timebase value | |
434 | outl(data[2], | |
435 | devpriv->iobase + APCI3501_WATCHDOG + | |
436 | APCI3501_TCW_TIMEBASE); | |
437 | ||
438 | //Loading the Reload value | |
439 | outl(data[3], | |
440 | devpriv->iobase + APCI3501_WATCHDOG + | |
441 | APCI3501_TCW_RELOAD_VALUE); | |
442 | //Set the mode | |
443 | ul_Command1 = inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG) | 0xFFF819E0UL; //e2->e0 | |
444 | outl(ul_Command1, | |
445 | devpriv->iobase + APCI3501_WATCHDOG + | |
446 | APCI3501_TCW_PROG); | |
447 | } //end if(data[0]==ADDIDATA_WATCHDOG) | |
448 | ||
449 | else if (data[0] == ADDIDATA_TIMER) { | |
450 | //First Stop The Timer | |
451 | ul_Command1 = | |
452 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
453 | APCI3501_TCW_PROG); | |
454 | ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; | |
455 | outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //Stop The Timer | |
456 | devpriv->b_TimerSelectMode = ADDIDATA_TIMER; | |
457 | if (data[1] == 1) { | |
458 | //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES | |
459 | outl(0x02, | |
460 | devpriv->iobase + APCI3501_WATCHDOG + | |
461 | APCI3501_TCW_PROG); | |
462 | } else { | |
463 | outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt | |
464 | } | |
465 | ||
466 | // Loading Timebase | |
467 | outl(data[2], | |
468 | devpriv->iobase + APCI3501_WATCHDOG + | |
469 | APCI3501_TCW_TIMEBASE); | |
470 | ||
471 | //Loading the Reload value | |
472 | outl(data[3], | |
473 | devpriv->iobase + APCI3501_WATCHDOG + | |
474 | APCI3501_TCW_RELOAD_VALUE); | |
475 | ||
476 | // printk ("\nTimer Address :: %x\n", (devpriv->iobase+APCI3501_WATCHDOG)); | |
477 | ul_Command1 = | |
478 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
479 | APCI3501_TCW_PROG); | |
480 | ul_Command1 = | |
481 | (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL; | |
482 | outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //mode 2 | |
483 | ||
484 | } //end if(data[0]==ADDIDATA_TIMER) | |
485 | ||
486 | return insn->n; | |
487 | } | |
488 | ||
489 | /* | |
490 | +----------------------------------------------------------------------------+ | |
491 | | Function Name : int i_APCI3501_StartStopWriteTimerCounterWatchdog | | |
34c43922 | 492 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
790c5541 | 493 | | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
494 | +----------------------------------------------------------------------------+ |
495 | | Task : Start / Stop The Selected Timer , Counter or Watchdog | | |
496 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 497 | | Input Parameters : struct comedi_device *dev : Driver handle | |
c995fe94 ADG |
498 | | UINT *data : Data Pointer contains | |
499 | | configuration parameters as below | | |
500 | | | | |
501 | | data[0] : 0 Timer | | |
502 | | 1 Counter | | |
503 | | 2 Watchdog | | data[1] : 1 Start | | |
504 | | 0 Stop | 2 Trigger | | |
505 | +----------------------------------------------------------------------------+ | |
506 | | Output Parameters : -- | | |
507 | +----------------------------------------------------------------------------+ | |
508 | | Return Value : TRUE : No error occur | | |
509 | | : FALSE : Error occur. Return the error | | |
510 | | | | |
511 | +----------------------------------------------------------------------------+ | |
512 | */ | |
513 | ||
71b5f4f1 | 514 | int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev, |
34c43922 | 515 | struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
516 | { |
517 | ULONG ul_Command1 = 0; | |
518 | int i_Temp; | |
519 | if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { | |
520 | ||
521 | if (data[1] == 1) { | |
522 | ul_Command1 = | |
523 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
524 | APCI3501_TCW_PROG); | |
525 | ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; | |
526 | //Enable the Watchdog | |
527 | outl(ul_Command1, | |
528 | devpriv->iobase + APCI3501_WATCHDOG + | |
529 | APCI3501_TCW_PROG); | |
530 | } | |
531 | ||
532 | else if (data[1] == 0) //Stop The Watchdog | |
533 | { | |
534 | //Stop The Watchdog | |
535 | ul_Command1 = | |
536 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
537 | APCI3501_TCW_PROG); | |
538 | ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; | |
539 | outl(0x0, | |
540 | devpriv->iobase + APCI3501_WATCHDOG + | |
541 | APCI3501_TCW_PROG); | |
542 | } else if (data[1] == 2) { | |
543 | ul_Command1 = | |
544 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
545 | APCI3501_TCW_PROG); | |
546 | ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL; | |
547 | outl(ul_Command1, | |
548 | devpriv->iobase + APCI3501_WATCHDOG + | |
549 | APCI3501_TCW_PROG); | |
550 | } //if(data[1]==2) | |
551 | } // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG) | |
552 | ||
553 | if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) { | |
554 | if (data[1] == 1) { | |
555 | ||
556 | ul_Command1 = | |
557 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
558 | APCI3501_TCW_PROG); | |
559 | ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL; | |
560 | //Enable the Timer | |
561 | outl(ul_Command1, | |
562 | devpriv->iobase + APCI3501_WATCHDOG + | |
563 | APCI3501_TCW_PROG); | |
564 | } else if (data[1] == 0) { | |
565 | //Stop The Timer | |
566 | ul_Command1 = | |
567 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
568 | APCI3501_TCW_PROG); | |
569 | ul_Command1 = ul_Command1 & 0xFFFFF9FEUL; | |
570 | outl(ul_Command1, | |
571 | devpriv->iobase + APCI3501_WATCHDOG + | |
572 | APCI3501_TCW_PROG); | |
573 | } | |
574 | ||
575 | else if (data[1] == 2) { | |
576 | //Trigger the Timer | |
577 | ul_Command1 = | |
578 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
579 | APCI3501_TCW_PROG); | |
580 | ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL; | |
581 | outl(ul_Command1, | |
582 | devpriv->iobase + APCI3501_WATCHDOG + | |
583 | APCI3501_TCW_PROG); | |
584 | } | |
585 | ||
586 | } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) | |
587 | i_Temp = inl(devpriv->iobase + APCI3501_WATCHDOG + | |
588 | APCI3501_TCW_TRIG_STATUS) & 0x1; | |
589 | return insn->n; | |
590 | } | |
591 | ||
592 | /* | |
593 | +----------------------------------------------------------------------------+ | |
594 | | Function Name : int i_APCI3501_ReadTimerCounterWatchdog | | |
34c43922 | 595 | | (struct comedi_device *dev,struct comedi_subdevice *s, | |
790c5541 | 596 | | comedi_insn *insn,unsigned int *data) | |
c995fe94 ADG |
597 | +----------------------------------------------------------------------------+ |
598 | | Task : Read The Selected Timer , Counter or Watchdog | | |
599 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 600 | | Input Parameters : struct comedi_device *dev : Driver handle | |
c995fe94 ADG |
601 | | UINT *data : Data Pointer contains | |
602 | | configuration parameters as below | | |
603 | | | | |
604 | | data[0] : 0 Timer | | |
605 | | 1 Counter | | |
606 | | 2 Watchdog | | data[1] : Timer Counter Watchdog Number | | |
607 | +----------------------------------------------------------------------------+ | |
608 | | Output Parameters : -- | | |
609 | +----------------------------------------------------------------------------+ | |
610 | | Return Value : TRUE : No error occur | | |
611 | | : FALSE : Error occur. Return the error | | |
612 | | | | |
613 | +----------------------------------------------------------------------------+ | |
614 | */ | |
615 | ||
71b5f4f1 | 616 | int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device * dev, |
34c43922 | 617 | struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data) |
c995fe94 ADG |
618 | { |
619 | ||
620 | if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) { | |
621 | data[0] = | |
622 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
623 | APCI3501_TCW_TRIG_STATUS) & 0x1; | |
624 | data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG); | |
625 | } // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG) | |
626 | ||
627 | else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) { | |
628 | data[0] = | |
629 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
630 | APCI3501_TCW_TRIG_STATUS) & 0x1; | |
631 | data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG); | |
632 | } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) | |
633 | ||
634 | else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER) | |
635 | && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)) { | |
636 | printk("\nIn ReadTimerCounterWatchdog :: Invalid Subdevice \n"); | |
637 | } | |
638 | return insn->n; | |
639 | } | |
640 | ||
641 | /* | |
642 | +----------------------------------------------------------------------------+ | |
71b5f4f1 | 643 | | Function Name : int i_APCI3501_Reset(struct comedi_device *dev) | |
c995fe94 ADG |
644 | | | |
645 | +----------------------------------------------------------------------------+ | |
646 | | Task :Resets the registers of the card | | |
647 | +----------------------------------------------------------------------------+ | |
648 | | Input Parameters : | | |
649 | +----------------------------------------------------------------------------+ | |
650 | | Output Parameters : -- | | |
651 | +----------------------------------------------------------------------------+ | |
652 | | Return Value : | | |
653 | | | | |
654 | +----------------------------------------------------------------------------+ | |
655 | */ | |
656 | ||
71b5f4f1 | 657 | int i_APCI3501_Reset(struct comedi_device * dev) |
c995fe94 ADG |
658 | { |
659 | int i_Count = 0, i_temp = 0; | |
660 | ULONG ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0; | |
661 | outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP); | |
662 | outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT + | |
663 | APCI3501_AO_VOLT_MODE); | |
664 | ||
665 | ul_Polarity = 0x80000000; | |
666 | ||
667 | for (i_Count = 0; i_Count <= 7; i_Count++) { | |
668 | ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT); | |
669 | ||
670 | while (ul_DAC_Ready == 0) { | |
671 | ul_DAC_Ready = | |
672 | inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT); | |
673 | ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1; | |
674 | } | |
675 | ||
676 | if (ul_DAC_Ready) { | |
677 | // Output the Value on the output channels. | |
678 | ul_Command1 = | |
679 | (ULONG) ((ULONG) (i_Count & 0xFF) | | |
680 | (ULONG) ((i_temp << 0x8) & 0x7FFFFF00L) | | |
681 | (ULONG) (ul_Polarity)); | |
682 | outl(ul_Command1, | |
683 | devpriv->iobase + APCI3501_ANALOG_OUTPUT + | |
684 | APCI3501_AO_PROG); | |
685 | } | |
686 | } | |
687 | ||
688 | return 0; | |
689 | } | |
690 | ||
691 | /* | |
692 | +----------------------------------------------------------------------------+ | |
693 | | Function Name : static void v_APCI3501_Interrupt | | |
694 | | (int irq , void *d) | | |
695 | +----------------------------------------------------------------------------+ | |
696 | | Task : Interrupt processing Routine | | |
697 | +----------------------------------------------------------------------------+ | |
698 | | Input Parameters : int irq : irq number | | |
699 | | void *d : void pointer | | |
700 | +----------------------------------------------------------------------------+ | |
701 | | Output Parameters : -- | | |
702 | +----------------------------------------------------------------------------+ | |
703 | | Return Value : TRUE : No error occur | | |
704 | | : FALSE : Error occur. Return the error | | |
705 | | | | |
706 | +----------------------------------------------------------------------------+ | |
707 | */ | |
708 | void v_APCI3501_Interrupt(int irq, void *d) | |
709 | { | |
710 | int i_temp; | |
71b5f4f1 | 711 | struct comedi_device *dev = d; |
c995fe94 ADG |
712 | unsigned int ui_Timer_AOWatchdog; |
713 | unsigned long ul_Command1; | |
714 | // Disable Interrupt | |
715 | ul_Command1 = | |
716 | inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); | |
717 | ||
718 | ul_Command1 = (ul_Command1 & 0xFFFFF9FDul); | |
719 | outl(ul_Command1, | |
720 | devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); | |
721 | ||
722 | ui_Timer_AOWatchdog = | |
723 | inl(devpriv->iobase + APCI3501_WATCHDOG + | |
724 | APCI3501_TCW_IRQ) & 0x1; | |
725 | ||
726 | if ((!ui_Timer_AOWatchdog)) { | |
727 | comedi_error(dev, "IRQ from unknow source"); | |
728 | return; | |
729 | } | |
730 | ||
731 | // Enable Interrupt | |
732 | //Send a signal to from kernel to user space | |
733 | send_sig(SIGIO, devpriv->tsk_Current, 0); | |
734 | ul_Command1 = | |
735 | inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); | |
736 | ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1); | |
737 | outl(ul_Command1, | |
738 | devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); | |
739 | i_temp = inl(devpriv->iobase + APCI3501_WATCHDOG + | |
740 | APCI3501_TCW_TRIG_STATUS) & 0x1; | |
741 | return; | |
742 | } |