Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[deliverable/linux.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci2200.c
CommitLineData
c995fe94
ADG
1/**
2@verbatim
3
4Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
5
356cdbcb
BP
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
25417922 11 http://www.addi-data.com
356cdbcb 12 info@addi-data.com
c995fe94
ADG
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
39cfb97b 20You should also find the complete GPL in the COPYING file accompanying this source code.
c995fe94
ADG
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-2200 | Compiler : GCC |
33 | Module name : hwdrv_apci2200.c| Version : 2.96 |
34 +-------------------------------+---------------------------------------+
35 | Project manager: Eric Stolz | Date : 02/12/2002 |
36 +-------------------------------+---------------------------------------+
6cd5a9a3 37 | Description : Hardware Layer Access For APCI-2200 |
c995fe94
ADG
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 |
34c43922 59| (struct comedi_device *dev,struct comedi_subdevice *s, |
90035c08 60| struct comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
61+----------------------------------------------------------------------------+
62| Task : Return the status of the digital input |
63+----------------------------------------------------------------------------+
71b5f4f1 64| Input Parameters : struct comedi_device *dev : Driver handle |
34c43922 65| struct comedi_subdevice *s, :pointer to subdevice structure
356cdbcb 66| struct comedi_insn *insn :pointer to insn structure |
790c5541 67| unsigned int *data : Data Pointer to read status |
c995fe94
ADG
68+----------------------------------------------------------------------------+
69| Output Parameters : -- |
70+----------------------------------------------------------------------------+
71| Return Value : TRUE : No error occur |
72| : FALSE : Error occur. Return the error |
73| |
74+----------------------------------------------------------------------------+
75*/
da91b269
BP
76int i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
77 struct comedi_insn *insn, unsigned int *data)
c995fe94 78{
117102b0
BP
79 unsigned int ui_TmpValue = 0;
80 unsigned int ui_Channel;
c995fe94 81 ui_Channel = CR_CHAN(insn->chanspec);
dc8af068 82 if (ui_Channel <= 7) {
117102b0 83 ui_TmpValue = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
c995fe94 84 *data = (ui_TmpValue >> ui_Channel) & 0x1;
2696fb57 85 } /* if(ui_Channel >= 0 && ui_Channel <=7) */
c995fe94
ADG
86 else {
87 printk("\nThe specified channel does not exist\n");
2696fb57
BP
88 return -EINVAL; /* "sorry channel spec wrong " */
89 } /* else if(ui_Channel >= 0 && ui_Channel <=7) */
c995fe94
ADG
90
91 return insn->n;
92}
93
94/*
95+----------------------------------------------------------------------------+
96| Function Name : int i_APCI2200_ReadMoreDigitalInput |
34c43922 97| (struct comedi_device *dev,struct comedi_subdevice *s, |
90035c08 98| struct comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
99+----------------------------------------------------------------------------+
100| Task : Return the status of the Requested digital inputs |
101+----------------------------------------------------------------------------+
71b5f4f1 102| Input Parameters : struct comedi_device *dev : Driver handle |
34c43922 103| struct comedi_subdevice *s, :pointer to subdevice structure
356cdbcb 104| struct comedi_insn *insn :pointer to insn structure |
790c5541 105| unsigned int *data : Data Pointer to read status |
c995fe94
ADG
106+----------------------------------------------------------------------------+
107| Output Parameters : -- |
108+----------------------------------------------------------------------------+
109| Return Value : TRUE : No error occur |
110| : FALSE : Error occur. Return the error |
111| |
112+----------------------------------------------------------------------------+
113*/
114
da91b269
BP
115int i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
116 struct comedi_insn *insn, unsigned int *data)
c995fe94
ADG
117{
118
117102b0
BP
119 unsigned int ui_PortValue = data[0];
120 unsigned int ui_Mask = 0;
121 unsigned int ui_NoOfChannels;
c995fe94
ADG
122
123 ui_NoOfChannels = CR_CHAN(insn->chanspec);
124
117102b0 125 *data = (unsigned int) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
c995fe94
ADG
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");
2696fb57 140 return -EINVAL; /* "sorry channel spec wrong " */
c995fe94 141 break;
2696fb57 142 } /* switch(ui_NoOfChannels) */
c995fe94
ADG
143
144 return insn->n;
145}
146
147/*
148+----------------------------------------------------------------------------+
71b5f4f1 149| Function Name : int i_APCI2200_ConfigDigitalOutput (struct comedi_device *dev,
356cdbcb 150| struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
151| |
152+----------------------------------------------------------------------------+
153| Task : Configures The Digital Output Subdevice. |
154+----------------------------------------------------------------------------+
71b5f4f1 155| Input Parameters : struct comedi_device *dev : Driver handle |
790c5541 156| unsigned int *data : Data Pointer contains |
c995fe94 157| configuration parameters as below |
34c43922 158| struct comedi_subdevice *s, :pointer to subdevice structure
356cdbcb 159| struct comedi_insn *insn :pointer to insn structure |
c995fe94
ADG
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*/
da91b269
BP
172int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
173 struct comedi_insn *insn, unsigned int *data)
c995fe94
ADG
174{
175 devpriv->b_OutputMemoryStatus = data[0];
176 return insn->n;
177}
178
179/*
180+----------------------------------------------------------------------------+
181| Function Name : int i_APCI2200_WriteDigitalOutput |
90035c08 182| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
356cdbcb 183| unsigned int *data) |
c995fe94
ADG
184+----------------------------------------------------------------------------+
185| Task : Writes port value To the selected port |
186+----------------------------------------------------------------------------+
71b5f4f1 187| Input Parameters : struct comedi_device *dev : Driver handle |
34c43922 188| struct comedi_subdevice *s, :pointer to subdevice structure
356cdbcb 189| struct comedi_insn *insn :pointer to insn structure |
790c5541 190| unsigned int *data : Data Pointer to read status |
c995fe94
ADG
191+----------------------------------------------------------------------------+
192| Output Parameters : -- |
193+----------------------------------------------------------------------------+
194| Return Value : TRUE : No error occur |
195| : FALSE : Error occur. Return the error |
196| |
197+----------------------------------------------------------------------------+
198*/
199
da91b269
BP
200int i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
201 struct comedi_insn *insn, unsigned int *data)
c995fe94 202{
117102b0 203 unsigned int ui_Temp, ui_Temp1;
2696fb57 204 unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
c995fe94
ADG
205 if (devpriv->b_OutputMemoryStatus) {
206 ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
207
2696fb57 208 } /* if(devpriv->b_OutputMemoryStatus ) */
c995fe94
ADG
209 else {
210 ui_Temp = 0;
2696fb57 211 } /* if(devpriv->b_OutputMemoryStatus ) */
c995fe94
ADG
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);
2696fb57 216 } /* if(data[1]==0) */
c995fe94
ADG
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");
2696fb57 243 return -EINVAL; /* "sorry channel spec wrong " */
c995fe94 244
2696fb57 245 } /* switch(ui_NoOfChannels) */
c995fe94
ADG
246
247 outw(data[0],
248 devpriv->iobase + APCI2200_DIGITAL_OP);
2696fb57 249 } /* if(data[1]==1) */
c995fe94
ADG
250 else {
251 printk("\nSpecified channel not supported\n");
2696fb57
BP
252 } /* else if(data[1]==1) */
253 } /* elseif(data[1]==0) */
254 } /* if(data[3]==0) */
c995fe94
ADG
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);
2696fb57 266 } /* if(data[1]==0) */
c995fe94
ADG
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");
2696fb57 315 return -EINVAL; /* "sorry channel spec wrong " */
c995fe94 316
2696fb57 317 } /* switch(ui_NoOfChannels) */
c995fe94
ADG
318
319 outw(data[0],
320 devpriv->iobase +
321 APCI2200_DIGITAL_OP);
2696fb57 322 } /* if(data[1]==1) */
c995fe94
ADG
323 else {
324 printk("\nSpecified channel not supported\n");
2696fb57
BP
325 } /* else if(data[1]==1) */
326 } /* elseif(data[1]==0) */
327 } /* if(data[3]==1); */
c995fe94
ADG
328 else {
329 printk("\nSpecified functionality does not exist\n");
330 return -EINVAL;
2696fb57
BP
331 } /* if else data[3]==1) */
332 } /* if else data[3]==0) */
dae0dc30 333 return insn->n;
c995fe94
ADG
334}
335
336/*
337+----------------------------------------------------------------------------+
338| Function Name : int i_APCI2200_ReadDigitalOutput |
90035c08 339| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
356cdbcb 340| unsigned int *data) |
c995fe94
ADG
341+----------------------------------------------------------------------------+
342| Task : Read value of the selected channel or port |
343+----------------------------------------------------------------------------+
71b5f4f1 344| Input Parameters : struct comedi_device *dev : Driver handle |
34c43922 345| struct comedi_subdevice *s, :pointer to subdevice structure
356cdbcb 346| struct comedi_insn *insn :pointer to insn structure |
790c5541 347| unsigned int *data : Data Pointer to read status |
c995fe94
ADG
348+----------------------------------------------------------------------------+
349| Output Parameters : -- |
350+----------------------------------------------------------------------------+
351| Return Value : TRUE : No error occur |
352| : FALSE : Error occur. Return the error |
353| |
354+----------------------------------------------------------------------------+
355*/
356
da91b269
BP
357int i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
358 struct comedi_insn *insn, unsigned int *data)
c995fe94
ADG
359{
360
117102b0 361 unsigned int ui_Temp;
2696fb57 362 unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec); /* get the channel */
c995fe94
ADG
363 ui_Temp = data[0];
364 *data = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
365 if (ui_Temp == 0) {
366 *data = (*data >> ui_NoOfChannel) & 0x1;
2696fb57 367 } /* if(ui_Temp==0) */
c995fe94
ADG
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");
2696fb57 389 return -EINVAL; /* "sorry channel spec wrong " */
c995fe94 390
2696fb57
BP
391 } /* switch(ui_NoOfChannels) */
392 } /* if(ui_Temp==1) */
c995fe94
ADG
393 else {
394 printk("\nSpecified channel not supported \n");
2696fb57
BP
395 } /* elseif(ui_Temp==1) */
396 } /* elseif(ui_Temp==0) */
c995fe94
ADG
397 return insn->n;
398}
399
400/*
401+----------------------------------------------------------------------------+
71b5f4f1 402| Function Name : int i_APCI2200_ConfigWatchdog(struct comedi_device *dev,
356cdbcb 403| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
c995fe94
ADG
404| |
405+----------------------------------------------------------------------------+
406| Task : Configures The Watchdog |
407+----------------------------------------------------------------------------+
71b5f4f1 408| Input Parameters : struct comedi_device *dev : Driver handle |
34c43922 409| struct comedi_subdevice *s, :pointer to subdevice structure
356cdbcb 410| struct comedi_insn *insn :pointer to insn structure |
790c5541 411| unsigned int *data : Data Pointer to read status |
c995fe94
ADG
412+----------------------------------------------------------------------------+
413| Output Parameters : -- |
414+----------------------------------------------------------------------------+
415| Return Value : TRUE : No error occur |
416| : FALSE : Error occur. Return the error |
417| |
418+----------------------------------------------------------------------------+
419*/
420
da91b269
BP
421int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
422 struct comedi_insn *insn, unsigned int *data)
c995fe94
ADG
423{
424 if (data[0] == 0) {
2696fb57 425 /* Disable the watchdog */
c995fe94
ADG
426 outw(0x0,
427 devpriv->iobase + APCI2200_WATCHDOG +
428 APCI2200_WATCHDOG_ENABLEDISABLE);
2696fb57 429 /* Loading the Reload value */
c995fe94
ADG
430 outw(data[1],
431 devpriv->iobase + APCI2200_WATCHDOG +
432 APCI2200_WATCHDOG_RELOAD_VALUE);
433 data[1] = data[1] >> 16;
434 outw(data[1],
435 devpriv->iobase + APCI2200_WATCHDOG +
436 APCI2200_WATCHDOG_RELOAD_VALUE + 2);
2696fb57 437 } /* if(data[0]==0) */
c995fe94
ADG
438 else {
439 printk("\nThe input parameters are wrong\n");
440 return -EINVAL;
2696fb57 441 } /* elseif(data[0]==0) */
c995fe94
ADG
442
443 return insn->n;
444}
445
446 /*
447 +----------------------------------------------------------------------------+
448 | Function Name : int i_APCI2200_StartStopWriteWatchdog |
34c43922 449 | (struct comedi_device *dev,struct comedi_subdevice *s,
90035c08 450 struct comedi_insn *insn,unsigned int *data); |
c995fe94
ADG
451 +----------------------------------------------------------------------------+
452 | Task : Start / Stop The Watchdog |
453 +----------------------------------------------------------------------------+
71b5f4f1 454 | Input Parameters : struct comedi_device *dev : Driver handle |
34c43922 455 | struct comedi_subdevice *s, :pointer to subdevice structure
90035c08 456 struct comedi_insn *insn :pointer to insn structure |
790c5541 457 | unsigned int *data : Data Pointer to read status |
c995fe94
ADG
458 +----------------------------------------------------------------------------+
459 | Output Parameters : -- |
460 +----------------------------------------------------------------------------+
461 | Return Value : TRUE : No error occur |
462 | : FALSE : Error occur. Return the error |
463 | |
464 +----------------------------------------------------------------------------+
465 */
466
da91b269
BP
467int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
468 struct comedi_insn *insn, unsigned int *data)
c995fe94
ADG
469{
470 switch (data[0]) {
2696fb57
BP
471 case 0: /* stop the watchdog */
472 outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE); /* disable the watchdog */
c995fe94 473 break;
2696fb57 474 case 1: /* start the watchdog */
c995fe94
ADG
475 outw(0x0001,
476 devpriv->iobase + APCI2200_WATCHDOG +
477 APCI2200_WATCHDOG_ENABLEDISABLE);
478 break;
2696fb57 479 case 2: /* Software trigger */
c995fe94
ADG
480 outw(0x0201,
481 devpriv->iobase + APCI2200_WATCHDOG +
482 APCI2200_WATCHDOG_ENABLEDISABLE);
483 break;
484 default:
485 printk("\nSpecified functionality does not exist\n");
486 return -EINVAL;
2696fb57 487 } /* switch(data[0]) */
c995fe94
ADG
488 return insn->n;
489}
490
491/*
492+----------------------------------------------------------------------------+
493| Function Name : int i_APCI2200_ReadWatchdog |
90035c08 494| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
356cdbcb 495| unsigned int *data); |
c995fe94
ADG
496+----------------------------------------------------------------------------+
497| Task : Read The Watchdog |
498+----------------------------------------------------------------------------+
71b5f4f1 499| Input Parameters : struct comedi_device *dev : Driver handle |
34c43922 500| struct comedi_subdevice *s, :pointer to subdevice structure
356cdbcb 501| struct comedi_insn *insn :pointer to insn structure |
790c5541 502| unsigned int *data : Data Pointer to read status |
c995fe94
ADG
503+----------------------------------------------------------------------------+
504| Output Parameters : -- |
505+----------------------------------------------------------------------------+
506| Return Value : TRUE : No error occur |
507| : FALSE : Error occur. Return the error |
508| |
509+----------------------------------------------------------------------------+
510*/
511
da91b269
BP
512int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
513 struct comedi_insn *insn, unsigned int *data)
c995fe94
ADG
514{
515 data[0] =
516 inw(devpriv->iobase + APCI2200_WATCHDOG +
517 APCI2200_WATCHDOG_STATUS) & 0x1;
518 return insn->n;
519}
520
521/*
522+----------------------------------------------------------------------------+
71b5f4f1 523| Function Name : int i_APCI2200_Reset(struct comedi_device *dev) | |
c995fe94
ADG
524+----------------------------------------------------------------------------+
525| Task :resets all the registers |
526+----------------------------------------------------------------------------+
71b5f4f1 527| Input Parameters : struct comedi_device *dev
c995fe94
ADG
528+----------------------------------------------------------------------------+
529| Output Parameters : -- |
530+----------------------------------------------------------------------------+
531| Return Value : |
532| |
533+----------------------------------------------------------------------------+
534*/
535
da91b269 536int i_APCI2200_Reset(struct comedi_device *dev)
c995fe94 537{
2696fb57 538 outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP); /* RESETS THE DIGITAL OUTPUTS */
c995fe94
ADG
539 outw(0x0,
540 devpriv->iobase + APCI2200_WATCHDOG +
541 APCI2200_WATCHDOG_ENABLEDISABLE);
542 outw(0x0,
543 devpriv->iobase + APCI2200_WATCHDOG +
544 APCI2200_WATCHDOG_RELOAD_VALUE);
545 outw(0x0,
546 devpriv->iobase + APCI2200_WATCHDOG +
547 APCI2200_WATCHDOG_RELOAD_VALUE + 2);
548 return 0;
549}
This page took 0.197384 seconds and 5 git commands to generate.