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