Staging: comedi: Remove C99 comments
[pandora-kernel.git] / drivers / staging / comedi / drivers / addi-data / APCI1710_Dig_io.c
1 /**
2 @verbatim
3
4 Copyright (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
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.
15
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.
17
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
19
20 You 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     : API APCI1710    | Compiler : gcc                        |
33   | Module name : DIG_IO.C        | Version  : 2.96                       |
34   +-------------------------------+---------------------------------------+
35   | Project manager: Eric Stolz   | Date     :  02/12/2002                |
36   +-----------------------------------------------------------------------+
37   | Description :   APCI-1710 digital I/O module                          |
38   |                                                                       |
39   |                                                                       |
40   +-----------------------------------------------------------------------+
41   |                             UPDATES                                   |
42   +-----------------------------------------------------------------------+
43   |   Date   |   Author  |          Description of updates                |
44   +----------+-----------+------------------------------------------------+
45   | 16/06/98 | S. Weber  | Digital input / output implementation          |
46   |----------|-----------|------------------------------------------------|
47   | 08/05/00 | Guinot C  | - 0400/0228 All Function in RING 0             |
48   |          |           |   available                                    |
49   +-----------------------------------------------------------------------+
50   |          |           |                                                |
51   |          |           |                                                |
52   +-----------------------------------------------------------------------+
53 */
54
55 /*
56 +----------------------------------------------------------------------------+
57 |                               Included files                               |
58 +----------------------------------------------------------------------------+
59 */
60 #include "APCI1710_Dig_io.h"
61
62 /*
63 +----------------------------------------------------------------------------+
64 | Function Name     : int i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, |
65 |                                               struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
66 +----------------------------------------------------------------------------+
67 | Task              : Configure the digital I/O operating mode from selected |
68 |                     module  (b_ModulNbr). You must calling this function be|
69 |                     for you call any other function witch access of digital|
70 |                     I/O.                                                   |
71 +----------------------------------------------------------------------------+
72 | Input Parameters  :                                                                                                        |
73 |                  unsigned char_ b_ModulNbr      data[0]: Module number to               |
74 |                                             configure (0 to 3)             |
75 |                     unsigned char_ b_ChannelAMode data[1]  : Channel A mode selection       |
76 |                                             0 : Channel used for digital   |
77 |                                                 input                      |
78 |                                             1 : Channel used for digital   |
79 |                                                 output                     |
80 |                     unsigned char_ b_ChannelBMode data[2] : Channel B mode selection       |
81 |                                             0 : Channel used for digital   |
82 |                                                 input                      |
83 |                                             1 : Channel used for digital   |
84 |                                                 output                                         |
85                                                 data[0]   memory on/off
86 Activates and deactivates the digital output memory.
87                                                 After having      |
88 |                 called up this function with memory on,the output you have previously|
89 |                     activated with the function are not reset
90 +----------------------------------------------------------------------------+
91 | Output Parameters : -                                                      |
92 +----------------------------------------------------------------------------+
93 | Return Value      : 0: No error                                            |
94 |                    -1: The handle parameter of the board is wrong          |
95 |                    -2: The module parameter is wrong                       |
96 |                    -3: The module is not a digital I/O module              |
97 |                    -4: Bi-directional channel A configuration error        |
98 |                    -5: Bi-directional channel B configuration error        |
99 +----------------------------------------------------------------------------+
100 */
101
102 int i_APCI1710_InsnConfigDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
103         struct comedi_insn * insn, unsigned int * data)
104 {
105         unsigned char b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
106         unsigned char b_MemoryOnOff, b_ConfigType;
107         int i_ReturnValue = 0;
108         unsigned int dw_WriteConfig = 0;
109
110         b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
111         b_ConfigType = (unsigned char) data[0]; /*  Memory or  Init */
112         b_ChannelAMode = (unsigned char) data[1];
113         b_ChannelBMode = (unsigned char) data[2];
114         b_MemoryOnOff = (unsigned char) data[1];        /*  if memory operation */
115         i_ReturnValue = insn->n;
116
117                 /**************************/
118         /* Test the module number */
119                 /**************************/
120
121         if (b_ModulNbr >= 4) {
122                 DPRINTK("Module Number invalid\n");
123                 i_ReturnValue = -2;
124                 return i_ReturnValue;
125         }
126         switch (b_ConfigType) {
127         case APCI1710_DIGIO_MEMORYONOFF:
128
129                 if (b_MemoryOnOff)      /*  If Memory ON */
130                 {
131                  /****************************/
132                         /* Set the output memory on */
133                  /****************************/
134
135                         devpriv->s_ModuleInfo[b_ModulNbr].
136                                 s_DigitalIOInfo.b_OutputMemoryEnabled = 1;
137
138                  /***************************/
139                         /* Clear the output memory */
140                  /***************************/
141                         devpriv->s_ModuleInfo[b_ModulNbr].
142                                 s_DigitalIOInfo.dw_OutputMemory = 0;
143                 } else          /*  If memory off */
144                 {
145                  /*****************************/
146                         /* Set the output memory off */
147                  /*****************************/
148
149                         devpriv->s_ModuleInfo[b_ModulNbr].
150                                 s_DigitalIOInfo.b_OutputMemoryEnabled = 0;
151                 }
152                 break;
153
154         case APCI1710_DIGIO_INIT:
155
156         /*******************************/
157                 /* Test if digital I/O counter */
158         /*******************************/
159
160                 if ((devpriv->s_BoardInfos.
161                                 dw_MolduleConfiguration[b_ModulNbr] &
162                                 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
163
164         /***************************************************/
165                         /* Test the bi-directional channel A configuration */
166         /***************************************************/
167
168                         if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1)) {
169         /***************************************************/
170                                 /* Test the bi-directional channel B configuration */
171         /***************************************************/
172
173                                 if ((b_ChannelBMode == 0)
174                                         || (b_ChannelBMode == 1)) {
175                                         devpriv->s_ModuleInfo[b_ModulNbr].
176                                                 s_DigitalIOInfo.b_DigitalInit =
177                                                 1;
178
179         /********************************/
180                                         /* Save channel A configuration */
181         /********************************/
182
183                                         devpriv->s_ModuleInfo[b_ModulNbr].
184                                                 s_DigitalIOInfo.
185                                                 b_ChannelAMode = b_ChannelAMode;
186
187         /********************************/
188                                         /* Save channel B configuration */
189         /********************************/
190
191                                         devpriv->s_ModuleInfo[b_ModulNbr].
192                                                 s_DigitalIOInfo.
193                                                 b_ChannelBMode = b_ChannelBMode;
194
195         /*****************************************/
196                                         /* Set the channel A and B configuration */
197         /*****************************************/
198
199                                         dw_WriteConfig =
200                                                 (unsigned int) (b_ChannelAMode |
201                                                 (b_ChannelBMode * 2));
202
203         /***************************/
204                                         /* Write the configuration */
205         /***************************/
206
207                                         outl(dw_WriteConfig,
208                                                 devpriv->s_BoardInfos.
209                                                 ui_Address + 4 +
210                                                 (64 * b_ModulNbr));
211
212                                 } else {
213         /************************************************/
214                                         /* Bi-directional channel B configuration error */
215         /************************************************/
216                                         DPRINTK("Bi-directional channel B configuration error\n");
217                                         i_ReturnValue = -5;
218                                 }
219
220                         } else {
221         /************************************************/
222                                 /* Bi-directional channel A configuration error */
223         /************************************************/
224                                 DPRINTK("Bi-directional channel A configuration error\n");
225                                 i_ReturnValue = -4;
226
227                         }
228
229                 } else {
230         /******************************************/
231                         /* The module is not a digital I/O module */
232         /******************************************/
233                         DPRINTK("The module is not a digital I/O module\n");
234                         i_ReturnValue = -3;
235                 }
236         }                       /*  end of Switch */
237         printk("Return Value %d\n", i_ReturnValue);
238         return i_ReturnValue;
239 }
240
241 /*
242 +----------------------------------------------------------------------------+
243 |                            INPUT FUNCTIONS                                 |
244 +----------------------------------------------------------------------------+
245 */
246
247 /*
248 +----------------------------------------------------------------------------+
249
250 |INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,comedi_subdevice
251 *s,     struct comedi_insn *insn,unsigned int *data)
252
253 +----------------------------------------------------------------------------+
254 | Task              : Read the status from selected digital I/O digital input|
255 |                     (b_InputChannel)                                       |
256 +----------------------------------------------------------------------------|
257
258
259 |
260 |  unsigned char_ b_ModulNbr  CR_AREF(chanspec)          : Selected module number   |
261 |                                                   (0 to 3)                 |
262 |  unsigned char_ b_InputChannel CR_CHAN(chanspec)        : Selection from digital   |
263 |                                                   input ( 0 to 6)          |
264 |                                                      0 : Channel C         |
265 |                                                      1 : Channel D         |
266 |                                                      2 : Channel E         |
267 |                                                      3 : Channel F         |
268 |                                                      4 : Channel G         |
269 |                                                      5 : Channel A         |
270 |                                                      6 : Channel B
271
272
273         |
274 +----------------------------------------------------------------------------+
275 | Output Parameters :                                    data[0]   : Digital input channel    |
276 |                                                   status                   |
277 |                                                   0 : Channle is not active|
278 |                                                   1 : Channle is active    |
279 +----------------------------------------------------------------------------+
280 | Return Value      : 0: No error                                            |
281 |                    -1: The handle parameter of the board is wrong          |
282 |                    -2: The module parameter is wrong                       |
283 |                    -3: The module is not a digital I/O module              |
284 |                    -4: The selected digital I/O digital input is wrong     |
285 |                    -5: Digital I/O not initialised                         |
286 |                    -6: The digital channel A is used for output            |
287 |                    -7: The digital channel B is used for output            |
288 +----------------------------------------------------------------------------+
289 */
290
291 /* _INT_   i_APCI1710_ReadDigitalIOChlValue      (unsigned char_    b_BoardHandle, */
292 /*
293 * unsigned char_ b_ModulNbr, unsigned char_ b_InputChannel,
294 * unsigned char *_ pb_ChannelStatus)
295 */
296 int i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device * dev,
297         struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
298 {
299         int i_ReturnValue = 0;
300         unsigned int dw_StatusReg;
301         unsigned char b_ModulNbr, b_InputChannel;
302         unsigned char * pb_ChannelStatus;
303         b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
304         b_InputChannel = (unsigned char) CR_CHAN(insn->chanspec);
305         data[0] = 0;
306         pb_ChannelStatus = (unsigned char *) & data[0];
307         i_ReturnValue = insn->n;
308
309         /**************************/
310         /* Test the module number */
311         /**************************/
312
313         if (b_ModulNbr < 4) {
314            /*******************************/
315                 /* Test if digital I/O counter */
316            /*******************************/
317
318                 if ((devpriv->s_BoardInfos.
319                                 dw_MolduleConfiguration[b_ModulNbr] &
320                                 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
321               /******************************************/
322                         /* Test the digital imnput channel number */
323               /******************************************/
324
325                         if (b_InputChannel <= 6) {
326                  /**********************************************/
327                                 /* Test if the digital I/O module initialised */
328                  /**********************************************/
329
330                                 if (devpriv->s_ModuleInfo[b_ModulNbr].
331                                         s_DigitalIOInfo.b_DigitalInit == 1) {
332                     /**********************************/
333                                         /* Test if channel A or channel B */
334                     /**********************************/
335
336                                         if (b_InputChannel > 4) {
337                        /*********************/
338                                                 /* Test if channel A */
339                        /*********************/
340
341                                                 if (b_InputChannel == 5) {
342                           /***************************/
343                                                         /* Test the channel A mode */
344                           /***************************/
345
346                                                         if (devpriv->
347                                                                 s_ModuleInfo
348                                                                 [b_ModulNbr].
349                                                                 s_DigitalIOInfo.
350                                                                 b_ChannelAMode
351                                                                 != 0) {
352                              /********************************************/
353                                                                 /* The digital channel A is used for output */
354                              /********************************************/
355
356                                                                 i_ReturnValue =
357                                                                         -6;
358                                                         }
359                                                 }       /*  if (b_InputChannel == 5) */
360                                                 else {
361                           /***************************/
362                                                         /* Test the channel B mode */
363                           /***************************/
364
365                                                         if (devpriv->
366                                                                 s_ModuleInfo
367                                                                 [b_ModulNbr].
368                                                                 s_DigitalIOInfo.
369                                                                 b_ChannelBMode
370                                                                 != 0) {
371                              /********************************************/
372                                                                 /* The digital channel B is used for output */
373                              /********************************************/
374
375                                                                 i_ReturnValue =
376                                                                         -7;
377                                                         }
378                                                 }       /*  if (b_InputChannel == 5) */
379                                         }       /*  if (b_InputChannel > 4) */
380
381                     /***********************/
382                                         /* Test if error occur */
383                     /***********************/
384
385                                         if (i_ReturnValue >= 0) {
386                        /**************************/
387                                                 /* Read all digital input */
388                        /**************************/
389
390 /*
391 * INPDW (ps_APCI1710Variable-> s_Board [b_BoardHandle].
392 * s_BoardInfos. ui_Address + (64 * b_ModulNbr), &dw_StatusReg);
393 */
394
395                                                 dw_StatusReg =
396                                                         inl(devpriv->
397                                                         s_BoardInfos.
398                                                         ui_Address +
399                                                         (64 * b_ModulNbr));
400
401                                                 *pb_ChannelStatus =
402                                                         (unsigned char) ((dw_StatusReg ^
403                                                                 0x1C) >>
404                                                         b_InputChannel) & 1;
405
406                                         }       /*  if (i_ReturnValue == 0) */
407                                 } else {
408                     /*******************************/
409                                         /* Digital I/O not initialised */
410                     /*******************************/
411                                         DPRINTK("Digital I/O not initialised\n");
412                                         i_ReturnValue = -5;
413                                 }
414                         } else {
415                  /********************************/
416                                 /* Selected digital input error */
417                  /********************************/
418                                 DPRINTK("Selected digital input error\n");
419                                 i_ReturnValue = -4;
420                         }
421                 } else {
422               /******************************************/
423                         /* The module is not a digital I/O module */
424               /******************************************/
425                         DPRINTK("The module is not a digital I/O module\n");
426                         i_ReturnValue = -3;
427                 }
428         } else {
429            /***********************/
430                 /* Module number error */
431            /***********************/
432                 DPRINTK("Module number error\n");
433                 i_ReturnValue = -2;
434         }
435
436         return (i_ReturnValue);
437 }
438
439 /*
440 +----------------------------------------------------------------------------+
441 |                            OUTPUT FUNCTIONS                                |
442 +----------------------------------------------------------------------------+
443 */
444
445 /*
446 +----------------------------------------------------------------------------+
447 | Function Name     : int i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device
448 |*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
449
450 +----------------------------------------------------------------------------+
451 | Task              : Sets or resets the output witch has been passed with the         |
452 |                     parameter b_Channel. Setting an output means setting   |
453 |                     an ouput high.                                         |
454 +----------------------------------------------------------------------------+
455 | Input Parameters  : unsigned char_ b_BoardHandle   : Handle of board APCI-1710      |
456 |                     unsigned char_ b_ModulNbr (aref )    : Selected module number (0 to 3)|
457 |                     unsigned char_ b_OutputChannel (CR_CHAN) : Selection from digital output  |
458 |                                             channel (0 to 2)               |
459 |                                                0 : Channel H               |
460 |                                                1 : Channel A               |
461 |                                                2 : Channel B               |
462 +----------------------------------------------------------------------------+
463 | Output Parameters : -                                                      |
464 +----------------------------------------------------------------------------+
465 | Return Value      : 0: No error                                            |
466 |                    -1: The handle parameter of the board is wrong          |
467 |                    -2: The module parameter is wrong                       |
468 |                    -3: The module is not a digital I/O module              |
469 |                    -4: The selected digital output is wrong                |
470 |                    -5: digital I/O not initialised see function            |
471 |                        " i_APCI1710_InitDigitalIO"                         |
472 |                    -6: The digital channel A is used for input             |
473 |                    -7: The digital channel B is used for input
474                                          -8: Digital Output Memory OFF.                          |
475 |                        Use previously the function                         |
476 |                        "i_APCI1710_SetDigitalIOMemoryOn".            |
477 +----------------------------------------------------------------------------+
478 */
479
480 /*
481 * _INT_ i_APCI1710_SetDigitalIOChlOn (unsigned char_ b_BoardHandle,
482 * unsigned char_ b_ModulNbr, unsigned char_ b_OutputChannel)
483 */
484 int i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device * dev,
485         struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
486 {
487         int i_ReturnValue = 0;
488         unsigned int dw_WriteValue = 0;
489         unsigned char b_ModulNbr, b_OutputChannel;
490         i_ReturnValue = insn->n;
491         b_ModulNbr = CR_AREF(insn->chanspec);
492         b_OutputChannel = CR_CHAN(insn->chanspec);
493
494         /**************************/
495         /* Test the module number */
496         /**************************/
497
498         if (b_ModulNbr < 4) {
499            /*******************************/
500                 /* Test if digital I/O counter */
501            /*******************************/
502
503                 if ((devpriv->s_BoardInfos.
504                                 dw_MolduleConfiguration[b_ModulNbr] &
505                                 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
506               /**********************************************/
507                         /* Test if the digital I/O module initialised */
508               /**********************************************/
509
510                         if (devpriv->s_ModuleInfo[b_ModulNbr].
511                                 s_DigitalIOInfo.b_DigitalInit == 1) {
512                  /******************************************/
513                                 /* Test the digital output channel number */
514                  /******************************************/
515
516                                 switch (b_OutputChannel) {
517                     /*************/
518                                         /* Channel H */
519                     /*************/
520
521                                 case 0:
522                                         break;
523
524                     /*************/
525                                         /* Channel A */
526                     /*************/
527
528                                 case 1:
529                                         if (devpriv->s_ModuleInfo[b_ModulNbr].
530                                                 s_DigitalIOInfo.
531                                                 b_ChannelAMode != 1) {
532                             /*******************************************/
533                                                 /* The digital channel A is used for input */
534                             /*******************************************/
535
536                                                 i_ReturnValue = -6;
537                                         }
538                                         break;
539
540                     /*************/
541                                         /* Channel B */
542                     /*************/
543
544                                 case 2:
545                                         if (devpriv->s_ModuleInfo[b_ModulNbr].
546                                                 s_DigitalIOInfo.
547                                                 b_ChannelBMode != 1) {
548                             /*******************************************/
549                                                 /* The digital channel B is used for input */
550                             /*******************************************/
551
552                                                 i_ReturnValue = -7;
553                                         }
554                                         break;
555
556                                 default:
557                          /****************************************/
558                                         /* The selected digital output is wrong */
559                          /****************************************/
560
561                                         i_ReturnValue = -4;
562                                         break;
563                                 }
564
565                  /***********************/
566                                 /* Test if error occur */
567                  /***********************/
568
569                                 if (i_ReturnValue >= 0) {
570
571                         /*********************************/
572                                         /* Test if set channel ON        */
573                     /*********************************/
574                                         if (data[0]) {
575                     /*********************************/
576                                                 /* Test if output memory enabled */
577                     /*********************************/
578
579                                                 if (devpriv->
580                                                         s_ModuleInfo
581                                                         [b_ModulNbr].
582                                                         s_DigitalIOInfo.
583                                                         b_OutputMemoryEnabled ==
584                                                         1) {
585                                                         dw_WriteValue =
586                                                                 devpriv->
587                                                                 s_ModuleInfo
588                                                                 [b_ModulNbr].
589                                                                 s_DigitalIOInfo.
590                                                                 dw_OutputMemory
591                                                                 | (1 <<
592                                                                 b_OutputChannel);
593
594                                                         devpriv->
595                                                                 s_ModuleInfo
596                                                                 [b_ModulNbr].
597                                                                 s_DigitalIOInfo.
598                                                                 dw_OutputMemory
599                                                                 = dw_WriteValue;
600                                                 } else {
601                                                         dw_WriteValue =
602                                                                 1 <<
603                                                                 b_OutputChannel;
604                                                 }
605                                         }       /*  set channel off */
606                                         else {
607                                                 if (devpriv->
608                                                         s_ModuleInfo
609                                                         [b_ModulNbr].
610                                                         s_DigitalIOInfo.
611                                                         b_OutputMemoryEnabled ==
612                                                         1) {
613                                                         dw_WriteValue =
614                                                                 devpriv->
615                                                                 s_ModuleInfo
616                                                                 [b_ModulNbr].
617                                                                 s_DigitalIOInfo.
618                                                                 dw_OutputMemory
619                                                                 & (0xFFFFFFFFUL
620                                                                 -
621                                                                 (1 << b_OutputChannel));
622
623                                                         devpriv->
624                                                                 s_ModuleInfo
625                                                                 [b_ModulNbr].
626                                                                 s_DigitalIOInfo.
627                                                                 dw_OutputMemory
628                                                                 = dw_WriteValue;
629                                                 } else {
630                                                         /*****************************/
631                                                         /* Digital Output Memory OFF */
632                                                         /*****************************/
633                                                         /*  +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn" */
634                                                         i_ReturnValue = -8;
635                                                 }
636
637                                         }
638                                         /*******************/
639                                         /* Write the value */
640                                         /*******************/
641
642                                         /* OUTPDW (ps_APCI1710Variable->
643                                          * s_Board [b_BoardHandle].
644                                          * s_BoardInfos. ui_Address + (64 * b_ModulNbr),
645                                          * dw_WriteValue);
646                                          */
647 */
648                                         outl(dw_WriteValue,
649                                                 devpriv->s_BoardInfos.
650                                                 ui_Address + (64 * b_ModulNbr));
651                                 }
652                         } else {
653                  /*******************************/
654                                 /* Digital I/O not initialised */
655                  /*******************************/
656
657                                 i_ReturnValue = -5;
658                         }
659                 } else {
660               /******************************************/
661                         /* The module is not a digital I/O module */
662               /******************************************/
663
664                         i_ReturnValue = -3;
665                 }
666         } else {
667            /***********************/
668                 /* Module number error */
669            /***********************/
670
671                 i_ReturnValue = -2;
672         }
673
674         return (i_ReturnValue);
675 }
676
677 /*
678 +----------------------------------------------------------------------------+
679
680 |INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice
681         *s,     struct comedi_insn *insn,unsigned int *data)
682 +----------------------------------------------------------------------------+
683 | Task              : write:
684                                           Sets or resets one or several outputs from port.                 |
685 |                     Setting an output means setting an output high.        |
686 |                     If you have switched OFF the digital output memory     |
687 |                     (OFF), all the other output are set to "0".
688
689 |                      read:
690                                           Read the status from digital input port                |
691 |                     from selected digital I/O module (b_ModulNbr)
692 +----------------------------------------------------------------------------+
693 | Input Parameters  :
694         unsigned char_ b_BoardHandle   : Handle of board APCI-1710      |
695 |   unsigned char_ b_ModulNbr  CR_AREF(aref)    : Selected module number (0 to 3)|
696 |   unsigned char_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 )
697 |                       data[0]           read or write port
698                         data[1]            if write then indicate ON or OFF
699
700                         if read : data[1] will return port status.
701 +----------------------------------------------------------------------------+
702 | Output Parameters : -                                                      |
703 +----------------------------------------------------------------------------+
704 | Return Value      :
705
706                 INPUT :
707
708                                           0: No error                                            |
709 |                    -1: The handle parameter of the board is wrong          |
710 |                    -2: The module parameter is wrong                       |
711 |                    -3: The module is not a digital I/O module              |
712 |                    -4: Digital I/O not initialised
713
714                                 OUTPUT:   0: No error                                            |
715 |                    -1: The handle parameter of the board is wrong          |
716 |                    -2: The module parameter is wrong                       |
717 |                    -3: The module is not a digital I/O module              |
718 |                    -4: Output value wrong                                  |
719 |                    -5: digital I/O not initialised see function            |
720 |                        " i_APCI1710_InitDigitalIO"                         |
721 |                    -6: The digital channel A is used for input             |
722 |                    -7: The digital channel B is used for input
723                                         -8: Digital Output Memory OFF.                          |
724 |                        Use previously the function                         |
725 |                        "i_APCI1710_SetDigitalIOMemoryOn".               |
726 +----------------------------------------------------------------------------+
727 */
728
729 /*
730  * _INT_ i_APCI1710_SetDigitalIOPortOn (unsigned char_
731  * b_BoardHandle, unsigned char_ b_ModulNbr, unsigned char_
732  * b_PortValue)
733 */
734 int i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device * dev,
735         struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
736 {
737         int i_ReturnValue = 0;
738         unsigned int dw_WriteValue = 0;
739         unsigned int dw_StatusReg;
740         unsigned char b_ModulNbr, b_PortValue;
741         unsigned char b_PortOperation, b_PortOnOFF;
742
743         unsigned char * pb_PortValue;
744
745         b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
746         b_PortOperation = (unsigned char) data[0];      /*  Input or output */
747         b_PortOnOFF = (unsigned char) data[1];  /*  if output then On or Off */
748         b_PortValue = (unsigned char) data[2];  /*  if out put then Value */
749         i_ReturnValue = insn->n;
750         pb_PortValue = (unsigned char *) & data[0];
751 /* if input then read value */
752
753         switch (b_PortOperation) {
754         case APCI1710_INPUT:
755                 /**************************/
756                 /* Test the module number */
757                 /**************************/
758
759                 if (b_ModulNbr < 4) {
760                         /*******************************/
761                         /* Test if digital I/O counter */
762                         /*******************************/
763
764                         if ((devpriv->s_BoardInfos.
765                                         dw_MolduleConfiguration[b_ModulNbr] &
766                                         0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
767                                 /**********************************************/
768                                 /* Test if the digital I/O module initialised */
769                                 /**********************************************/
770
771                                 if (devpriv->s_ModuleInfo[b_ModulNbr].
772                                         s_DigitalIOInfo.b_DigitalInit == 1) {
773                                         /**************************/
774                                         /* Read all digital input */
775                                         /**************************/
776
777                                         /* INPDW (ps_APCI1710Variable->
778                                          * s_Board [b_BoardHandle].
779                                          * s_BoardInfos.
780                                          * ui_Address + (64 * b_ModulNbr),
781                                          * &dw_StatusReg);
782                                          */
783
784                                         dw_StatusReg =
785                                                 inl(devpriv->s_BoardInfos.
786                                                 ui_Address + (64 * b_ModulNbr));
787                                         *pb_PortValue =
788                                                 (unsigned char) (dw_StatusReg ^ 0x1C);
789
790                                 } else {
791                                         /*******************************/
792                                         /* Digital I/O not initialised */
793                                         /*******************************/
794
795                                         i_ReturnValue = -4;
796                                 }
797                         } else {
798                                 /******************************************/
799                                 /* The module is not a digital I/O module */
800                                 /******************************************/
801
802                                 i_ReturnValue = -3;
803                         }
804                 } else {
805            /***********************/
806                         /* Module number error */
807            /***********************/
808
809                         i_ReturnValue = -2;
810                 }
811
812                 break;
813
814         case APCI1710_OUTPUT:
815         /**************************/
816                 /* Test the module number */
817         /**************************/
818
819                 if (b_ModulNbr < 4) {
820            /*******************************/
821                         /* Test if digital I/O counter */
822            /*******************************/
823
824                         if ((devpriv->s_BoardInfos.
825                                         dw_MolduleConfiguration[b_ModulNbr] &
826                                         0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
827               /**********************************************/
828                                 /* Test if the digital I/O module initialised */
829               /**********************************************/
830
831                                 if (devpriv->s_ModuleInfo[b_ModulNbr].
832                                         s_DigitalIOInfo.b_DigitalInit == 1) {
833                  /***********************/
834                                         /* Test the port value */
835                  /***********************/
836
837                                         if (b_PortValue <= 7) {
838                     /***********************************/
839                                                 /* Test the digital output channel */
840                     /***********************************/
841
842                     /**************************/
843                                                 /* Test if channel A used */
844                     /**************************/
845
846                                                 if ((b_PortValue & 2) == 2) {
847                                                         if (devpriv->
848                                                                 s_ModuleInfo
849                                                                 [b_ModulNbr].
850                                                                 s_DigitalIOInfo.
851                                                                 b_ChannelAMode
852                                                                 != 1) {
853                           /*******************************************/
854                                                                 /* The digital channel A is used for input */
855                           /*******************************************/
856
857                                                                 i_ReturnValue =
858                                                                         -6;
859                                                         }
860                                                 }       /*  if ((b_PortValue & 2) == 2) */
861
862                                                 /**************************/
863                                                 /* Test if channel B used */
864                                                 /**************************/
865
866                                                 if ((b_PortValue & 4) == 4) {
867                                                         if (devpriv->
868                                                                 s_ModuleInfo
869                                                                 [b_ModulNbr].
870                                                                 s_DigitalIOInfo.
871                                                                 b_ChannelBMode
872                                                                 != 1) {
873                                                                 /*******************************************/
874                                                                 /* The digital channel B is used for input */
875                                                                 /*******************************************/
876
877                                                                 i_ReturnValue =
878                                                                         -7;
879                                                         }
880                                                 }       /*  if ((b_PortValue & 4) == 4) */
881
882                                                 /***********************/
883                                                 /* Test if error occur */
884                                                 /***********************/
885
886                                                 if (i_ReturnValue >= 0) {
887
888                                                         /* if(data[1]) { */
889
890                                                         switch (b_PortOnOFF) {
891                                                                 /*********************************/
892                                                                 /* Test if set Port ON                   */
893                                                                 /*********************************/
894
895                                                         case APCI1710_ON:
896
897                                                                 /*********************************/
898                                                                 /* Test if output memory enabled */
899                                                                 /*********************************/
900
901                                                                 if (devpriv->
902                                                                         s_ModuleInfo
903                                                                         [b_ModulNbr].
904                                                                         s_DigitalIOInfo.
905                                                                         b_OutputMemoryEnabled
906                                                                         == 1) {
907                                                                         dw_WriteValue
908                                                                                 =
909                                                                                 devpriv->
910                                                                                 s_ModuleInfo
911                                                                                 [b_ModulNbr].
912                                                                                 s_DigitalIOInfo.
913                                                                                 dw_OutputMemory
914                                                                                 |
915                                                                                 b_PortValue;
916
917                                                                         devpriv->
918                                                                                 s_ModuleInfo
919                                                                                 [b_ModulNbr].
920                                                                                 s_DigitalIOInfo.
921                                                                                 dw_OutputMemory
922                                                                                 =
923                                                                                 dw_WriteValue;
924                                                                 } else {
925                                                                         dw_WriteValue
926                                                                                 =
927                                                                                 b_PortValue;
928                                                                 }
929                                                                 break;
930
931                                                                 /*  If Set PORT  OFF */
932                                                         case APCI1710_OFF:
933
934                            /*********************************/
935                                                                 /* Test if output memory enabled */
936                        /*********************************/
937
938                                                                 if (devpriv->
939                                                                         s_ModuleInfo
940                                                                         [b_ModulNbr].
941                                                                         s_DigitalIOInfo.
942                                                                         b_OutputMemoryEnabled
943                                                                         == 1) {
944                                                                         dw_WriteValue
945                                                                                 =
946                                                                                 devpriv->
947                                                                                 s_ModuleInfo
948                                                                                 [b_ModulNbr].
949                                                                                 s_DigitalIOInfo.
950                                                                                 dw_OutputMemory
951                                                                                 &
952                                                                                 (0xFFFFFFFFUL
953                                                                                 -
954                                                                                 b_PortValue);
955
956                                                                         devpriv->
957                                                                                 s_ModuleInfo
958                                                                                 [b_ModulNbr].
959                                                                                 s_DigitalIOInfo.
960                                                                                 dw_OutputMemory
961                                                                                 =
962                                                                                 dw_WriteValue;
963                                                                 } else {
964                                                                         /*****************************/
965                                                                         /* Digital Output Memory OFF */
966                                                                         /*****************************/
967
968                                                                         i_ReturnValue
969                                                                                 =
970                                                                                 -8;
971                                                                 }
972                                                         }       /*  switch */
973
974                                                         /*******************/
975                                                         /* Write the value */
976                                                         /*******************/
977
978                                                         /* OUTPDW (ps_APCI1710Variable->
979                                                          * s_Board [b_BoardHandle].
980                                                          * s_BoardInfos.
981                                                          * ui_Address + (64 * b_ModulNbr),
982                                                          * dw_WriteValue); */
983
984                                                         outl(dw_WriteValue,
985                                                                 devpriv->
986                                                                 s_BoardInfos.
987                                                                 ui_Address +
988                                                                 (64 * b_ModulNbr));
989                                                 }
990                                         } else {
991                                                 /**********************/
992                                                 /* Output value wrong */
993                                                 /**********************/
994
995                                                 i_ReturnValue = -4;
996                                         }
997                                 } else {
998                                         /*******************************/
999                                         /* Digital I/O not initialised */
1000                                         /*******************************/
1001
1002                                         i_ReturnValue = -5;
1003                                 }
1004                         } else {
1005               /******************************************/
1006                                 /* The module is not a digital I/O module */
1007               /******************************************/
1008
1009                                 i_ReturnValue = -3;
1010                         }
1011                 } else {
1012            /***********************/
1013                         /* Module number error */
1014            /***********************/
1015
1016                         i_ReturnValue = -2;
1017                 }
1018                 break;
1019
1020         default:
1021                 i_ReturnValue = -9;
1022                 DPRINTK("NO INPUT/OUTPUT specified\n");
1023         }                       /* switch INPUT / OUTPUT */
1024         return (i_ReturnValue);
1025 }