Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
hwdrv_apci2016.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-2016 | Compiler : GCC |
33  | Module name : hwdrv_apci2016.c| Version : 2.96 |
34  +-------------------------------+---------------------------------------+
35  | Project manager: Eric Stolz | Date : 02/12/2002 |
36  +-------------------------------+---------------------------------------+
37  | Description : Hardware Layer Access For APCI-2016 |
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_apci2016.h"
55 
56 /*
57 +----------------------------------------------------------------------------+
58 | Function Name : int i_APCI2016_ConfigDigitalOutput |
59 | (struct comedi_device *dev,struct comedi_subdevice *s, |
60 | struct comedi_insn *insn,unsigned int *data) |
61 +----------------------------------------------------------------------------+
62 | Task : Configures The Digital Output Subdevice. |
63 +----------------------------------------------------------------------------+
64 | Input Parameters : struct comedi_device *dev : Driver handle |
65 | unsigned int *data : Data Pointer contains |
66 | configuration parameters as below |
67 | |
68 | data[0] : 1 Digital Memory On |
69 | 0 Digital Memory Off |
70 +----------------------------------------------------------------------------+
71 | Output Parameters : -- |
72 +----------------------------------------------------------------------------+
73 | Return Value : TRUE : No error occur |
74 | : FALSE : Error occur. Return the error |
75 | |
76 +----------------------------------------------------------------------------+
77 */
79  struct comedi_insn *insn, unsigned int *data)
80 {
81  if ((data[0] != 0) && (data[0] != 1)) {
82  comedi_error(dev,
83  "Not a valid Data !!! ,Data should be 1 or 0\n");
84  return -EINVAL;
85  } /* if ((data[0]!=0) && (data[0]!=1)) */
86  if (data[0]) {
87  devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
88  } /* if (data[0] */
89  else {
90  devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
91  } /* else if (data[0] */
92  return insn->n;
93 }
94 
95 /*
96 +----------------------------------------------------------------------------+
97 | Function Name : int i_APCI2016_WriteDigitalOutput |
98 | (struct comedi_device *dev,struct comedi_subdevice *s, |
99 | struct comedi_insn *insn,unsigned int *data) |
100 +----------------------------------------------------------------------------+
101 | Task : Writes port value To the selected port |
102 +----------------------------------------------------------------------------+
103 | Input Parameters : struct comedi_device *dev : Driver handle |
104 | unsigned int ui_NoOfChannels : No Of Channels To Write |
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 */
115  struct comedi_insn *insn, unsigned int *data)
116 {
117  unsigned int ui_NoOfChannel;
118  unsigned int ui_Temp, ui_Temp1;
119  ui_NoOfChannel = CR_CHAN(insn->chanspec);
120  if (ui_NoOfChannel > 15) {
121  comedi_error(dev,
122  "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
123  return -EINVAL;
124  } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */
125  if (devpriv->b_OutputMemoryStatus) {
126  ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP);
127  } /* if (devpriv->b_OutputMemoryStatus ) */
128  else {
129  ui_Temp = 0;
130  } /* else if (devpriv->b_OutputMemoryStatus ) */
131  if ((data[1] != 0) && (data[1] != 1)) {
132  comedi_error(dev,
133  "Invalid Data[1] value !!!, Data[1] should be 0 or 1\n");
134  return -EINVAL;
135  } /* if ((data[1]!=0) && (data[1]!=1)) */
136 
137  if (data[3] == 0) {
138  if (data[1] == 0) {
139  data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
140  outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP);
141  } /* if (data[1]==0) */
142  else {
143  if (data[1] == 1) {
144  switch (ui_NoOfChannel) {
145  case 2:
146  data[0] =
147  (data[0] << (2 *
148  data[2])) | ui_Temp;
149  break;
150  case 4:
151  data[0] =
152  (data[0] << (4 *
153  data[2])) | ui_Temp;
154  break;
155  case 8:
156  data[0] =
157  (data[0] << (8 *
158  data[2])) | ui_Temp;
159  break;
160  case 15:
161  data[0] = data[0] | ui_Temp;
162  break;
163  default:
164  comedi_error(dev, " chan spec wrong");
165  return -EINVAL; /* "sorry channel spec wrong " */
166  } /* switch(ui_NoOfChannels) */
167  outw(data[0],
168  devpriv->iobase + APCI2016_DIGITAL_OP);
169  } /* if (data[1]==1) */
170  else {
171  printk("\nSpecified channel not supported\n");
172  } /* else if (data[1]==1) */
173  } /* else if (data[1]==0) */
174  } /* if (data[3]==0) */
175  else {
176  if (data[3] == 1) {
177  if (data[1] == 0) {
178  data[0] = ~data[0] & 0x1;
179  ui_Temp1 = 1;
180  ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
181  ui_Temp = ui_Temp | ui_Temp1;
182  data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
183  data[0] = data[0] & ui_Temp;
184  outw(data[0],
185  devpriv->iobase + APCI2016_DIGITAL_OP);
186  } /* if (data[1]==0) */
187  else {
188  if (data[1] == 1) {
189  switch (ui_NoOfChannel) {
190  case 2:
191  data[0] = ~data[0] & 0x3;
192  ui_Temp1 = 3;
193  ui_Temp1 =
194  ui_Temp1 << 2 * data[2];
195  ui_Temp = ui_Temp | ui_Temp1;
196  data[0] =
197  ((data[0] << (2 *
198  data
199  [2])) ^
200  0xffff) & ui_Temp;
201  break;
202  case 4:
203  data[0] = ~data[0] & 0xf;
204  ui_Temp1 = 15;
205  ui_Temp1 =
206  ui_Temp1 << 4 * data[2];
207  ui_Temp = ui_Temp | ui_Temp1;
208  data[0] =
209  ((data[0] << (4 *
210  data
211  [2])) ^
212  0xffff) & ui_Temp;
213  break;
214  case 8:
215  data[0] = ~data[0] & 0xff;
216  ui_Temp1 = 255;
217  ui_Temp1 =
218  ui_Temp1 << 8 * data[2];
219  ui_Temp = ui_Temp | ui_Temp1;
220  data[0] =
221  ((data[0] << (8 *
222  data
223  [2])) ^
224  0xffff) & ui_Temp;
225  break;
226  case 15:
227  break;
228  default:
229  comedi_error(dev,
230  " chan spec wrong");
231  return -EINVAL; /* "sorry channel spec wrong " */
232  } /* switch(ui_NoOfChannels) */
233  outw(data[0],
234  devpriv->iobase +
236  } /* if(data[1]==1) */
237  else {
238  printk("\nSpecified channel not supported\n");
239  } /* else if(data[1]==1) */
240  } /* elseif(data[1]==0) */
241  } /* if(data[3]==1); */
242  else {
243  printk("\nSpecified functionality does not exist\n");
244  return -EINVAL;
245  } /* if else data[3]==1) */
246  } /* if else data[3]==0) */
247  return insn->n;
248 }
249 
250 /*
251 +----------------------------------------------------------------------------+
252 | Function Name : int i_APCI2016_BitsDigitalOutput |
253 | (struct comedi_device *dev,struct comedi_subdevice *s, |
254 | struct comedi_insn *insn,unsigned int *data) |
255 +----------------------------------------------------------------------------+
256 | Task : Read value of the selected channel or port |
257 +----------------------------------------------------------------------------+
258 | Input Parameters : struct comedi_device *dev : Driver handle |
259 | unsigned int ui_NoOfChannels : No Of Channels To read |
260 | unsigned int *data : Data Pointer to read status |
261 +----------------------------------------------------------------------------+
262 | Output Parameters : -- |
263 +----------------------------------------------------------------------------+
264 | Return Value : TRUE : No error occur |
265 | : FALSE : Error occur. Return the error |
266 | |
267 +----------------------------------------------------------------------------+
268 */
270  struct comedi_insn *insn, unsigned int *data)
271 {
272  unsigned int ui_Temp;
273  unsigned int ui_NoOfChannel;
274  ui_NoOfChannel = CR_CHAN(insn->chanspec);
275  if (ui_NoOfChannel > 15) {
276  comedi_error(dev,
277  "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
278  return -EINVAL;
279  } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */
280  if ((data[0] != 0) && (data[0] != 1)) {
281  comedi_error(dev,
282  "Invalid Data[0] value !!!, Data[0] should be 0 or 1\n");
283  return -EINVAL;
284  } /* if ((data[0]!=0) && (data[0]!=1)) */
285  ui_Temp = data[0];
286  *data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW);
287  if (ui_Temp == 0) {
288  *data = (*data >> ui_NoOfChannel) & 0x1;
289  } /* if (ui_Temp==0) */
290  else {
291  if (ui_Temp == 1) {
292  switch (ui_NoOfChannel) {
293  case 2:
294  *data = (*data >> (2 * data[1])) & 3;
295  break;
296 
297  case 4:
298  *data = (*data >> (4 * data[1])) & 15;
299  break;
300 
301  case 8:
302  *data = (*data >> (8 * data[1])) & 255;
303  break;
304 
305  case 15:
306  break;
307 
308  default:
309  comedi_error(dev, " chan spec wrong");
310  return -EINVAL; /* "sorry channel spec wrong " */
311  } /* switch(ui_NoOfChannel) */
312  } /* if (ui_Temp==1) */
313  else {
314  printk("\nSpecified channel not supported \n");
315  } /* else if (ui_Temp==1) */
316  } /* if (ui_Temp==0) */
317  return insn->n;
318 }
319 
320 /*
321 +----------------------------------------------------------------------------+
322 | Function Name : int i_APCI2016_ConfigWatchdog |
323 | (struct comedi_device *dev,struct comedi_subdevice *s, |
324 | struct comedi_insn *insn,unsigned int *data) |
325 +----------------------------------------------------------------------------+
326 | Task : Configures The Watchdog |
327 +----------------------------------------------------------------------------+
328 | Input Parameters : struct comedi_device *dev : Driver handle |
329 | struct comedi_subdevice *s, :pointer to subdevice structure |
330 | struct comedi_insn *insn :pointer to insn structure |
331 | unsigned int *data : Data Pointer to read status |
332 +----------------------------------------------------------------------------+
333 | Output Parameters : -- |
334 +----------------------------------------------------------------------------+
335 | Return Value : TRUE : No error occur |
336 | : FALSE : Error occur. Return the error |
337 | |
338 +----------------------------------------------------------------------------+
339 */
341  struct comedi_insn *insn, unsigned int *data)
342 {
343 
344  if (data[0] == 0) {
345  /* Disable the watchdog */
346  outw(0x0,
347  devpriv->i_IobaseAddon +
349  /* Loading the Reload value */
350  outw(data[1],
351  devpriv->i_IobaseAddon +
353  data[1] = data[1] >> 16;
354  outw(data[1],
355  devpriv->i_IobaseAddon +
357  } else {
358  printk("\nThe input parameters are wrong\n");
359  }
360  return insn->n;
361 }
362 
363 /*
364 +----------------------------------------------------------------------------+
365 | Function Name : int i_APCI2016_StartStopWriteWatchdog |
366 | (struct comedi_device *dev,struct comedi_subdevice *s, |
367 | struct comedi_insn *insn,unsigned int *data) |
368 +----------------------------------------------------------------------------+
369 | Task : Start / Stop The Watchdog |
370 +----------------------------------------------------------------------------+
371 | Input Parameters : struct comedi_device *dev : Driver handle |
372 | struct comedi_subdevice *s, :pointer to subdevice structure |
373 | struct comedi_insn *insn :pointer to insn structure |
374 | unsigned int *data : Data Pointer to read status |
375 +----------------------------------------------------------------------------+
376 | Output Parameters : -- |
377 +----------------------------------------------------------------------------+
378 | Return Value : TRUE : No error occur |
379 | : FALSE : Error occur. Return the error |
380 | |
381 +----------------------------------------------------------------------------+
382 */
384  struct comedi_insn *insn, unsigned int *data)
385 {
386 
387  switch (data[0]) {
388  case 0: /* stop the watchdog */
389  outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */
390  break;
391  case 1: /* start the watchdog */
392  outw(0x0001,
393  devpriv->i_IobaseAddon +
395  break;
396  case 2: /* Software trigger */
397  outw(0x0201,
398  devpriv->i_IobaseAddon +
400  break;
401  default:
402  printk("\nSpecified functionality does not exist\n");
403  return -EINVAL;
404  } /* switch(data[0]) */
405 
406  return insn->n;
407 }
408 
409 /*
410 +----------------------------------------------------------------------------+
411 | Function Name : int i_APCI2016_ReadWatchdog |
412 | (struct comedi_device *dev,struct comedi_subdevice *s, |
413 | struct comedi_insn *insn,unsigned int *data) |
414 +----------------------------------------------------------------------------+
415 | Task : Read The Watchdog |
416 +----------------------------------------------------------------------------+
417 | Input Parameters : struct comedi_device *dev : Driver handle |
418 | struct comedi_subdevice *s, :pointer to subdevice structure |
419 | struct comedi_insn *insn :pointer to insn structure |
420 | unsigned int *data : Data Pointer to read status |
421 +----------------------------------------------------------------------------+
422 | Output Parameters : -- |
423 +----------------------------------------------------------------------------+
424 | Return Value : TRUE : No error occur |
425 | : FALSE : Error occur. Return the error |
426 | |
427 +----------------------------------------------------------------------------+
428 */
429 
431  struct comedi_insn *insn, unsigned int *data)
432 {
433  udelay(5);
434  data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1;
435  return insn->n;
436 }
437 
438 /*
439 +----------------------------------------------------------------------------+
440 | Function Name : int i_APCI2016_Reset(struct comedi_device *dev) | |
441 +----------------------------------------------------------------------------+
442 | Task :resets all the registers |
443 +----------------------------------------------------------------------------+
444 | Input Parameters : struct comedi_device *dev
445 +----------------------------------------------------------------------------+
446 | Output Parameters : -- |
447 +----------------------------------------------------------------------------+
448 | Return Value : |
449 | |
450 +----------------------------------------------------------------------------+
451 */
452 
454 {
455  outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); /* Resets the digital output channels */
456  outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE);
457  outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE);
458  outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2);
459  return 0;
460 }