Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hwdrv_apci035.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-035 | Compiler : GCC |
33  | Module name : hwdrv_apci035.c | Version : 2.96 |
34  +-------------------------------+---------------------------------------+
35  | Project manager: Eric Stolz | Date : 02/12/2002 |
36  +-------------------------------+---------------------------------------+
37  | Description : Hardware Layer Access For APCI-035 |
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_apci035.h"
55 static int i_WatchdogNbr = 0;
56 static int i_Temp = 0;
57 static int i_Flag = 1;
58 /*
59 +----------------------------------------------------------------------------+
60 | Function Name : int i_APCI035_ConfigTimerWatchdog |
61 | (struct comedi_device *dev,struct comedi_subdevice *s, |
62 | struct comedi_insn *insn,unsigned int *data) |
63 +----------------------------------------------------------------------------+
64 | Task : Configures The Timer , Counter or Watchdog |
65 +----------------------------------------------------------------------------+
66 | Input Parameters : struct comedi_device *dev : Driver handle |
67 | unsigned int *data : Data Pointer contains |
68 | configuration parameters as below |
69 | |
70 | data[0] : 0 Configure As Timer |
71 | 1 Configure As Watchdog |
72 | data[1] : Watchdog number
73 | data[2] : Time base Unit |
74 | data[3] : Reload Value |
75 | data[4] : External Trigger |
76 | 1:Enable
77 | 0:Disable
78 | data[5] :External Trigger Level
79 | 00 Trigger Disabled
80 | 01 Trigger Enabled (Low level)
81 | 10 Trigger Enabled (High Level)
82 | 11 Trigger Enabled (High/Low level)
83 | data[6] : External Gate |
84 | 1:Enable
85 | 0:Disable
86 | data[7] : External Gate level
87 | 00 Gate Disabled
88 | 01 Gate Enabled (Low level)
89 | 10 Gate Enabled (High Level)
90 | data[8] :Warning Relay
91 | 1: ENABLE
92 | 0: DISABLE
93 | data[9] :Warning Delay available
94 | data[10] :Warning Relay Time unit
95 | data[11] :Warning Relay Time Reload value
96 | data[12] :Reset Relay
97 | 1 : ENABLE
98 | 0 : DISABLE
99 | data[13] :Interrupt
100 | 1 : ENABLE
101 | 0 : DISABLE
102 |
103 |
104 +----------------------------------------------------------------------------+
105 | Output Parameters : -- |
106 +----------------------------------------------------------------------------+
107 | Return Value : TRUE : No error occur |
108 | : FALSE : Error occur. Return the error |
109 | |
110 +----------------------------------------------------------------------------+
111 */
113  struct comedi_insn *insn, unsigned int *data)
114 {
115  unsigned int ui_Status = 0;
116  unsigned int ui_Command = 0;
117  unsigned int ui_Mode = 0;
118  i_Temp = 0;
119  devpriv->tsk_Current = current;
120  devpriv->b_TimerSelectMode = data[0];
121  i_WatchdogNbr = data[1];
122  if (data[0] == 0) {
123  ui_Mode = 2;
124  } else {
125  ui_Mode = 0;
126  }
127 /* ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12); */
128  ui_Command = 0;
129 /* ui_Command = ui_Command & 0xFFFFF9FEUL; */
130  outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
131  ui_Command = 0;
132  ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
133 /************************/
134 /* Set the reload value */
135 /************************/
136  outl(data[3], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 4);
137 /*********************/
138 /* Set the time unit */
139 /*********************/
140  outl(data[2], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 8);
141  if (data[0] == ADDIDATA_TIMER) {
142 
143  /******************************/
144  /* Set the mode : */
145  /* - Disable the hardware */
146  /* - Disable the counter mode */
147  /* - Disable the warning */
148  /* - Disable the reset */
149  /* - Enable the timer mode */
150  /* - Set the timer mode */
151  /******************************/
152 
153  ui_Command =
154  (ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL;
155 
156  } /* if (data[0] == ADDIDATA_TIMER) */
157  else {
158  if (data[0] == ADDIDATA_WATCHDOG) {
159 
160  /******************************/
161  /* Set the mode : */
162  /* - Disable the hardware */
163  /* - Disable the counter mode */
164  /* - Disable the warning */
165  /* - Disable the reset */
166  /* - Disable the timer mode */
167  /******************************/
168 
169  ui_Command = ui_Command & 0xFFF819E2UL;
170 
171  } else {
172  printk("\n The parameter for Timer/watchdog selection is in error\n");
173  return -EINVAL;
174  }
175  }
176  outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
177  ui_Command = 0;
178  ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
179 /********************************/
180 /* Disable the hardware trigger */
181 /********************************/
182  ui_Command = ui_Command & 0xFFFFF89FUL;
183  if (data[4] == ADDIDATA_ENABLE) {
184  /**********************************/
185  /* Set the hardware trigger level */
186  /**********************************/
187  ui_Command = ui_Command | (data[5] << 5);
188  }
189  outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
190  ui_Command = 0;
191  ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
192 /*****************************/
193 /* Disable the hardware gate */
194 /*****************************/
195  ui_Command = ui_Command & 0xFFFFF87FUL;
196  if (data[6] == ADDIDATA_ENABLE) {
197 /*******************************/
198 /* Set the hardware gate level */
199 /*******************************/
200  ui_Command = ui_Command | (data[7] << 7);
201  }
202  outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
203  ui_Command = 0;
204  ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
205 /*******************************/
206 /* Disable the hardware output */
207 /*******************************/
208  ui_Command = ui_Command & 0xFFFFF9FBUL;
209 /*********************************/
210 /* Set the hardware output level */
211 /*********************************/
212  ui_Command = ui_Command | (data[8] << 2);
213  outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
214  if (data[9] == ADDIDATA_ENABLE) {
215  /************************/
216  /* Set the reload value */
217  /************************/
218  outl(data[11],
219  devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24);
220  /**********************/
221  /* Set the time unite */
222  /**********************/
223  outl(data[10],
224  devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 28);
225  }
226 
227  ui_Command = 0;
228  ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
229  /*******************************/
230  /* Disable the hardware output */
231  /*******************************/
232  ui_Command = ui_Command & 0xFFFFF9F7UL;
233  /*********************************/
234  /* Set the hardware output level */
235  /*********************************/
236  ui_Command = ui_Command | (data[12] << 3);
237  outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
238  /*************************************/
240  /*************************************/
241  ui_Command = 0;
242  ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
243 /*******************************/
244 /* Set the interrupt selection */
245 /*******************************/
246  ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
247 
248  ui_Command = (ui_Command & 0xFFFFF9FDUL) | (data[13] << 1);
249  outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
250 
251  return insn->n;
252 }
253 
254 /*
255 +----------------------------------------------------------------------------+
256 | Function Name : int i_APCI035_StartStopWriteTimerWatchdog |
257 | (struct comedi_device *dev,struct comedi_subdevice *s, |
258 | struct comedi_insn *insn,unsigned int *data) |
259 +----------------------------------------------------------------------------+
260 | Task : Start / Stop The Selected Timer , or Watchdog |
261 +----------------------------------------------------------------------------+
262 | Input Parameters : struct comedi_device *dev : Driver handle |
263 | unsigned int *data : Data Pointer contains |
264 | configuration parameters as below |
265 | |
266 | data[0] : 0 - Stop Selected Timer/Watchdog |
267 | 1 - Start Selected Timer/Watchdog |
268 | 2 - Trigger Selected Timer/Watchdog |
269 | 3 - Stop All Timer/Watchdog |
270 | 4 - Start All Timer/Watchdog |
271 | 5 - Trigger All Timer/Watchdog |
272 | |
273 +----------------------------------------------------------------------------+
274 | Output Parameters : -- |
275 +----------------------------------------------------------------------------+
276 | Return Value : TRUE : No error occur |
277 | : FALSE : Error occur. Return the error |
278 | |
279 +----------------------------------------------------------------------------+
280 */
282  struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
283 {
284  unsigned int ui_Command = 0;
285  int i_Count = 0;
286  if (data[0] == 1) {
287  ui_Command =
288  inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
289  /**********************/
290  /* Start the hardware */
291  /**********************/
292  ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL;
293  outl(ui_Command,
294  devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
295  } /* if (data[0]==1) */
296  if (data[0] == 2) {
297  ui_Command =
298  inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
299  /***************************/
300  /* Set the trigger command */
301  /***************************/
302  ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL;
303  outl(ui_Command,
304  devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
305  }
306 
307  if (data[0] == 0) /* Stop The Watchdog */
308  {
309  /* Stop The Watchdog */
310  ui_Command = 0;
311 /*
312 * ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
313 * ui_Command = ui_Command & 0xFFFFF9FEUL;
314 */
315  outl(ui_Command,
316  devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
317  } /* if (data[1]==0) */
318  if (data[0] == 3) /* stop all Watchdogs */
319  {
320  ui_Command = 0;
321  for (i_Count = 1; i_Count <= 4; i_Count++) {
322  if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
323  ui_Command = 0x2UL;
324  } else {
325  ui_Command = 0x10UL;
326  }
327  i_WatchdogNbr = i_Count;
328  outl(ui_Command,
329  devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
330  0);
331  }
332 
333  }
334  if (data[0] == 4) /* start all Watchdogs */
335  {
336  ui_Command = 0;
337  for (i_Count = 1; i_Count <= 4; i_Count++) {
338  if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
339  ui_Command = 0x1UL;
340  } else {
341  ui_Command = 0x8UL;
342  }
343  i_WatchdogNbr = i_Count;
344  outl(ui_Command,
345  devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
346  0);
347  }
348  }
349  if (data[0] == 5) /* trigger all Watchdogs */
350  {
351  ui_Command = 0;
352  for (i_Count = 1; i_Count <= 4; i_Count++) {
353  if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
354  ui_Command = 0x4UL;
355  } else {
356  ui_Command = 0x20UL;
357  }
358 
359  i_WatchdogNbr = i_Count;
360  outl(ui_Command,
361  devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
362  0);
363  }
364  i_Temp = 1;
365  }
366  return insn->n;
367 }
368 
369 /*
370 +----------------------------------------------------------------------------+
371 | Function Name : int i_APCI035_ReadTimerWatchdog |
372 | (struct comedi_device *dev,struct comedi_subdevice *s, |
373 | struct comedi_insn *insn,unsigned int *data) |
374 +----------------------------------------------------------------------------+
375 | Task : Read The Selected Timer , Counter or Watchdog |
376 +----------------------------------------------------------------------------+
377 | Input Parameters : struct comedi_device *dev : Driver handle |
378 | unsigned int *data : Data Pointer contains |
379 | configuration parameters as below |
380 | |
381 | |
382 +----------------------------------------------------------------------------+
383 | Output Parameters : data[0] : software trigger status
384 | data[1] : hardware trigger status
385 | data[2] : Software clear status
386 | data[3] : Overflow status
387 | data[4] : Timer actual value
388 |
389 
390 +----------------------------------------------------------------------------+
391 | Return Value : TRUE : No error occur |
392 | : FALSE : Error occur. Return the error |
393 | |
394 +----------------------------------------------------------------------------+
395 */
397  struct comedi_insn *insn, unsigned int *data)
398 {
399  unsigned int ui_Status = 0; /* Status register */
400  i_WatchdogNbr = insn->unused[0];
401 
402  /******************/
403  /* Get the status */
404  /******************/
405 
406  ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
407 
408  /***********************************/
409  /* Get the software trigger status */
410  /***********************************/
411 
412  data[0] = ((ui_Status >> 1) & 1);
413  /***********************************/
414  /* Get the hardware trigger status */
415  /***********************************/
416  data[1] = ((ui_Status >> 2) & 1);
417  /*********************************/
418  /* Get the software clear status */
419  /*********************************/
420  data[2] = ((ui_Status >> 3) & 1);
421  /***************************/
422  /* Get the overflow status */
423  /***************************/
424  data[3] = ((ui_Status >> 0) & 1);
425  if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
426  data[4] = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0);
427 
428  } /* if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) */
429 
430  return insn->n;
431 }
432 
433 /*
434 +----------------------------------------------------------------------------+
435 | Function Name : int i_APCI035_ConfigAnalogInput |
436 | (struct comedi_device *dev,struct comedi_subdevice *s, |
437 | struct comedi_insn *insn,unsigned int *data) |
438 +----------------------------------------------------------------------------+
439 | Task : Configures The Analog Input Subdevice |
440 +----------------------------------------------------------------------------+
441 | Input Parameters : struct comedi_device *dev : Driver handle |
442 | struct comedi_subdevice *s : Subdevice Pointer |
443 | struct comedi_insn *insn : Insn Structure Pointer |
444 | unsigned int *data : Data Pointer contains |
445 | configuration parameters as below |
446 | data[0] : Warning delay value
447 | |
448 +----------------------------------------------------------------------------+
449 | Output Parameters : -- |
450 +----------------------------------------------------------------------------+
451 | Return Value : TRUE : No error occur |
452 | : FALSE : Error occur. Return the error |
453 | |
454 +----------------------------------------------------------------------------+
455 */
457  struct comedi_insn *insn, unsigned int *data)
458 {
459  devpriv->tsk_Current = current;
460  outl(0x200 | 0, devpriv->iobase + 128 + 0x4);
461  outl(0, devpriv->iobase + 128 + 0);
462 /********************************/
463 /* Initialise the warning value */
464 /********************************/
465  outl(0x300 | 0, devpriv->iobase + 128 + 0x4);
466  outl((data[0] << 8), devpriv->iobase + 128 + 0);
467  outl(0x200000UL, devpriv->iobase + 128 + 12);
468 
469  return insn->n;
470 }
471 
472 /*
473 +----------------------------------------------------------------------------+
474 | Function Name : int i_APCI035_ReadAnalogInput |
475 | (struct comedi_device *dev,struct comedi_subdevice *s, |
476 | struct comedi_insn *insn,unsigned int *data) |
477 +----------------------------------------------------------------------------+
478 | Task : Read value of the selected channel |
479 +----------------------------------------------------------------------------+
480 | Input Parameters : struct comedi_device *dev : Driver handle |
481 | unsigned int ui_NoOfChannels : No Of Channels To read |
482 | unsigned int *data : Data Pointer to read status |
483 +----------------------------------------------------------------------------+
484 | Output Parameters : -- |
485 | data[0] : Digital Value Of Input |
486 | |
487 +----------------------------------------------------------------------------+
488 | Return Value : TRUE : No error occur |
489 | : FALSE : Error occur. Return the error |
490 | |
491 +----------------------------------------------------------------------------+
492 */
494  struct comedi_insn *insn, unsigned int *data)
495 {
496  unsigned int ui_CommandRegister = 0;
497 /******************/
498 /* Set the start */
499 /******************/
500  ui_CommandRegister = 0x80000;
501  /******************************/
502  /* Write the command register */
503  /******************************/
504  outl(ui_CommandRegister, devpriv->iobase + 128 + 8);
505 
506 /***************************************/
507 /* Read the digital value of the input */
508 /***************************************/
509  data[0] = inl(devpriv->iobase + 128 + 28);
510  return insn->n;
511 }
512 
513 /*
514 +----------------------------------------------------------------------------+
515 | Function Name : int i_APCI035_Reset(struct comedi_device *dev) |
516 | |
517 +----------------------------------------------------------------------------+
518 | Task :Resets the registers of the card |
519 +----------------------------------------------------------------------------+
520 | Input Parameters : |
521 +----------------------------------------------------------------------------+
522 | Output Parameters : -- |
523 +----------------------------------------------------------------------------+
524 | Return Value : |
525 | |
526 +----------------------------------------------------------------------------+
527 */
529 {
530  int i_Count = 0;
531  for (i_Count = 1; i_Count <= 4; i_Count++) {
532  i_WatchdogNbr = i_Count;
533  outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); /* stop all timers */
534  }
535  outl(0x0, devpriv->iobase + 128 + 12); /* Disable the warning delay */
536 
537  return 0;
538 }
539 
540 /*
541 +----------------------------------------------------------------------------+
542 | Function Name : static void v_APCI035_Interrupt |
543 | (int irq , void *d) |
544 +----------------------------------------------------------------------------+
545 | Task : Interrupt processing Routine |
546 +----------------------------------------------------------------------------+
547 | Input Parameters : int irq : irq number |
548 | void *d : void pointer |
549 +----------------------------------------------------------------------------+
550 | Output Parameters : -- |
551 +----------------------------------------------------------------------------+
552 | Return Value : TRUE : No error occur |
553 | : FALSE : Error occur. Return the error |
554 | |
555 +----------------------------------------------------------------------------+
556 */
557 static void v_APCI035_Interrupt(int irq, void *d)
558 {
559  struct comedi_device *dev = d;
560  unsigned int ui_StatusRegister1 = 0;
561  unsigned int ui_StatusRegister2 = 0;
562  unsigned int ui_ReadCommand = 0;
563  unsigned int ui_ChannelNumber = 0;
564  unsigned int ui_DigitalTemperature = 0;
565  if (i_Temp == 1) {
566  i_WatchdogNbr = i_Flag;
567  i_Flag = i_Flag + 1;
568  }
569  /**************************************/
570  /* Read the interrupt status register of temperature Warning */
571  /**************************************/
572  ui_StatusRegister1 = inl(devpriv->iobase + 128 + 16);
573  /**************************************/
574  /* Read the interrupt status register for Watchdog/timer */
575  /**************************************/
576 
577  ui_StatusRegister2 =
578  inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 20);
579 
580  if ((((ui_StatusRegister1) & 0x8) == 0x8)) /* Test if warning relay interrupt */
581  {
582  /**********************************/
583  /* Disable the temperature warning */
584  /**********************************/
585  ui_ReadCommand = inl(devpriv->iobase + 128 + 12);
586  ui_ReadCommand = ui_ReadCommand & 0xFFDF0000UL;
587  outl(ui_ReadCommand, devpriv->iobase + 128 + 12);
588  /***************************/
589  /* Read the channel number */
590  /***************************/
591  ui_ChannelNumber = inl(devpriv->iobase + 128 + 60);
592  /**************************************/
593  /* Read the digital temperature value */
594  /**************************************/
595  ui_DigitalTemperature = inl(devpriv->iobase + 128 + 60);
596  send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
597  } /* if (((ui_StatusRegister1 & 0x8) == 0x8)) */
598 
599  else {
600  if ((ui_StatusRegister2 & 0x1) == 0x1) {
601  send_sig(SIGIO, devpriv->tsk_Current, 0); /* send signal to the sample */
602  }
603  } /* else if (((ui_StatusRegister1 & 0x8) == 0x8)) */
604 
605  return;
606 }