4 Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data.com
14 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 You should also find the complete GPL in the COPYING file accompanying this source code.
26 +-----------------------------------------------------------------------+
27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28 +-----------------------------------------------------------------------+
29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
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 +-----------------------------------------------------------------------+
40 +----------+-----------+------------------------------------------------+
41 | Date | Author | Description of updates |
42 +----------+-----------+------------------------------------------------+
46 +----------+-----------+------------------------------------------------+
49 /********* Definitions for APCI-2016 card *****/
51 #define APCI2016_ADDRESS_RANGE 8
53 /* DIGITAL INPUT-OUTPUT DEFINE */
55 #define APCI2016_DIGITAL_OP 0x04
56 #define APCI2016_DIGITAL_OP_RW 4
58 /* TIMER COUNTER WATCHDOG DEFINES */
60 #define ADDIDATA_WATCHDOG 2
61 #define APCI2016_DIGITAL_OP_WATCHDOG 0
62 #define APCI2016_WATCHDOG_ENABLEDISABLE 12
63 #define APCI2016_WATCHDOG_RELOAD_VALUE 4
64 #define APCI2016_WATCHDOG_STATUS 16
67 +----------------------------------------------------------------------------+
68 | Function Name : int i_APCI2016_ConfigDigitalOutput |
69 | (struct comedi_device *dev,struct comedi_subdevice *s, |
70 | struct comedi_insn *insn,unsigned int *data) |
71 +----------------------------------------------------------------------------+
72 | Task : Configures The Digital Output Subdevice. |
73 +----------------------------------------------------------------------------+
74 | Input Parameters : struct comedi_device *dev : Driver handle |
75 | unsigned int *data : Data Pointer contains |
76 | configuration parameters as below |
78 | data[0] : 1 Digital Memory On |
79 | 0 Digital Memory Off |
80 +----------------------------------------------------------------------------+
81 | Output Parameters : -- |
82 +----------------------------------------------------------------------------+
83 | Return Value : TRUE : No error occur |
84 | : FALSE : Error occur. Return the error |
86 +----------------------------------------------------------------------------+
88 static int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev,
89 struct comedi_subdevice *s,
90 struct comedi_insn *insn,
93 struct addi_private *devpriv = dev->private;
95 if ((data[0] != 0) && (data[0] != 1)) {
97 "Not a valid Data !!! ,Data should be 1 or 0\n");
99 } /* if ((data[0]!=0) && (data[0]!=1)) */
101 devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
104 devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
105 } /* else if (data[0] */
110 +----------------------------------------------------------------------------+
111 | Function Name : int i_APCI2016_WriteDigitalOutput |
112 | (struct comedi_device *dev,struct comedi_subdevice *s, |
113 | struct comedi_insn *insn,unsigned int *data) |
114 +----------------------------------------------------------------------------+
115 | Task : Writes port value To the selected port |
116 +----------------------------------------------------------------------------+
117 | Input Parameters : struct comedi_device *dev : Driver handle |
118 | unsigned int ui_NoOfChannels : No Of Channels To Write |
119 | unsigned int *data : Data Pointer to read status |
120 +----------------------------------------------------------------------------+
121 | Output Parameters : -- |
122 +----------------------------------------------------------------------------+
123 | Return Value : TRUE : No error occur |
124 | : FALSE : Error occur. Return the error |
126 +----------------------------------------------------------------------------+
128 static int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev,
129 struct comedi_subdevice *s,
130 struct comedi_insn *insn,
133 struct addi_private *devpriv = dev->private;
134 unsigned int ui_NoOfChannel;
135 unsigned int ui_Temp, ui_Temp1;
137 ui_NoOfChannel = CR_CHAN(insn->chanspec);
138 if (ui_NoOfChannel > 15) {
140 "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
142 } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */
143 if (devpriv->b_OutputMemoryStatus) {
144 ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP);
145 } /* if (devpriv->b_OutputMemoryStatus ) */
148 } /* else if (devpriv->b_OutputMemoryStatus ) */
149 if ((data[1] != 0) && (data[1] != 1)) {
151 "Invalid Data[1] value !!!, Data[1] should be 0 or 1\n");
153 } /* if ((data[1]!=0) && (data[1]!=1)) */
157 data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
158 outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP);
159 } /* if (data[1]==0) */
162 switch (ui_NoOfChannel) {
179 data[0] = data[0] | ui_Temp;
182 comedi_error(dev, " chan spec wrong");
183 return -EINVAL; /* "sorry channel spec wrong " */
184 } /* switch(ui_NoOfChannels) */
186 devpriv->iobase + APCI2016_DIGITAL_OP);
187 } /* if (data[1]==1) */
189 printk("\nSpecified channel not supported\n");
190 } /* else if (data[1]==1) */
191 } /* else if (data[1]==0) */
192 } /* if (data[3]==0) */
196 data[0] = ~data[0] & 0x1;
198 ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
199 ui_Temp = ui_Temp | ui_Temp1;
200 data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
201 data[0] = data[0] & ui_Temp;
203 devpriv->iobase + APCI2016_DIGITAL_OP);
204 } /* if (data[1]==0) */
207 switch (ui_NoOfChannel) {
209 data[0] = ~data[0] & 0x3;
212 ui_Temp1 << 2 * data[2];
213 ui_Temp = ui_Temp | ui_Temp1;
221 data[0] = ~data[0] & 0xf;
224 ui_Temp1 << 4 * data[2];
225 ui_Temp = ui_Temp | ui_Temp1;
233 data[0] = ~data[0] & 0xff;
236 ui_Temp1 << 8 * data[2];
237 ui_Temp = ui_Temp | ui_Temp1;
249 return -EINVAL; /* "sorry channel spec wrong " */
250 } /* switch(ui_NoOfChannels) */
253 APCI2016_DIGITAL_OP);
254 } /* if(data[1]==1) */
256 printk("\nSpecified channel not supported\n");
257 } /* else if(data[1]==1) */
258 } /* elseif(data[1]==0) */
259 } /* if(data[3]==1); */
261 printk("\nSpecified functionality does not exist\n");
263 } /* if else data[3]==1) */
264 } /* if else data[3]==0) */
269 +----------------------------------------------------------------------------+
270 | Function Name : int i_APCI2016_BitsDigitalOutput |
271 | (struct comedi_device *dev,struct comedi_subdevice *s, |
272 | struct comedi_insn *insn,unsigned int *data) |
273 +----------------------------------------------------------------------------+
274 | Task : Read value of the selected channel or port |
275 +----------------------------------------------------------------------------+
276 | Input Parameters : struct comedi_device *dev : Driver handle |
277 | unsigned int ui_NoOfChannels : No Of Channels To read |
278 | unsigned int *data : Data Pointer to read status |
279 +----------------------------------------------------------------------------+
280 | Output Parameters : -- |
281 +----------------------------------------------------------------------------+
282 | Return Value : TRUE : No error occur |
283 | : FALSE : Error occur. Return the error |
285 +----------------------------------------------------------------------------+
287 static int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev,
288 struct comedi_subdevice *s,
289 struct comedi_insn *insn,
292 struct addi_private *devpriv = dev->private;
293 unsigned int ui_Temp;
294 unsigned int ui_NoOfChannel;
296 ui_NoOfChannel = CR_CHAN(insn->chanspec);
297 if (ui_NoOfChannel > 15) {
299 "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
301 } /* if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15)) */
302 if ((data[0] != 0) && (data[0] != 1)) {
304 "Invalid Data[0] value !!!, Data[0] should be 0 or 1\n");
306 } /* if ((data[0]!=0) && (data[0]!=1)) */
308 *data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW);
310 *data = (*data >> ui_NoOfChannel) & 0x1;
311 } /* if (ui_Temp==0) */
314 switch (ui_NoOfChannel) {
316 *data = (*data >> (2 * data[1])) & 3;
320 *data = (*data >> (4 * data[1])) & 15;
324 *data = (*data >> (8 * data[1])) & 255;
331 comedi_error(dev, " chan spec wrong");
332 return -EINVAL; /* "sorry channel spec wrong " */
333 } /* switch(ui_NoOfChannel) */
334 } /* if (ui_Temp==1) */
336 printk("\nSpecified channel not supported \n");
337 } /* else if (ui_Temp==1) */
338 } /* if (ui_Temp==0) */
343 +----------------------------------------------------------------------------+
344 | Function Name : int i_APCI2016_ConfigWatchdog |
345 | (struct comedi_device *dev,struct comedi_subdevice *s, |
346 | struct comedi_insn *insn,unsigned int *data) |
347 +----------------------------------------------------------------------------+
348 | Task : Configures The Watchdog |
349 +----------------------------------------------------------------------------+
350 | Input Parameters : struct comedi_device *dev : Driver handle |
351 | struct comedi_subdevice *s, :pointer to subdevice structure |
352 | struct comedi_insn *insn :pointer to insn structure |
353 | unsigned int *data : Data Pointer to read status |
354 +----------------------------------------------------------------------------+
355 | Output Parameters : -- |
356 +----------------------------------------------------------------------------+
357 | Return Value : TRUE : No error occur |
358 | : FALSE : Error occur. Return the error |
360 +----------------------------------------------------------------------------+
362 static int i_APCI2016_ConfigWatchdog(struct comedi_device *dev,
363 struct comedi_subdevice *s,
364 struct comedi_insn *insn,
367 struct addi_private *devpriv = dev->private;
370 /* Disable the watchdog */
372 devpriv->i_IobaseAddon +
373 APCI2016_WATCHDOG_ENABLEDISABLE);
374 /* Loading the Reload value */
376 devpriv->i_IobaseAddon +
377 APCI2016_WATCHDOG_RELOAD_VALUE);
378 data[1] = data[1] >> 16;
380 devpriv->i_IobaseAddon +
381 APCI2016_WATCHDOG_RELOAD_VALUE + 2);
383 printk("\nThe input parameters are wrong\n");
389 +----------------------------------------------------------------------------+
390 | Function Name : int i_APCI2016_StartStopWriteWatchdog |
391 | (struct comedi_device *dev,struct comedi_subdevice *s, |
392 | struct comedi_insn *insn,unsigned int *data) |
393 +----------------------------------------------------------------------------+
394 | Task : Start / Stop The Watchdog |
395 +----------------------------------------------------------------------------+
396 | Input Parameters : struct comedi_device *dev : Driver handle |
397 | struct comedi_subdevice *s, :pointer to subdevice structure |
398 | struct comedi_insn *insn :pointer to insn structure |
399 | unsigned int *data : Data Pointer to read status |
400 +----------------------------------------------------------------------------+
401 | Output Parameters : -- |
402 +----------------------------------------------------------------------------+
403 | Return Value : TRUE : No error occur |
404 | : FALSE : Error occur. Return the error |
406 +----------------------------------------------------------------------------+
408 static int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev,
409 struct comedi_subdevice *s,
410 struct comedi_insn *insn,
413 struct addi_private *devpriv = dev->private;
416 case 0: /* stop the watchdog */
417 outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */
419 case 1: /* start the watchdog */
421 devpriv->i_IobaseAddon +
422 APCI2016_WATCHDOG_ENABLEDISABLE);
424 case 2: /* Software trigger */
426 devpriv->i_IobaseAddon +
427 APCI2016_WATCHDOG_ENABLEDISABLE);
430 printk("\nSpecified functionality does not exist\n");
432 } /* switch(data[0]) */
438 +----------------------------------------------------------------------------+
439 | Function Name : int i_APCI2016_ReadWatchdog |
440 | (struct comedi_device *dev,struct comedi_subdevice *s, |
441 | struct comedi_insn *insn,unsigned int *data) |
442 +----------------------------------------------------------------------------+
443 | Task : Read The Watchdog |
444 +----------------------------------------------------------------------------+
445 | Input Parameters : struct comedi_device *dev : Driver handle |
446 | struct comedi_subdevice *s, :pointer to subdevice structure |
447 | struct comedi_insn *insn :pointer to insn structure |
448 | unsigned int *data : Data Pointer to read status |
449 +----------------------------------------------------------------------------+
450 | Output Parameters : -- |
451 +----------------------------------------------------------------------------+
452 | Return Value : TRUE : No error occur |
453 | : FALSE : Error occur. Return the error |
455 +----------------------------------------------------------------------------+
458 static int i_APCI2016_ReadWatchdog(struct comedi_device *dev,
459 struct comedi_subdevice *s,
460 struct comedi_insn *insn,
463 struct addi_private *devpriv = dev->private;
466 data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1;
471 +----------------------------------------------------------------------------+
472 | Function Name : int i_APCI2016_Reset(struct comedi_device *dev) | |
473 +----------------------------------------------------------------------------+
474 | Task :resets all the registers |
475 +----------------------------------------------------------------------------+
476 | Input Parameters : struct comedi_device *dev
477 +----------------------------------------------------------------------------+
478 | Output Parameters : -- |
479 +----------------------------------------------------------------------------+
482 +----------------------------------------------------------------------------+
485 static int i_APCI2016_Reset(struct comedi_device *dev)
487 struct addi_private *devpriv = dev->private;
489 outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); /* Resets the digital output channels */
490 outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE);
491 outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE);
492 outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2);