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