Staging: comedi: Remove comedi_subdevice typedef
[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,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 |                  BYTE_ b_ModulNbr      data[0]: Module number to               |
74 |                                             configure (0 to 3)             |
75 |                     BYTE_ 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 |                     BYTE_ 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         comedi_insn * insn, unsigned int * data)
104 {
105         BYTE b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
106         BYTE b_MemoryOnOff, b_ConfigType;
107         INT i_ReturnValue = 0;
108         DWORD dw_WriteConfig = 0;
109
110         b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
111         b_ConfigType = (BYTE) data[0];  // Memory or  Init
112         b_ChannelAMode = (BYTE) data[1];
113         b_ChannelBMode = (BYTE) data[2];
114         b_MemoryOnOff = (BYTE) 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                                                 (DWORD) (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,     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 |  BYTE_ b_ModulNbr  CR_AREF(chanspec)          : Selected module number   |
261 |                                                   (0 to 3)                 |
262 |  BYTE_ 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      (BYTE_    b_BoardHandle,
292 //                                             BYTE_    b_ModulNbr,
293 //                                             BYTE_    b_InputChannel,
294 //
295 //                                             PBYTE_  pb_ChannelStatus)
296 INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device * dev,
297         struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
298 {
299         INT i_ReturnValue = 0;
300         DWORD dw_StatusReg;
301         BYTE b_ModulNbr, b_InputChannel;
302         PBYTE pb_ChannelStatus;
303         b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
304         b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
305         data[0] = 0;
306         pb_ChannelStatus = (PBYTE) & 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                                                 //INPDW (ps_APCI1710Variable->
391                                                 //   s_Board [b_BoardHandle].
392                                                 //   s_BoardInfos.
393                                                 //  ui_Address + (64 * b_ModulNbr),
394                                                 // &dw_StatusReg);
395
396                                                 dw_StatusReg =
397                                                         inl(devpriv->
398                                                         s_BoardInfos.
399                                                         ui_Address +
400                                                         (64 * b_ModulNbr));
401
402                                                 *pb_ChannelStatus =
403                                                         (BYTE) ((dw_StatusReg ^
404                                                                 0x1C) >>
405                                                         b_InputChannel) & 1;
406
407                                         }       // if (i_ReturnValue == 0)
408                                 } else {
409                     /*******************************/
410                                         /* Digital I/O not initialised */
411                     /*******************************/
412                                         DPRINTK("Digital I/O not initialised\n");
413                                         i_ReturnValue = -5;
414                                 }
415                         } else {
416                  /********************************/
417                                 /* Selected digital input error */
418                  /********************************/
419                                 DPRINTK("Selected digital input error\n");
420                                 i_ReturnValue = -4;
421                         }
422                 } else {
423               /******************************************/
424                         /* The module is not a digital I/O module */
425               /******************************************/
426                         DPRINTK("The module is not a digital I/O module\n");
427                         i_ReturnValue = -3;
428                 }
429         } else {
430            /***********************/
431                 /* Module number error */
432            /***********************/
433                 DPRINTK("Module number error\n");
434                 i_ReturnValue = -2;
435         }
436
437         return (i_ReturnValue);
438 }
439
440 /*
441 +----------------------------------------------------------------------------+
442 |                            OUTPUT FUNCTIONS                                |
443 +----------------------------------------------------------------------------+
444 */
445
446 /*
447 +----------------------------------------------------------------------------+
448 | Function Name     : INT i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device
449 |*dev,struct comedi_subdevice *s,comedi_insn *insn,unsigned int *data)
450
451 +----------------------------------------------------------------------------+
452 | Task              : Sets or resets the output witch has been passed with the         |
453 |                     parameter b_Channel. Setting an output means setting   |
454 |                     an ouput high.                                         |
455 +----------------------------------------------------------------------------+
456 | Input Parameters  : BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
457 |                     BYTE_ b_ModulNbr (aref )    : Selected module number (0 to 3)|
458 |                     BYTE_ b_OutputChannel (CR_CHAN) : Selection from digital output  |
459 |                                             channel (0 to 2)               |
460 |                                                0 : Channel H               |
461 |                                                1 : Channel A               |
462 |                                                2 : Channel B               |
463 +----------------------------------------------------------------------------+
464 | Output Parameters : -                                                      |
465 +----------------------------------------------------------------------------+
466 | Return Value      : 0: No error                                            |
467 |                    -1: The handle parameter of the board is wrong          |
468 |                    -2: The module parameter is wrong                       |
469 |                    -3: The module is not a digital I/O module              |
470 |                    -4: The selected digital output is wrong                |
471 |                    -5: digital I/O not initialised see function            |
472 |                        " i_APCI1710_InitDigitalIO"                         |
473 |                    -6: The digital channel A is used for input             |
474 |                    -7: The digital channel B is used for input
475                                          -8: Digital Output Memory OFF.                          |
476 |                        Use previously the function                         |
477 |                        "i_APCI1710_SetDigitalIOMemoryOn".            |
478 +----------------------------------------------------------------------------+
479 */
480
481 //_INT_   i_APCI1710_SetDigitalIOChlOn    (BYTE_ b_BoardHandle,
482 //                                       BYTE_ b_ModulNbr,
483 //                                       BYTE_ b_OutputChannel)
484 INT i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device * dev,
485         struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
486 {
487         INT i_ReturnValue = 0;
488         DWORD dw_WriteValue = 0;
489         BYTE 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.
645                                         //   ui_Address + (64 * b_ModulNbr),
646                                         //   dw_WriteValue);
647                                         outl(dw_WriteValue,
648                                                 devpriv->s_BoardInfos.
649                                                 ui_Address + (64 * b_ModulNbr));
650                                 }
651                         } else {
652                  /*******************************/
653                                 /* Digital I/O not initialised */
654                  /*******************************/
655
656                                 i_ReturnValue = -5;
657                         }
658                 } else {
659               /******************************************/
660                         /* The module is not a digital I/O module */
661               /******************************************/
662
663                         i_ReturnValue = -3;
664                 }
665         } else {
666            /***********************/
667                 /* Module number error */
668            /***********************/
669
670                 i_ReturnValue = -2;
671         }
672
673         return (i_ReturnValue);
674 }
675
676 /*
677 +----------------------------------------------------------------------------+
678
679 |INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice
680         *s,     comedi_insn *insn,unsigned int *data)
681 +----------------------------------------------------------------------------+
682 | Task              : write:
683                                           Sets or resets one or several outputs from port.                 |
684 |                     Setting an output means setting an output high.        |
685 |                     If you have switched OFF the digital output memory     |
686 |                     (OFF), all the other output are set to "0".
687
688 |                      read:
689                                           Read the status from digital input port                |
690 |                     from selected digital I/O module (b_ModulNbr)
691 +----------------------------------------------------------------------------+
692 | Input Parameters  :
693         BYTE_ b_BoardHandle   : Handle of board APCI-1710      |
694 |   BYTE_ b_ModulNbr  CR_AREF(aref)    : Selected module number (0 to 3)|
695 |   BYTE_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 )
696 |                       data[0]           read or write port
697                         data[1]            if write then indicate ON or OFF
698
699                         if read : data[1] will return port status.
700 +----------------------------------------------------------------------------+
701 | Output Parameters : -                                                      |
702 +----------------------------------------------------------------------------+
703 | Return Value      :
704
705                 INPUT :
706
707                                           0: No error                                            |
708 |                    -1: The handle parameter of the board is wrong          |
709 |                    -2: The module parameter is wrong                       |
710 |                    -3: The module is not a digital I/O module              |
711 |                    -4: Digital I/O not initialised
712
713                                 OUTPUT:   0: No error                                            |
714 |                    -1: The handle parameter of the board is wrong          |
715 |                    -2: The module parameter is wrong                       |
716 |                    -3: The module is not a digital I/O module              |
717 |                    -4: Output value wrong                                  |
718 |                    -5: digital I/O not initialised see function            |
719 |                        " i_APCI1710_InitDigitalIO"                         |
720 |                    -6: The digital channel A is used for input             |
721 |                    -7: The digital channel B is used for input
722                                         -8: Digital Output Memory OFF.                          |
723 |                        Use previously the function                         |
724 |                        "i_APCI1710_SetDigitalIOMemoryOn".               |
725 +----------------------------------------------------------------------------+
726 */
727
728 //_INT_   i_APCI1710_SetDigitalIOPortOn   (BYTE_ b_BoardHandle,
729 //                                       BYTE_ b_ModulNbr,
730 //                                       BYTE_ b_PortValue)
731 INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device * dev,
732         struct comedi_subdevice * s, comedi_insn * insn, unsigned int * data)
733 {
734         INT i_ReturnValue = 0;
735         DWORD dw_WriteValue = 0;
736         DWORD dw_StatusReg;
737         BYTE b_ModulNbr, b_PortValue;
738         BYTE b_PortOperation, b_PortOnOFF;
739
740         PBYTE pb_PortValue;
741
742         b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
743         b_PortOperation = (BYTE) data[0];       // Input or output
744         b_PortOnOFF = (BYTE) data[1];   // if output then On or Off
745         b_PortValue = (BYTE) data[2];   // if out put then Value
746         i_ReturnValue = insn->n;
747         pb_PortValue = (PBYTE) & data[0];
748 // if input then read value
749
750         switch (b_PortOperation) {
751         case APCI1710_INPUT:
752         /**************************/
753                 /* Test the module number */
754         /**************************/
755
756                 if (b_ModulNbr < 4) {
757            /*******************************/
758                         /* Test if digital I/O counter */
759            /*******************************/
760
761                         if ((devpriv->s_BoardInfos.
762                                         dw_MolduleConfiguration[b_ModulNbr] &
763                                         0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
764               /**********************************************/
765                                 /* Test if the digital I/O module initialised */
766               /**********************************************/
767
768                                 if (devpriv->s_ModuleInfo[b_ModulNbr].
769                                         s_DigitalIOInfo.b_DigitalInit == 1) {
770                  /**************************/
771                                         /* Read all digital input */
772                  /**************************/
773
774                                         //INPDW (ps_APCI1710Variable->
775                                         //      s_Board [b_BoardHandle].
776                                         //      s_BoardInfos.
777                                         //      ui_Address + (64 * b_ModulNbr),
778                                         //      &dw_StatusReg);
779
780                                         dw_StatusReg =
781                                                 inl(devpriv->s_BoardInfos.
782                                                 ui_Address + (64 * b_ModulNbr));
783                                         *pb_PortValue =
784                                                 (BYTE) (dw_StatusReg ^ 0x1C);
785
786                                 } else {
787                  /*******************************/
788                                         /* Digital I/O not initialised */
789                  /*******************************/
790
791                                         i_ReturnValue = -4;
792                                 }
793                         } else {
794               /******************************************/
795                                 /* The module is not a digital I/O module */
796               /******************************************/
797
798                                 i_ReturnValue = -3;
799                         }
800                 } else {
801            /***********************/
802                         /* Module number error */
803            /***********************/
804
805                         i_ReturnValue = -2;
806                 }
807
808                 break;
809
810         case APCI1710_OUTPUT:
811         /**************************/
812                 /* Test the module number */
813         /**************************/
814
815                 if (b_ModulNbr < 4) {
816            /*******************************/
817                         /* Test if digital I/O counter */
818            /*******************************/
819
820                         if ((devpriv->s_BoardInfos.
821                                         dw_MolduleConfiguration[b_ModulNbr] &
822                                         0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
823               /**********************************************/
824                                 /* Test if the digital I/O module initialised */
825               /**********************************************/
826
827                                 if (devpriv->s_ModuleInfo[b_ModulNbr].
828                                         s_DigitalIOInfo.b_DigitalInit == 1) {
829                  /***********************/
830                                         /* Test the port value */
831                  /***********************/
832
833                                         if (b_PortValue <= 7) {
834                     /***********************************/
835                                                 /* Test the digital output channel */
836                     /***********************************/
837
838                     /**************************/
839                                                 /* Test if channel A used */
840                     /**************************/
841
842                                                 if ((b_PortValue & 2) == 2) {
843                                                         if (devpriv->
844                                                                 s_ModuleInfo
845                                                                 [b_ModulNbr].
846                                                                 s_DigitalIOInfo.
847                                                                 b_ChannelAMode
848                                                                 != 1) {
849                           /*******************************************/
850                                                                 /* The digital channel A is used for input */
851                           /*******************************************/
852
853                                                                 i_ReturnValue =
854                                                                         -6;
855                                                         }
856                                                 }       // if ((b_PortValue & 2) == 2)
857
858                     /**************************/
859                                                 /* Test if channel B used */
860                     /**************************/
861
862                                                 if ((b_PortValue & 4) == 4) {
863                                                         if (devpriv->
864                                                                 s_ModuleInfo
865                                                                 [b_ModulNbr].
866                                                                 s_DigitalIOInfo.
867                                                                 b_ChannelBMode
868                                                                 != 1) {
869                           /*******************************************/
870                                                                 /* The digital channel B is used for input */
871                           /*******************************************/
872
873                                                                 i_ReturnValue =
874                                                                         -7;
875                                                         }
876                                                 }       // if ((b_PortValue & 4) == 4)
877
878                     /***********************/
879                                                 /* Test if error occur */
880                     /***********************/
881
882                                                 if (i_ReturnValue >= 0) {
883
884                                                         //if(data[1])
885                                                         //{
886                                                         switch (b_PortOnOFF) {
887                            /*********************************/
888                                                                 /* Test if set Port ON                   */
889                        /*********************************/
890
891                                                         case APCI1710_ON:
892
893                        /*********************************/
894                                                                 /* Test if output memory enabled */
895                        /*********************************/
896
897                                                                 if (devpriv->
898                                                                         s_ModuleInfo
899                                                                         [b_ModulNbr].
900                                                                         s_DigitalIOInfo.
901                                                                         b_OutputMemoryEnabled
902                                                                         == 1) {
903                                                                         dw_WriteValue
904                                                                                 =
905                                                                                 devpriv->
906                                                                                 s_ModuleInfo
907                                                                                 [b_ModulNbr].
908                                                                                 s_DigitalIOInfo.
909                                                                                 dw_OutputMemory
910                                                                                 |
911                                                                                 b_PortValue;
912
913                                                                         devpriv->
914                                                                                 s_ModuleInfo
915                                                                                 [b_ModulNbr].
916                                                                                 s_DigitalIOInfo.
917                                                                                 dw_OutputMemory
918                                                                                 =
919                                                                                 dw_WriteValue;
920                                                                 } else {
921                                                                         dw_WriteValue
922                                                                                 =
923                                                                                 b_PortValue;
924                                                                 }
925                                                                 break;
926
927                                                                 // If Set PORT  OFF
928                                                         case APCI1710_OFF:
929
930                            /*********************************/
931                                                                 /* Test if output memory enabled */
932                        /*********************************/
933
934                                                                 if (devpriv->
935                                                                         s_ModuleInfo
936                                                                         [b_ModulNbr].
937                                                                         s_DigitalIOInfo.
938                                                                         b_OutputMemoryEnabled
939                                                                         == 1) {
940                                                                         dw_WriteValue
941                                                                                 =
942                                                                                 devpriv->
943                                                                                 s_ModuleInfo
944                                                                                 [b_ModulNbr].
945                                                                                 s_DigitalIOInfo.
946                                                                                 dw_OutputMemory
947                                                                                 &
948                                                                                 (0xFFFFFFFFUL
949                                                                                 -
950                                                                                 b_PortValue);
951
952                                                                         devpriv->
953                                                                                 s_ModuleInfo
954                                                                                 [b_ModulNbr].
955                                                                                 s_DigitalIOInfo.
956                                                                                 dw_OutputMemory
957                                                                                 =
958                                                                                 dw_WriteValue;
959                                                                 } else {
960                           /*****************************/
961                                                                         /* Digital Output Memory OFF */
962                           /*****************************/
963
964                                                                         i_ReturnValue
965                                                                                 =
966                                                                                 -8;
967                                                                 }
968                                                         }       // switch
969
970                        /*******************/
971                                                         /* Write the value */
972                        /*******************/
973
974                                                         //  OUTPDW (ps_APCI1710Variable->
975                                                         //      s_Board [b_BoardHandle].
976                                                         //      s_BoardInfos.
977                                                         //      ui_Address + (64 * b_ModulNbr),
978                                                         //      dw_WriteValue);
979                                                         outl(dw_WriteValue,
980                                                                 devpriv->
981                                                                 s_BoardInfos.
982                                                                 ui_Address +
983                                                                 (64 * b_ModulNbr));
984                                                 }
985                                         } else {
986                     /**********************/
987                                                 /* Output value wrong */
988                     /**********************/
989
990                                                 i_ReturnValue = -4;
991                                         }
992                                 } else {
993                  /*******************************/
994                                         /* Digital I/O not initialised */
995                  /*******************************/
996
997                                         i_ReturnValue = -5;
998                                 }
999                         } else {
1000               /******************************************/
1001                                 /* The module is not a digital I/O module */
1002               /******************************************/
1003
1004                                 i_ReturnValue = -3;
1005                         }
1006                 } else {
1007            /***********************/
1008                         /* Module number error */
1009            /***********************/
1010
1011                         i_ReturnValue = -2;
1012                 }
1013                 break;
1014
1015         default:
1016                 i_ReturnValue = -9;
1017                 DPRINTK("NO INPUT/OUTPUT specified\n");
1018         }                       //switch INPUT / OUTPUT
1019         return (i_ReturnValue);
1020 }