hwdrv_apci1516.c revision 90035c0886b256d75bced13b3b3cea5234aff136
1/**
2@verbatim
3
4Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
5
6        ADDI-DATA GmbH
7        Dieselstrasse 3
8        D-77833 Ottersweier
9        Tel: +19(0)7223/9493-0
10        Fax: +49(0)7223/9493-92
11        http://www.addi-data-com
12        info@addi-data.com
13
14This 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.
15
16This 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.
17
18You 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
19
20You shoud also find the complete GPL in the COPYING file accompanying this source code.
21
22@endverbatim
23*/
24/*
25
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-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 Acces 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*/
76INT i_APCI1516_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
77	struct comedi_insn * insn, unsigned int * data)
78{
79	UINT ui_TmpValue = 0;
80	UINT ui_Channel;
81	ui_Channel = CR_CHAN(insn->chanspec);
82	if (ui_Channel >= 0 && ui_Channel <= 7) {
83		ui_TmpValue = (UINT) 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
117INT i_APCI1516_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
118	struct comedi_insn * insn, unsigned int * data)
119{
120
121	UINT ui_PortValue = data[0];
122	UINT ui_Mask = 0;
123	UINT ui_NoOfChannels;
124
125	ui_NoOfChannels = CR_CHAN(insn->chanspec);
126
127	*data = (UINT) 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*/
174int i_APCI1516_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
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
202INT i_APCI1516_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
203	struct comedi_insn * insn, unsigned int * data)
204{
205	UINT ui_Temp, ui_Temp1;
206	UINT 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 +
321						APCI1516_DIGITAL_OP);
322
323					printk("EL311003 : d=%d @=%x\n",
324						data[0],
325						devpriv->iobase +
326						APCI1516_DIGITAL_OP);
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
362INT i_APCI1516_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
363	struct comedi_insn * insn, unsigned int * data)
364{
365
366	UINT ui_Temp;
367	UINT 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
422int i_APCI1516_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
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 +
429			APCI1516_WATCHDOG_ENABLEDISABLE);
430		//Loading the Reload value
431		outw(data[1],
432			devpriv->i_IobaseAddon +
433			APCI1516_WATCHDOG_RELOAD_VALUE);
434		data[1] = data[1] >> 16;
435		outw(data[1],
436			devpriv->i_IobaseAddon +
437			APCI1516_WATCHDOG_RELOAD_VALUE + 2);
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
468int i_APCI1516_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
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 +
478			APCI1516_WATCHDOG_ENABLEDISABLE);
479		break;
480	case 2:		//Software trigger
481		outw(0x0201,
482			devpriv->i_IobaseAddon +
483			APCI1516_WATCHDOG_ENABLEDISABLE);
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
513int i_APCI1516_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
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
535INT i_APCI1516_Reset(struct comedi_device * dev)
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}
543