Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hwdrv_apci3501.c
Go to the documentation of this file.
1 
24 /*.
25 
26  +-----------------------------------------------------------------------+
27  | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28  +-----------------------------------------------------------------------+
29  | Tel : +49 (0) 7223/9493-0 | email : [email protected] |
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 Access 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 |
59 | (struct comedi_device *dev,struct comedi_subdevice *s, |
60 | struct comedi_insn *insn,unsigned int *data) |
61 +----------------------------------------------------------------------------+
62 | Task : Read value of the selected channel or port |
63 +----------------------------------------------------------------------------+
64 | Input Parameters : struct comedi_device *dev : Driver handle |
65 | unsigned int ui_NoOfChannels : No Of Channels To read |
66 | unsigned int *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 
77  struct comedi_insn *insn, unsigned int *data)
78 {
79  unsigned int ui_Temp;
80  unsigned int 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 |
102 | (struct comedi_device *dev,struct comedi_subdevice *s, |
103 | struct comedi_insn *insn,unsigned int *data) |
104 +----------------------------------------------------------------------------+
105 | Task : Configures The Digital Output Subdevice. |
106 +----------------------------------------------------------------------------+
107 | Input Parameters : struct comedi_device *dev : Driver handle |
108 | unsigned int *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 */
125  struct comedi_insn *insn, unsigned int *data)
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 |
145 | (struct comedi_device *dev,struct comedi_subdevice *s, |
146 | struct comedi_insn *insn,unsigned int *data) |
147 +----------------------------------------------------------------------------+
148 | Task : writes To the digital Output Subdevice |
149 +----------------------------------------------------------------------------+
150 | Input Parameters : struct comedi_device *dev : Driver handle |
151 | struct comedi_subdevice *s : Subdevice Pointer |
152 | struct comedi_insn *insn : Insn Structure Pointer |
153 | unsigned int *data : Data Pointer contains |
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 */
165  struct comedi_insn *insn, unsigned int *data)
166 {
167  unsigned int ui_Temp, ui_Temp1;
168  unsigned int 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 +
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 |
235 | (struct comedi_device *dev,struct comedi_subdevice *s, |
236 | struct comedi_insn *insn,unsigned int *data) |
237 +----------------------------------------------------------------------------+
238 | Task : Read value of the selected channel or port |
239 +----------------------------------------------------------------------------+
240 | Input Parameters : struct comedi_device *dev : Driver handle |
241 | unsigned int ui_NoOfChannels : No Of Channels To read |
242 | unsigned int *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 */
252  struct comedi_insn *insn, unsigned int *data)
253 {
254  unsigned int ui_Temp;
255  unsigned int 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 |
278 | (struct comedi_device *dev,struct comedi_subdevice *s, |
279 | struct comedi_insn *insn,unsigned int *data) |
280 +----------------------------------------------------------------------------+
281 | Task : Configures The Analog Output Subdevice |
282 +----------------------------------------------------------------------------+
283 | Input Parameters : struct comedi_device *dev : Driver handle |
284 | struct comedi_subdevice *s : Subdevice Pointer |
285 | struct comedi_insn *insn : Insn Structure Pointer |
286 | unsigned int *data : Data Pointer contains |
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 */
302  struct comedi_insn *insn, unsigned int *data)
303 {
304  outl(data[0],
305  devpriv->iobase + APCI3501_ANALOG_OUTPUT +
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 |
319 | (struct comedi_device *dev,struct comedi_subdevice *s, |
320 | struct comedi_insn *insn,unsigned int *data) |
321 +----------------------------------------------------------------------------+
322 | Task : Writes To the Selected Anlog Output Channel |
323 +----------------------------------------------------------------------------+
324 | Input Parameters : struct comedi_device *dev : Driver handle |
325 | struct comedi_subdevice *s : Subdevice Pointer |
326 | struct comedi_insn *insn : Insn Structure Pointer |
327 | unsigned int *data : Data Pointer contains |
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 */
340  struct comedi_insn *insn, unsigned int *data)
341 {
342  unsigned int 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  (unsigned int) ((unsigned int) (ul_Channel_no & 0xFF) |
376  (unsigned int) ((*data << 0x8) & 0x7FFFFF00L) |
377  (unsigned int) (ul_Polarity));
378  outl(ul_Command1,
379  devpriv->iobase + APCI3501_ANALOG_OUTPUT +
381  }
382 
383  return insn->n;
384 }
385 
386 /*
387 +----------------------------------------------------------------------------+
388 | Function Name : int i_APCI3501_ConfigTimerCounterWatchdog |
389 | (struct comedi_device *dev,struct comedi_subdevice *s, |
390 | struct comedi_insn *insn,unsigned int *data) |
391 +----------------------------------------------------------------------------+
392 | Task : Configures The Timer , Counter or Watchdog |
393 +----------------------------------------------------------------------------+
394 | Input Parameters : struct comedi_device *dev : Driver handle |
395 | unsigned int *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 */
414  struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
415 {
416  unsigned int 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 +
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 +
437 
438  /* Loading the Reload value */
439  outl(data[3],
440  devpriv->iobase + APCI3501_WATCHDOG +
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 +
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 +
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 +
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 +
470 
471  /* Loading the Reload value */
472  outl(data[3],
473  devpriv->iobase + APCI3501_WATCHDOG +
475 
476  /* printk ("\nTimer Address :: %x\n", (devpriv->iobase+APCI3501_WATCHDOG)); */
477  ul_Command1 =
478  inl(devpriv->iobase + APCI3501_WATCHDOG +
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 |
492 | (struct comedi_device *dev,struct comedi_subdevice *s, |
493 | struct comedi_insn *insn,unsigned int *data) |
494 +----------------------------------------------------------------------------+
495 | Task : Start / Stop The Selected Timer , Counter or Watchdog |
496 +----------------------------------------------------------------------------+
497 | Input Parameters : struct comedi_device *dev : Driver handle |
498 | unsigned int *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 
515  struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
516 {
517  unsigned int 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 +
525  ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
526  /* Enable the Watchdog */
527  outl(ul_Command1,
528  devpriv->iobase + APCI3501_WATCHDOG +
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 +
538  ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
539  outl(0x0,
540  devpriv->iobase + APCI3501_WATCHDOG +
542  } else if (data[1] == 2) {
543  ul_Command1 =
544  inl(devpriv->iobase + APCI3501_WATCHDOG +
546  ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
547  outl(ul_Command1,
548  devpriv->iobase + APCI3501_WATCHDOG +
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 +
559  ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
560  /* Enable the Timer */
561  outl(ul_Command1,
562  devpriv->iobase + APCI3501_WATCHDOG +
564  } else if (data[1] == 0) {
565  /* Stop The Timer */
566  ul_Command1 =
567  inl(devpriv->iobase + APCI3501_WATCHDOG +
569  ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
570  outl(ul_Command1,
571  devpriv->iobase + APCI3501_WATCHDOG +
573  }
574 
575  else if (data[1] == 2) {
576  /* Trigger the Timer */
577  ul_Command1 =
578  inl(devpriv->iobase + APCI3501_WATCHDOG +
580  ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
581  outl(ul_Command1,
582  devpriv->iobase + APCI3501_WATCHDOG +
584  }
585 
586  } /* end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) */
587  i_Temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
589  return insn->n;
590 }
591 
592 /*
593 +----------------------------------------------------------------------------+
594 | Function Name : int i_APCI3501_ReadTimerCounterWatchdog |
595 | (struct comedi_device *dev,struct comedi_subdevice *s, |
596 | struct comedi_insn *insn,unsigned int *data) |
597 +----------------------------------------------------------------------------+
598 | Task : Read The Selected Timer , Counter or Watchdog |
599 +----------------------------------------------------------------------------+
600 | Input Parameters : struct comedi_device *dev : Driver handle |
601 | unsigned int *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 
617  struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
618 {
619 
620  if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
621  data[0] =
622  inl(devpriv->iobase + APCI3501_WATCHDOG +
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 +
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 +----------------------------------------------------------------------------+
643 | Function Name : int i_APCI3501_Reset(struct comedi_device *dev) |
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 
658 {
659  int i_Count = 0, i_temp = 0;
660  unsigned int 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 +
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 =
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  (unsigned int) ((unsigned int) (i_Count & 0xFF) |
680  (unsigned int) ((i_temp << 0x8) & 0x7FFFFF00L) |
681  (unsigned int) (ul_Polarity));
682  outl(ul_Command1,
683  devpriv->iobase + APCI3501_ANALOG_OUTPUT +
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;
711  struct comedi_device *dev = d;
712  unsigned int ui_Timer_AOWatchdog;
713  unsigned long ul_Command1;
714  /* Disable Interrupt */
715  ul_Command1 =
717 
718  ul_Command1 = (ul_Command1 & 0xFFFFF9FDul);
719  outl(ul_Command1,
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 unknown source");
728  return;
729  }
730 
731 /*
732 * Enable Interrupt Send a signal to from kernel to user space
733 */
734  send_sig(SIGIO, devpriv->tsk_Current, 0);
735  ul_Command1 =
737  ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
738  outl(ul_Command1,
740  i_temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
742  return;
743 }