Staging: comedi: Remove comedi_subdevice typedef
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci3501.c
CommitLineData
c995fe94
ADG
1/**
2@verbatim
3
4Copyright (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
14This 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
16This 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
18You 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
20You 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 76INT 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 124int 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 164INT 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 251INT 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 301INT 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 339INT 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 413INT 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 514int 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 616int 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 657int 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*/
708void 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}