Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hwdrv_apci2200.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-2200 | Compiler : GCC |
33  | Module name : hwdrv_apci2200.c| Version : 2.96 |
34  +-------------------------------+---------------------------------------+
35  | Project manager: Eric Stolz | Date : 02/12/2002 |
36  +-------------------------------+---------------------------------------+
37  | Description : Hardware Layer Access For APCI-2200 |
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_apci2200.h"
55 
56 /*
57 +----------------------------------------------------------------------------+
58 | Function Name : int i_APCI2200_Read1DigitalInput |
59 | (struct comedi_device *dev,struct comedi_subdevice *s, |
60 | struct comedi_insn *insn,unsigned int *data) |
61 +----------------------------------------------------------------------------+
62 | Task : Return the status of the digital input |
63 +----------------------------------------------------------------------------+
64 | Input Parameters : struct comedi_device *dev : Driver handle |
65 | struct comedi_subdevice *s, :pointer to subdevice structure
66 | struct comedi_insn *insn :pointer to insn structure |
67 | unsigned int *data : Data Pointer to read status |
68 +----------------------------------------------------------------------------+
69 | Output Parameters : -- |
70 +----------------------------------------------------------------------------+
71 | Return Value : TRUE : No error occur |
72 | : FALSE : Error occur. Return the error |
73 | |
74 +----------------------------------------------------------------------------+
75 */
77  struct comedi_insn *insn, unsigned int *data)
78 {
79  unsigned int ui_TmpValue = 0;
80  unsigned int ui_Channel;
81  ui_Channel = CR_CHAN(insn->chanspec);
82  if (ui_Channel <= 7) {
83  ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
84  *data = (ui_TmpValue >> ui_Channel) & 0x1;
85  } /* if(ui_Channel >= 0 && ui_Channel <=7) */
86  else {
87  printk("\nThe specified channel does not exist\n");
88  return -EINVAL; /* "sorry channel spec wrong " */
89  } /* else if(ui_Channel >= 0 && ui_Channel <=7) */
90 
91  return insn->n;
92 }
93 
94 /*
95 +----------------------------------------------------------------------------+
96 | Function Name : int i_APCI2200_ReadMoreDigitalInput |
97 | (struct comedi_device *dev,struct comedi_subdevice *s, |
98 | struct comedi_insn *insn,unsigned int *data) |
99 +----------------------------------------------------------------------------+
100 | Task : Return the status of the Requested digital inputs |
101 +----------------------------------------------------------------------------+
102 | Input Parameters : struct comedi_device *dev : Driver handle |
103 | struct comedi_subdevice *s, :pointer to subdevice structure
104 | struct comedi_insn *insn :pointer to insn structure |
105 | unsigned int *data : Data Pointer to read status |
106 +----------------------------------------------------------------------------+
107 | Output Parameters : -- |
108 +----------------------------------------------------------------------------+
109 | Return Value : TRUE : No error occur |
110 | : FALSE : Error occur. Return the error |
111 | |
112 +----------------------------------------------------------------------------+
113 */
114 
116  struct comedi_insn *insn, unsigned int *data)
117 {
118 
119  unsigned int ui_PortValue = data[0];
120  unsigned int ui_Mask = 0;
121  unsigned int ui_NoOfChannels;
122 
123  ui_NoOfChannels = CR_CHAN(insn->chanspec);
124 
125  *data = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
126  switch (ui_NoOfChannels) {
127  case 2:
128  ui_Mask = 3;
129  *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
130  break;
131  case 4:
132  ui_Mask = 15;
133  *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
134  break;
135  case 7:
136  break;
137 
138  default:
139  printk("\nWrong parameters\n");
140  return -EINVAL; /* "sorry channel spec wrong " */
141  break;
142  } /* switch(ui_NoOfChannels) */
143 
144  return insn->n;
145 }
146 
147 /*
148 +----------------------------------------------------------------------------+
149 | Function Name : int i_APCI2200_ConfigDigitalOutput (struct comedi_device *dev,
150 | struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
151 | |
152 +----------------------------------------------------------------------------+
153 | Task : Configures The Digital Output Subdevice. |
154 +----------------------------------------------------------------------------+
155 | Input Parameters : struct comedi_device *dev : Driver handle |
156 | unsigned int *data : Data Pointer contains |
157 | configuration parameters as below |
158 | struct comedi_subdevice *s, :pointer to subdevice structure
159 | struct comedi_insn *insn :pointer to insn structure |
160 | data[0] :1:Memory on |
161 | 0:Memory off |
162 | |
163 | |
164 +----------------------------------------------------------------------------+
165 | Output Parameters : -- |
166 +----------------------------------------------------------------------------+
167 | Return Value : TRUE : No error occur |
168 | : FALSE : Error occur. Return the error |
169 | |
170 +----------------------------------------------------------------------------+
171 */
173  struct comedi_insn *insn, unsigned int *data)
174 {
175  devpriv->b_OutputMemoryStatus = data[0];
176  return insn->n;
177 }
178 
179 /*
180 +----------------------------------------------------------------------------+
181 | Function Name : int i_APCI2200_WriteDigitalOutput |
182 | (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
183 | unsigned int *data) |
184 +----------------------------------------------------------------------------+
185 | Task : Writes port value To the selected port |
186 +----------------------------------------------------------------------------+
187 | Input Parameters : struct comedi_device *dev : Driver handle |
188 | struct comedi_subdevice *s, :pointer to subdevice structure
189 | struct comedi_insn *insn :pointer to insn structure |
190 | unsigned int *data : Data Pointer to read status |
191 +----------------------------------------------------------------------------+
192 | Output Parameters : -- |
193 +----------------------------------------------------------------------------+
194 | Return Value : TRUE : No error occur |
195 | : FALSE : Error occur. Return the error |
196 | |
197 +----------------------------------------------------------------------------+
198 */
199 
201  struct comedi_insn *insn, unsigned int *data)
202 {
203  unsigned int ui_Temp, ui_Temp1;
204  unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
205  if (devpriv->b_OutputMemoryStatus) {
206  ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
207 
208  } /* if(devpriv->b_OutputMemoryStatus ) */
209  else {
210  ui_Temp = 0;
211  } /* if(devpriv->b_OutputMemoryStatus ) */
212  if (data[3] == 0) {
213  if (data[1] == 0) {
214  data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
215  outw(data[0], devpriv->iobase + APCI2200_DIGITAL_OP);
216  } /* if(data[1]==0) */
217  else {
218  if (data[1] == 1) {
219  switch (ui_NoOfChannel) {
220 
221  case 2:
222  data[0] =
223  (data[0] << (2 *
224  data[2])) | ui_Temp;
225  break;
226 
227  case 4:
228  data[0] =
229  (data[0] << (4 *
230  data[2])) | ui_Temp;
231  break;
232 
233  case 8:
234  data[0] =
235  (data[0] << (8 *
236  data[2])) | ui_Temp;
237  break;
238  case 15:
239  data[0] = data[0] | ui_Temp;
240  break;
241  default:
242  comedi_error(dev, " chan spec wrong");
243  return -EINVAL; /* "sorry channel spec wrong " */
244 
245  } /* switch(ui_NoOfChannels) */
246 
247  outw(data[0],
248  devpriv->iobase + APCI2200_DIGITAL_OP);
249  } /* if(data[1]==1) */
250  else {
251  printk("\nSpecified channel not supported\n");
252  } /* else if(data[1]==1) */
253  } /* elseif(data[1]==0) */
254  } /* if(data[3]==0) */
255  else {
256  if (data[3] == 1) {
257  if (data[1] == 0) {
258  data[0] = ~data[0] & 0x1;
259  ui_Temp1 = 1;
260  ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
261  ui_Temp = ui_Temp | ui_Temp1;
262  data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
263  data[0] = data[0] & ui_Temp;
264  outw(data[0],
265  devpriv->iobase + APCI2200_DIGITAL_OP);
266  } /* if(data[1]==0) */
267  else {
268  if (data[1] == 1) {
269  switch (ui_NoOfChannel) {
270 
271  case 2:
272  data[0] = ~data[0] & 0x3;
273  ui_Temp1 = 3;
274  ui_Temp1 =
275  ui_Temp1 << 2 * data[2];
276  ui_Temp = ui_Temp | ui_Temp1;
277  data[0] =
278  ((data[0] << (2 *
279  data
280  [2])) ^
281  0xffff) & ui_Temp;
282  break;
283 
284  case 4:
285  data[0] = ~data[0] & 0xf;
286  ui_Temp1 = 15;
287  ui_Temp1 =
288  ui_Temp1 << 4 * data[2];
289  ui_Temp = ui_Temp | ui_Temp1;
290  data[0] =
291  ((data[0] << (4 *
292  data
293  [2])) ^
294  0xffff) & ui_Temp;
295  break;
296 
297  case 8:
298  data[0] = ~data[0] & 0xff;
299  ui_Temp1 = 255;
300  ui_Temp1 =
301  ui_Temp1 << 8 * data[2];
302  ui_Temp = ui_Temp | ui_Temp1;
303  data[0] =
304  ((data[0] << (8 *
305  data
306  [2])) ^
307  0xffff) & ui_Temp;
308  break;
309  case 15:
310  break;
311 
312  default:
313  comedi_error(dev,
314  " chan spec wrong");
315  return -EINVAL; /* "sorry channel spec wrong " */
316 
317  } /* switch(ui_NoOfChannels) */
318 
319  outw(data[0],
320  devpriv->iobase +
322  } /* if(data[1]==1) */
323  else {
324  printk("\nSpecified channel not supported\n");
325  } /* else if(data[1]==1) */
326  } /* elseif(data[1]==0) */
327  } /* if(data[3]==1); */
328  else {
329  printk("\nSpecified functionality does not exist\n");
330  return -EINVAL;
331  } /* if else data[3]==1) */
332  } /* if else data[3]==0) */
333  return insn->n;
334 }
335 
336 /*
337 +----------------------------------------------------------------------------+
338 | Function Name : int i_APCI2200_ReadDigitalOutput |
339 | (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
340 | unsigned int *data) |
341 +----------------------------------------------------------------------------+
342 | Task : Read value of the selected channel or port |
343 +----------------------------------------------------------------------------+
344 | Input Parameters : struct comedi_device *dev : Driver handle |
345 | struct comedi_subdevice *s, :pointer to subdevice structure
346 | struct comedi_insn *insn :pointer to insn structure |
347 | unsigned int *data : Data Pointer to read status |
348 +----------------------------------------------------------------------------+
349 | Output Parameters : -- |
350 +----------------------------------------------------------------------------+
351 | Return Value : TRUE : No error occur |
352 | : FALSE : Error occur. Return the error |
353 | |
354 +----------------------------------------------------------------------------+
355 */
356 
358  struct comedi_insn *insn, unsigned int *data)
359 {
360 
361  unsigned int ui_Temp;
362  unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
363  ui_Temp = data[0];
364  *data = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
365  if (ui_Temp == 0) {
366  *data = (*data >> ui_NoOfChannel) & 0x1;
367  } /* if(ui_Temp==0) */
368  else {
369  if (ui_Temp == 1) {
370  switch (ui_NoOfChannel) {
371 
372  case 2:
373  *data = (*data >> (2 * data[1])) & 3;
374  break;
375 
376  case 4:
377  *data = (*data >> (4 * data[1])) & 15;
378  break;
379 
380  case 8:
381  *data = (*data >> (8 * data[1])) & 255;
382  break;
383 
384  case 15:
385  break;
386 
387  default:
388  comedi_error(dev, " chan spec wrong");
389  return -EINVAL; /* "sorry channel spec wrong " */
390 
391  } /* switch(ui_NoOfChannels) */
392  } /* if(ui_Temp==1) */
393  else {
394  printk("\nSpecified channel not supported \n");
395  } /* elseif(ui_Temp==1) */
396  } /* elseif(ui_Temp==0) */
397  return insn->n;
398 }
399 
400 /*
401 +----------------------------------------------------------------------------+
402 | Function Name : int i_APCI2200_ConfigWatchdog(struct comedi_device *dev,
403 | struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
404 | |
405 +----------------------------------------------------------------------------+
406 | Task : Configures The Watchdog |
407 +----------------------------------------------------------------------------+
408 | Input Parameters : struct comedi_device *dev : Driver handle |
409 | struct comedi_subdevice *s, :pointer to subdevice structure
410 | struct comedi_insn *insn :pointer to insn structure |
411 | unsigned int *data : Data Pointer to read status |
412 +----------------------------------------------------------------------------+
413 | Output Parameters : -- |
414 +----------------------------------------------------------------------------+
415 | Return Value : TRUE : No error occur |
416 | : FALSE : Error occur. Return the error |
417 | |
418 +----------------------------------------------------------------------------+
419 */
420 
422  struct comedi_insn *insn, unsigned int *data)
423 {
424  if (data[0] == 0) {
425  /* Disable the watchdog */
426  outw(0x0,
427  devpriv->iobase + APCI2200_WATCHDOG +
429  /* Loading the Reload value */
430  outw(data[1],
431  devpriv->iobase + APCI2200_WATCHDOG +
433  data[1] = data[1] >> 16;
434  outw(data[1],
435  devpriv->iobase + APCI2200_WATCHDOG +
437  } /* if(data[0]==0) */
438  else {
439  printk("\nThe input parameters are wrong\n");
440  return -EINVAL;
441  } /* elseif(data[0]==0) */
442 
443  return insn->n;
444 }
445 
446  /*
447  +----------------------------------------------------------------------------+
448  | Function Name : int i_APCI2200_StartStopWriteWatchdog |
449  | (struct comedi_device *dev,struct comedi_subdevice *s,
450  struct comedi_insn *insn,unsigned int *data); |
451  +----------------------------------------------------------------------------+
452  | Task : Start / Stop The Watchdog |
453  +----------------------------------------------------------------------------+
454  | Input Parameters : struct comedi_device *dev : Driver handle |
455  | struct comedi_subdevice *s, :pointer to subdevice structure
456  struct comedi_insn *insn :pointer to insn structure |
457  | unsigned int *data : Data Pointer to read status |
458  +----------------------------------------------------------------------------+
459  | Output Parameters : -- |
460  +----------------------------------------------------------------------------+
461  | Return Value : TRUE : No error occur |
462  | : FALSE : Error occur. Return the error |
463  | |
464  +----------------------------------------------------------------------------+
465  */
466 
468  struct comedi_insn *insn, unsigned int *data)
469 {
470  switch (data[0]) {
471  case 0: /* stop the watchdog */
472  outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */
473  break;
474  case 1: /* start the watchdog */
475  outw(0x0001,
476  devpriv->iobase + APCI2200_WATCHDOG +
478  break;
479  case 2: /* Software trigger */
480  outw(0x0201,
481  devpriv->iobase + APCI2200_WATCHDOG +
483  break;
484  default:
485  printk("\nSpecified functionality does not exist\n");
486  return -EINVAL;
487  } /* switch(data[0]) */
488  return insn->n;
489 }
490 
491 /*
492 +----------------------------------------------------------------------------+
493 | Function Name : int i_APCI2200_ReadWatchdog |
494 | (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
495 | unsigned int *data); |
496 +----------------------------------------------------------------------------+
497 | Task : Read The Watchdog |
498 +----------------------------------------------------------------------------+
499 | Input Parameters : struct comedi_device *dev : Driver handle |
500 | struct comedi_subdevice *s, :pointer to subdevice structure
501 | struct comedi_insn *insn :pointer to insn structure |
502 | unsigned int *data : Data Pointer to read status |
503 +----------------------------------------------------------------------------+
504 | Output Parameters : -- |
505 +----------------------------------------------------------------------------+
506 | Return Value : TRUE : No error occur |
507 | : FALSE : Error occur. Return the error |
508 | |
509 +----------------------------------------------------------------------------+
510 */
511 
513  struct comedi_insn *insn, unsigned int *data)
514 {
515  data[0] =
516  inw(devpriv->iobase + APCI2200_WATCHDOG +
518  return insn->n;
519 }
520 
521 /*
522 +----------------------------------------------------------------------------+
523 | Function Name : int i_APCI2200_Reset(struct comedi_device *dev) | |
524 +----------------------------------------------------------------------------+
525 | Task :resets all the registers |
526 +----------------------------------------------------------------------------+
527 | Input Parameters : struct comedi_device *dev
528 +----------------------------------------------------------------------------+
529 | Output Parameters : -- |
530 +----------------------------------------------------------------------------+
531 | Return Value : |
532 | |
533 +----------------------------------------------------------------------------+
534 */
535 
537 {
538  outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP); /* RESETS THE DIGITAL OUTPUTS */
539  outw(0x0,
540  devpriv->iobase + APCI2200_WATCHDOG +
542  outw(0x0,
543  devpriv->iobase + APCI2200_WATCHDOG +
545  outw(0x0,
546  devpriv->iobase + APCI2200_WATCHDOG +
548  return 0;
549 }