]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
5fbd03db3ba6989b74a7a87dcfc0d7f1baac9d4f
[karo-tx-linux.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci1564.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     : APCI-1564       | Compiler   : GCC                      |
33   | Module name : hwdrv_apci1564.c| Version    : 2.96                     |
34   +-------------------------------+---------------------------------------+
35   | Project manager: Eric Stolz   | Date       :  02/12/2002              |
36   +-------------------------------+---------------------------------------+
37   | Description :   Hardware Layer Access For APCI-1564                   |
38   +-----------------------------------------------------------------------+
39   |                             UPDATES                                   |
40   +----------+-----------+------------------------------------------------+
41   |   Date   |   Author  |          Description of updates                |
42   +----------+-----------+------------------------------------------------+
43   |          |           |                                                |
44   |          |           |                                                |
45   |          |           |                                                |
46   +----------+-----------+------------------------------------------------+
47 */
48
49 /*
50 +----------------------------------------------------------------------------+
51 |                               Included files                               |
52 +----------------------------------------------------------------------------+
53 */
54
55 #include <linux/delay.h>
56 #include "hwdrv_apci1564.h"
57
58 /* Global variables */
59 static unsigned int ui_InterruptStatus_1564 = 0;
60 static unsigned int ui_InterruptData, ui_Type;
61
62 /*
63 +----------------------------------------------------------------------------+
64 | Function   Name   : int i_APCI1564_ConfigDigitalInput                      |
65 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
66 |                      struct comedi_insn *insn,unsigned int *data)                     |
67 +----------------------------------------------------------------------------+
68 | Task              : Configures the digital input Subdevice                 |
69 +----------------------------------------------------------------------------+
70 | Input Parameters  : struct comedi_device *dev : Driver handle                     |
71 |                     unsigned int *data         : Data Pointer contains         |
72 |                                          configuration parameters as below |
73 |                                                                            |
74 |                         data[0]            : 1 Enable  Digital Input Interrupt |
75 |                                                                  0 Disable Digital Input Interrupt |
76 |                         data[1]            : 0 ADDIDATA Interrupt OR LOGIC     |
77 |                                                                : 1 ADDIDATA Interrupt AND LOGIC    |
78 |                         data[2]                        : Interrupt mask for the mode 1         |
79 |                         data[3]                        : Interrupt mask for the mode 2         |
80 |                                                                                                                                        |
81 +----------------------------------------------------------------------------+
82 | Output Parameters :   --                                                                                                       |
83 +----------------------------------------------------------------------------+
84 | Return Value      : TRUE  : No error occur                                 |
85 |                           : FALSE : Error occur. Return the error          |
86 |                                                                                |
87 +----------------------------------------------------------------------------+
88 */
89 static int i_APCI1564_ConfigDigitalInput(struct comedi_device *dev,
90                                          struct comedi_subdevice *s,
91                                          struct comedi_insn *insn,
92                                          unsigned int *data)
93 {
94         struct addi_private *devpriv = dev->private;
95
96         devpriv->tsk_Current = current;
97    /*******************************/
98         /* Set the digital input logic */
99    /*******************************/
100         if (data[0] == ADDIDATA_ENABLE) {
101                 data[2] = data[2] << 4;
102                 data[3] = data[3] << 4;
103                 outl(data[2],
104                         devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
105                         APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
106                 outl(data[3],
107                         devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
108                         APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
109                 if (data[1] == ADDIDATA_OR) {
110                         outl(0x4,
111                                 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
112                                 APCI1564_DIGITAL_IP_IRQ);
113                 }               /*  if  (data[1] == ADDIDATA_OR) */
114                 else {
115                         outl(0x6,
116                                 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
117                                 APCI1564_DIGITAL_IP_IRQ);
118                 }               /*  else if  (data[1] == ADDIDATA_OR) */
119         }                       /*  if  (data[0] == ADDIDATA_ENABLE) */
120         else {
121                 outl(0x0,
122                         devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
123                         APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
124                 outl(0x0,
125                         devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
126                         APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
127                 outl(0x0,
128                         devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
129                         APCI1564_DIGITAL_IP_IRQ);
130         }                       /*  else if  (data[0] == ADDIDATA_ENABLE) */
131
132         return insn->n;
133 }
134
135 /*
136 +----------------------------------------------------------------------------+
137 | Function   Name   : int i_APCI1564_Read1DigitalInput                       |
138 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
139 |                      struct comedi_insn *insn,unsigned int *data)                     |
140 +----------------------------------------------------------------------------+
141 | Task              : Return the status of the digital input                 |
142 +----------------------------------------------------------------------------+
143 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
144 |                             unsigned int ui_Channel : Channel number to read       |
145 |                     unsigned int *data          : Data Pointer to read status  |
146 +----------------------------------------------------------------------------+
147 | Output Parameters :   --                                                                                                       |
148 +----------------------------------------------------------------------------+
149 | Return Value      : TRUE  : No error occur                                 |
150 |                           : FALSE : Error occur. Return the error          |
151 |                                                                                |
152 +----------------------------------------------------------------------------+
153 */
154 static int i_APCI1564_Read1DigitalInput(struct comedi_device *dev,
155                                         struct comedi_subdevice *s,
156                                         struct comedi_insn *insn,
157                                         unsigned int *data)
158 {
159         struct addi_private *devpriv = dev->private;
160         unsigned int ui_TmpValue = 0;
161         unsigned int ui_Channel;
162
163         ui_Channel = CR_CHAN(insn->chanspec);
164         if (ui_Channel <= 31) {
165                 ui_TmpValue =
166                         (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
167 /*
168 * since only 1 channel reqd to bring it to last bit it is rotated 8
169 * +(chan - 1) times then ANDed with 1 for last bit.
170 */
171                 *data = (ui_TmpValue >> ui_Channel) & 0x1;
172         }                       /*  if  (ui_Channel >= 0 && ui_Channel <=31) */
173         else {
174                 comedi_error(dev, "Not a valid channel number !!! \n");
175                 return -EINVAL; /*  "sorry channel spec wrong " */
176         }                       /* else if  (ui_Channel >= 0 && ui_Channel <=31) */
177         return insn->n;
178 }
179
180 /*
181 +----------------------------------------------------------------------------+
182 | Function   Name   : int i_APCI1564_ReadMoreDigitalInput                    |
183 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
184 |                     struct comedi_insn *insn,unsigned int *data)                      |
185 +----------------------------------------------------------------------------+
186 | Task              : Return the status of the Requested digital inputs      |
187 +----------------------------------------------------------------------------+
188 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
189 |                     unsigned int ui_NoOfChannels    : No Of Channels To be Read    |
190 |                      unsigned int *data             : Data Pointer to read status  |
191 +----------------------------------------------------------------------------+
192 | Output Parameters :   --                                                                                                       |
193 +----------------------------------------------------------------------------+
194 | Return Value      : TRUE  : No error occur                                 |
195 |                           : FALSE : Error occur. Return the error          |
196 |                                                                                |
197 +----------------------------------------------------------------------------+
198 */
199 static int i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev,
200                                            struct comedi_subdevice *s,
201                                            struct comedi_insn *insn,
202                                            unsigned int *data)
203 {
204         struct addi_private *devpriv = dev->private;
205         unsigned int ui_PortValue = data[0];
206         unsigned int ui_Mask = 0;
207         unsigned int ui_NoOfChannels;
208
209         ui_NoOfChannels = CR_CHAN(insn->chanspec);
210         if (data[1] == 0) {
211                 *data = (unsigned int) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
212                 switch (ui_NoOfChannels) {
213                 case 2:
214                         ui_Mask = 3;
215                         *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
216                         break;
217                 case 4:
218                         ui_Mask = 15;
219                         *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
220                         break;
221                 case 8:
222                         ui_Mask = 255;
223                         *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
224                         break;
225                 case 16:
226                         ui_Mask = 65535;
227                         *data = (*data >> (16 * ui_PortValue)) & ui_Mask;
228                         break;
229                 case 31:
230                         break;
231                 default:
232                         comedi_error(dev, "Not a valid Channel number !!!\n");
233                         return -EINVAL; /*  "sorry channel spec wrong " */
234                         break;
235                 }               /*  switch  (ui_NoOfChannels) */
236         }                       /*  if  (data[1]==0) */
237         else {
238                 if (data[1] == 1) {
239                         *data = ui_InterruptStatus_1564;
240                 }               /*  if  (data[1]==1) */
241         }                       /*  else if  (data[1]==0) */
242         return insn->n;
243 }
244
245 /*
246 +----------------------------------------------------------------------------+
247 | Function   Name   : int i_APCI1564_ConfigDigitalOutput                     |
248 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
249 |                      struct comedi_insn *insn,unsigned int *data)                     |
250 +----------------------------------------------------------------------------+
251 | Task              : Configures The Digital Output Subdevice.               |
252 +----------------------------------------------------------------------------+
253 | Input Parameters  : struct comedi_device *dev : Driver handle                     |
254 |                     unsigned int *data         : Data Pointer contains             |
255 |                                          configuration parameters as below |
256 |                                                                            |
257 |                                         data[1]            : 1 Enable  VCC  Interrupt  |
258 |                                                                                  0 Disable VCC  Interrupt  |
259 |                                         data[2]            : 1 Enable  CC  Interrupt   |
260 |                                                                                  0 Disable CC  Interrupt   |
261 |                                                                                                                                        |
262 +----------------------------------------------------------------------------+
263 | Output Parameters :   --                                                                                                       |
264 +----------------------------------------------------------------------------+
265 | Return Value      : TRUE  : No error occur                                 |
266 |                           : FALSE : Error occur. Return the error          |
267 |                                                                                |
268 +----------------------------------------------------------------------------+
269 */
270 static int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev,
271                                           struct comedi_subdevice *s,
272                                           struct comedi_insn *insn,
273                                           unsigned int *data)
274 {
275         struct addi_private *devpriv = dev->private;
276         unsigned int ul_Command = 0;
277
278         if ((data[0] != 0) && (data[0] != 1)) {
279                 comedi_error(dev,
280                         "Not a valid Data !!! ,Data should be 1 or 0\n");
281                 return -EINVAL;
282         }                       /*  if  ((data[0]!=0) && (data[0]!=1)) */
283         if (data[0]) {
284                 devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
285         }                       /*  if  (data[0]) */
286         else {
287                 devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
288         }                       /*  else if  (data[0]) */
289         if (data[1] == ADDIDATA_ENABLE) {
290                 ul_Command = ul_Command | 0x1;
291         }                       /*  if  (data[1] == ADDIDATA_ENABLE) */
292         else {
293                 ul_Command = ul_Command & 0xFFFFFFFE;
294         }                       /*  else if  (data[1] == ADDIDATA_ENABLE) */
295         if (data[2] == ADDIDATA_ENABLE) {
296                 ul_Command = ul_Command | 0x2;
297         }                       /*  if  (data[2] == ADDIDATA_ENABLE) */
298         else {
299                 ul_Command = ul_Command & 0xFFFFFFFD;
300         }                       /*  else if  (data[2] == ADDIDATA_ENABLE) */
301         outl(ul_Command,
302                 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
303                 APCI1564_DIGITAL_OP_INTERRUPT);
304         ui_InterruptData =
305                 inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
306                 APCI1564_DIGITAL_OP_INTERRUPT);
307         devpriv->tsk_Current = current;
308         return insn->n;
309 }
310
311 /*
312 +----------------------------------------------------------------------------+
313 | Function   Name   : int i_APCI1564_WriteDigitalOutput                      |
314 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
315 |                      struct comedi_insn *insn,unsigned int *data)                     |
316 +----------------------------------------------------------------------------+
317 | Task              : Writes port value  To the selected port                |
318 +----------------------------------------------------------------------------+
319 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
320 |                     unsigned int ui_NoOfChannels    : No Of Channels To Write      |
321 |                     unsigned int *data              : Data Pointer to read status  |
322 +----------------------------------------------------------------------------+
323 | Output Parameters :   --                                                                                                       |
324 +----------------------------------------------------------------------------+
325 | Return Value      : TRUE  : No error occur                                 |
326 |                           : FALSE : Error occur. Return the error          |
327 |                                                                                |
328 +----------------------------------------------------------------------------+
329 */
330 static int i_APCI1564_WriteDigitalOutput(struct comedi_device *dev,
331                                          struct comedi_subdevice *s,
332                                          struct comedi_insn *insn,
333                                          unsigned int *data)
334 {
335         struct addi_private *devpriv = dev->private;
336         unsigned int ui_Temp, ui_Temp1;
337         unsigned int ui_NoOfChannel;
338
339         ui_NoOfChannel = CR_CHAN(insn->chanspec);
340         if (devpriv->b_OutputMemoryStatus) {
341                 ui_Temp =
342                         inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
343                         APCI1564_DIGITAL_OP_RW);
344         }                       /*  if  (devpriv->b_OutputMemoryStatus ) */
345         else {
346                 ui_Temp = 0;
347         }                       /*  else if  (devpriv->b_OutputMemoryStatus ) */
348         if (data[3] == 0) {
349                 if (data[1] == 0) {
350                         data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
351                         outl(data[0],
352                                 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
353                                 APCI1564_DIGITAL_OP_RW);
354                 }               /*  if  (data[1]==0) */
355                 else {
356                         if (data[1] == 1) {
357                                 switch (ui_NoOfChannel) {
358                                 case 2:
359                                         data[0] =
360                                                 (data[0] << (2 *
361                                                         data[2])) | ui_Temp;
362                                         break;
363                                 case 4:
364                                         data[0] =
365                                                 (data[0] << (4 *
366                                                         data[2])) | ui_Temp;
367                                         break;
368                                 case 8:
369                                         data[0] =
370                                                 (data[0] << (8 *
371                                                         data[2])) | ui_Temp;
372                                         break;
373                                 case 16:
374                                         data[0] =
375                                                 (data[0] << (16 *
376                                                         data[2])) | ui_Temp;
377                                         break;
378                                 case 31:
379                                         data[0] = data[0] | ui_Temp;
380                                         break;
381                                 default:
382                                         comedi_error(dev, " chan spec wrong");
383                                         return -EINVAL; /*  "sorry channel spec wrong " */
384                                 }       /*  switch (ui_NoOfChannels) */
385                                 outl(data[0],
386                                         devpriv->i_IobaseAmcc +
387                                         APCI1564_DIGITAL_OP +
388                                         APCI1564_DIGITAL_OP_RW);
389                         }       /*  if  (data[1]==1) */
390                         else {
391                                 printk("\nSpecified channel not supported\n");
392                         }       /*  else if  (data[1]==1) */
393                 }               /*  else if (data[1]==0) */
394         }                       /* if(data[3]==0) */
395         else {
396                 if (data[3] == 1) {
397                         if (data[1] == 0) {
398                                 data[0] = ~data[0] & 0x1;
399                                 ui_Temp1 = 1;
400                                 ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
401                                 ui_Temp = ui_Temp | ui_Temp1;
402                                 data[0] =
403                                         (data[0] << ui_NoOfChannel) ^
404                                         0xffffffff;
405                                 data[0] = data[0] & ui_Temp;
406                                 outl(data[0],
407                                         devpriv->i_IobaseAmcc +
408                                         APCI1564_DIGITAL_OP +
409                                         APCI1564_DIGITAL_OP_RW);
410                         }       /*  if  (data[1]==0) */
411                         else {
412                                 if (data[1] == 1) {
413                                         switch (ui_NoOfChannel) {
414                                         case 2:
415                                                 data[0] = ~data[0] & 0x3;
416                                                 ui_Temp1 = 3;
417                                                 ui_Temp1 =
418                                                         ui_Temp1 << 2 * data[2];
419                                                 ui_Temp = ui_Temp | ui_Temp1;
420                                                 data[0] =
421                                                         ((data[0] << (2 *
422                                                                         data
423                                                                         [2])) ^
424                                                         0xffffffff) & ui_Temp;
425                                                 break;
426                                         case 4:
427                                                 data[0] = ~data[0] & 0xf;
428                                                 ui_Temp1 = 15;
429                                                 ui_Temp1 =
430                                                         ui_Temp1 << 4 * data[2];
431                                                 ui_Temp = ui_Temp | ui_Temp1;
432                                                 data[0] =
433                                                         ((data[0] << (4 *
434                                                                         data
435                                                                         [2])) ^
436                                                         0xffffffff) & ui_Temp;
437                                                 break;
438                                         case 8:
439                                                 data[0] = ~data[0] & 0xff;
440                                                 ui_Temp1 = 255;
441                                                 ui_Temp1 =
442                                                         ui_Temp1 << 8 * data[2];
443                                                 ui_Temp = ui_Temp | ui_Temp1;
444                                                 data[0] =
445                                                         ((data[0] << (8 *
446                                                                         data
447                                                                         [2])) ^
448                                                         0xffffffff) & ui_Temp;
449                                                 break;
450                                         case 16:
451                                                 data[0] = ~data[0] & 0xffff;
452                                                 ui_Temp1 = 65535;
453                                                 ui_Temp1 =
454                                                         ui_Temp1 << 16 *
455                                                         data[2];
456                                                 ui_Temp = ui_Temp | ui_Temp1;
457                                                 data[0] =
458                                                         ((data[0] << (16 *
459                                                                         data
460                                                                         [2])) ^
461                                                         0xffffffff) & ui_Temp;
462                                                 break;
463                                         case 31:
464                                                 break;
465                                         default:
466                                                 comedi_error(dev,
467                                                         " chan spec wrong");
468                                                 return -EINVAL; /*  "sorry channel spec wrong " */
469                                         }       /* switch(ui_NoOfChannels) */
470                                         outl(data[0],
471                                                 devpriv->i_IobaseAmcc +
472                                                 APCI1564_DIGITAL_OP +
473                                                 APCI1564_DIGITAL_OP_RW);
474                                 }       /*  if  (data[1]==1) */
475                                 else {
476                                         printk("\nSpecified channel not supported\n");
477                                 }       /*  else if  (data[1]==1) */
478                         }       /*  else if  (data[1]==0) */
479                 }               /*  if  (data[3]==1); */
480                 else {
481                         printk("\nSpecified functionality does not exist\n");
482                         return -EINVAL;
483                 }               /*  else if (data[3]==1) */
484         }                       /*  else if (data[3]==0) */
485         return insn->n;
486 }
487
488 /*
489 +----------------------------------------------------------------------------+
490 | Function   Name   : int i_APCI1564_ReadDigitalOutput                       |
491 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
492 |                      struct comedi_insn *insn,unsigned int *data)                     |
493 +----------------------------------------------------------------------------+
494 | Task              : Read  value  of the selected channel or port           |
495 +----------------------------------------------------------------------------+
496 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
497 |                     unsigned int ui_NoOfChannels    : No Of Channels To read       |
498 |                     unsigned int *data              : Data Pointer to read status  |
499 +----------------------------------------------------------------------------+
500 | Output Parameters :   --                                                                                                       |
501 +----------------------------------------------------------------------------+
502 | Return Value      : TRUE  : No error occur                                 |
503 |                           : FALSE : Error occur. Return the error          |
504 |                                                                                |
505 +----------------------------------------------------------------------------+
506 */
507 static int i_APCI1564_ReadDigitalOutput(struct comedi_device *dev,
508                                         struct comedi_subdevice *s,
509                                         struct comedi_insn *insn,
510                                         unsigned int *data)
511 {
512         struct addi_private *devpriv = dev->private;
513         unsigned int ui_Temp;
514         unsigned int ui_NoOfChannel;
515
516         ui_NoOfChannel = CR_CHAN(insn->chanspec);
517         ui_Temp = data[0];
518         *data = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
519                 APCI1564_DIGITAL_OP_RW);
520         if (ui_Temp == 0) {
521                 *data = (*data >> ui_NoOfChannel) & 0x1;
522         }                       /*  if  (ui_Temp==0) */
523         else {
524                 if (ui_Temp == 1) {
525                         switch (ui_NoOfChannel) {
526                         case 2:
527                                 *data = (*data >> (2 * data[1])) & 3;
528                                 break;
529
530                         case 4:
531                                 *data = (*data >> (4 * data[1])) & 15;
532                                 break;
533
534                         case 8:
535                                 *data = (*data >> (8 * data[1])) & 255;
536                                 break;
537
538                         case 16:
539                                 *data = (*data >> (16 * data[1])) & 65535;
540                                 break;
541
542                         case 31:
543                                 break;
544
545                         default:
546                                 comedi_error(dev, " chan spec wrong");
547                                 return -EINVAL; /*  "sorry channel spec wrong " */
548                                 break;
549                         }       /*  switch(ui_NoOfChannels) */
550                 }               /*  if  (ui_Temp==1) */
551                 else {
552                         printk("\nSpecified channel not supported \n");
553                 }               /*  else if (ui_Temp==1) */
554         }                       /*  else if  (ui_Temp==0) */
555         return insn->n;
556 }
557
558 /*
559 +----------------------------------------------------------------------------+
560 | Function   Name   : int i_APCI1564_ConfigTimerCounterWatchdog              |
561 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
562 |                      struct comedi_insn *insn,unsigned int *data)                     |
563 +----------------------------------------------------------------------------+
564 | Task              : Configures The Timer , Counter or Watchdog             |
565 +----------------------------------------------------------------------------+
566 | Input Parameters  : struct comedi_device *dev : Driver handle                     |
567 |                     unsigned int *data         : Data Pointer contains             |
568 |                                          configuration parameters as below |
569 |                                                                            |
570 |                                         data[0]            : 0 Configure As Timer      |
571 |                                                                                  1 Configure As Counter    |
572 |                                                                                  2 Configure As Watchdog   |
573 |                                         data[1]            : 1 Enable  Interrupt       |
574 |                                                                                  0 Disable Interrupt       |
575 |                                         data[2]            : Time Unit                 |
576 |                                         data[3]                        : Reload Value                      |
577 |                                         data[4]            : Timer Mode                |
578 |                                         data[5]                        : Timer Counter Watchdog Number|
579                               data[6]            :  Counter Direction
580 +----------------------------------------------------------------------------+
581 | Output Parameters :   --                                                                                                       |
582 +----------------------------------------------------------------------------+
583 | Return Value      : TRUE  : No error occur                                 |
584 |                           : FALSE : Error occur. Return the error          |
585 |                                                                                |
586 +----------------------------------------------------------------------------+
587 */
588 static int i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
589                                                  struct comedi_subdevice *s,
590                                                  struct comedi_insn *insn,
591                                                  unsigned int *data)
592 {
593         struct addi_private *devpriv = dev->private;
594         unsigned int ul_Command1 = 0;
595
596         devpriv->tsk_Current = current;
597         if (data[0] == ADDIDATA_WATCHDOG) {
598                 devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
599
600                 /* Disable the watchdog */
601                 outl(0x0,
602                         devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
603                         APCI1564_TCW_PROG);
604                 /* Loading the Reload value */
605                 outl(data[3],
606                         devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
607                         APCI1564_TCW_RELOAD_VALUE);
608         }                       /*  if  (data[0]==ADDIDATA_WATCHDOG) */
609         else if (data[0] == ADDIDATA_TIMER) {
610                 /* First Stop The Timer */
611                 ul_Command1 =
612                         inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
613                         APCI1564_TCW_PROG);
614                 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
615                 outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);  /* Stop The Timer */
616
617                 devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
618                 if (data[1] == 1) {
619                         outl(0x02, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); /* Enable TIMER int & DISABLE ALL THE OTHER int SOURCES */
620                         outl(0x0,
621                                 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
622                                 APCI1564_DIGITAL_IP_IRQ);
623                         outl(0x0,
624                                 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
625                                 APCI1564_DIGITAL_OP_IRQ);
626                         outl(0x0,
627                                 devpriv->i_IobaseAmcc +
628                                 APCI1564_DIGITAL_OP_WATCHDOG +
629                                 APCI1564_TCW_IRQ);
630                         outl(0x0,
631                                 devpriv->iobase + APCI1564_COUNTER1 +
632                                 APCI1564_TCW_IRQ);
633                         outl(0x0,
634                                 devpriv->iobase + APCI1564_COUNTER2 +
635                                 APCI1564_TCW_IRQ);
636                         outl(0x0,
637                                 devpriv->iobase + APCI1564_COUNTER3 +
638                                 APCI1564_TCW_IRQ);
639                         outl(0x0,
640                                 devpriv->iobase + APCI1564_COUNTER4 +
641                                 APCI1564_TCW_IRQ);
642                 }               /*  if  (data[1]==1) */
643                 else {
644                         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);  /* disable Timer interrupt */
645                 }               /*  else if  (data[1]==1) */
646
647                 /*  Loading Timebase */
648
649                 outl(data[2],
650                         devpriv->i_IobaseAmcc + APCI1564_TIMER +
651                         APCI1564_TCW_TIMEBASE);
652
653                 /* Loading the Reload value */
654                 outl(data[3],
655                         devpriv->i_IobaseAmcc + APCI1564_TIMER +
656                         APCI1564_TCW_RELOAD_VALUE);
657
658                 ul_Command1 =
659                         inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
660                         APCI1564_TCW_PROG);
661                 ul_Command1 =
662                         (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
663                 outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);  /* mode 2 */
664         }                       /*  else if  (data[0]==ADDIDATA_TIMER) */
665         else if (data[0] == ADDIDATA_COUNTER) {
666                 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
667                 devpriv->b_ModeSelectRegister = data[5];
668
669                 /* First Stop The Counter */
670                 ul_Command1 =
671                         inl(devpriv->iobase + ((data[5] - 1) * 0x20) +
672                         APCI1564_TCW_PROG);
673                 ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
674                 outl(ul_Command1, devpriv->iobase + ((data[5] - 1) * 0x20) + APCI1564_TCW_PROG);        /* Stop The Timer */
675
676       /************************/
677                 /* Set the reload value */
678       /************************/
679                 outl(data[3],
680                         devpriv->iobase + ((data[5] - 1) * 0x20) +
681                         APCI1564_TCW_RELOAD_VALUE);
682
683       /******************************/
684                 /* Set the mode :             */
685                 /* - Disable the hardware     */
686                 /* - Disable the counter mode */
687                 /* - Disable the warning      */
688                 /* - Disable the reset        */
689                 /* - Disable the timer mode   */
690                 /* - Enable the counter mode  */
691       /******************************/
692                 ul_Command1 =
693                         (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL |
694                         (unsigned int) ((unsigned int) data[4] << 16UL);
695                 outl(ul_Command1,
696                         devpriv->iobase + ((data[5] - 1) * 0x20) +
697                         APCI1564_TCW_PROG);
698
699                 /*  Enable or Disable Interrupt */
700                 ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
701                 outl(ul_Command1,
702                         devpriv->iobase + ((data[5] - 1) * 0x20) +
703                         APCI1564_TCW_PROG);
704
705       /*****************************/
706                 /* Set the Up/Down selection */
707       /*****************************/
708                 ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
709                 outl(ul_Command1,
710                         devpriv->iobase + ((data[5] - 1) * 0x20) +
711                         APCI1564_TCW_PROG);
712         }                       /*  else if  (data[0]==ADDIDATA_COUNTER) */
713         else {
714                 printk(" Invalid subdevice.");
715         }                       /*  else if  (data[0]==ADDIDATA_WATCHDOG) */
716
717         return insn->n;
718 }
719
720 /*
721 +----------------------------------------------------------------------------+
722 | Function   Name   : int i_APCI1564_StartStopWriteTimerCounterWatchdog      |
723 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
724 |                      struct comedi_insn *insn,unsigned int *data)                     |
725 +----------------------------------------------------------------------------+
726 | Task              : Start / Stop The Selected Timer , Counter or Watchdog  |
727 +----------------------------------------------------------------------------+
728 | Input Parameters  : struct comedi_device *dev : Driver handle                     |
729 |                     unsigned int *data         : Data Pointer contains             |
730 |                                          configuration parameters as below |
731 |                                                                            |
732 |                                         data[0]            : 0 Timer                   |
733 |                                                                                  1 Counter                 |
734 |                                                                                  2 Watchdog                    |                             |                                                 data[1]            : 1 Start                   |
735 |                                                                                  0 Stop                    |
736 |                                                  2 Trigger                     |
737 |                                                    Clear (Only Counter)    |
738 +----------------------------------------------------------------------------+
739 | Output Parameters :   --                                                                                                       |
740 +----------------------------------------------------------------------------+
741 | Return Value      : TRUE  : No error occur                                 |
742 |                           : FALSE : Error occur. Return the error          |
743 |                                                                                |
744 +----------------------------------------------------------------------------+
745 */
746 static int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
747                                                          struct comedi_subdevice *s,
748                                                          struct comedi_insn *insn,
749                                                          unsigned int *data)
750 {
751         struct addi_private *devpriv = dev->private;
752         unsigned int ul_Command1 = 0;
753
754         if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
755                 switch (data[1]) {
756                 case 0: /* stop the watchdog */
757                         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_PROG);    /* disable the watchdog */
758                         break;
759                 case 1: /* start the watchdog */
760                         outl(0x0001,
761                                 devpriv->i_IobaseAmcc +
762                                 APCI1564_DIGITAL_OP_WATCHDOG +
763                                 APCI1564_TCW_PROG);
764                         break;
765                 case 2: /* Software trigger */
766                         outl(0x0201,
767                                 devpriv->i_IobaseAmcc +
768                                 APCI1564_DIGITAL_OP_WATCHDOG +
769                                 APCI1564_TCW_PROG);
770                         break;
771                 default:
772                         printk("\nSpecified functionality does not exist\n");
773                         return -EINVAL;
774                 }               /*  switch (data[1]) */
775         }                       /*  if  (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG) */
776         if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
777                 if (data[1] == 1) {
778                         ul_Command1 =
779                                 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
780                                 APCI1564_TCW_PROG);
781                         ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
782
783                         /* Enable the Timer */
784                         outl(ul_Command1,
785                                 devpriv->i_IobaseAmcc + APCI1564_TIMER +
786                                 APCI1564_TCW_PROG);
787                 }               /*  if  (data[1]==1) */
788                 else if (data[1] == 0) {
789                         /* Stop The Timer */
790
791                         ul_Command1 =
792                                 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
793                                 APCI1564_TCW_PROG);
794                         ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
795                         outl(ul_Command1,
796                                 devpriv->i_IobaseAmcc + APCI1564_TIMER +
797                                 APCI1564_TCW_PROG);
798                 }               /*  else if(data[1]==0) */
799         }                       /*  if  (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) */
800         if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
801                 ul_Command1 =
802                         inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
803                                         1) * 0x20) + APCI1564_TCW_PROG);
804                 if (data[1] == 1) {
805                         /* Start the Counter subdevice */
806                         ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
807                 }               /*  if  (data[1] == 1) */
808                 else if (data[1] == 0) {
809                         /*  Stops the Counter subdevice */
810                         ul_Command1 = 0;
811
812                 }               /*  else if  (data[1] == 0) */
813                 else if (data[1] == 2) {
814                         /*  Clears the Counter subdevice */
815                         ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
816                 }               /*  else if  (data[1] == 3) */
817                 outl(ul_Command1,
818                         devpriv->iobase + ((devpriv->b_ModeSelectRegister -
819                                         1) * 0x20) + APCI1564_TCW_PROG);
820         }                       /*  if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER) */
821         return insn->n;
822 }
823
824 /*
825 +----------------------------------------------------------------------------+
826 | Function   Name   : int i_APCI1564_ReadTimerCounterWatchdog                |
827 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
828 |                      struct comedi_insn *insn,unsigned int *data)                     |
829 +----------------------------------------------------------------------------+
830 | Task              : Read The Selected Timer , Counter or Watchdog          |
831 +----------------------------------------------------------------------------+
832 | Input Parameters  : struct comedi_device *dev : Driver handle                     |
833 |                     unsigned int *data         : Data Pointer contains             |
834 |                                          configuration parameters as below |
835 |                                                                            |
836
837 +----------------------------------------------------------------------------+
838 | Output Parameters :   --                                                                                                       |
839 +----------------------------------------------------------------------------+
840 | Return Value      : TRUE  : No error occur                                 |
841 |                           : FALSE : Error occur. Return the error          |
842 |                                                                                |
843 +----------------------------------------------------------------------------+
844 */
845 static int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
846                                                struct comedi_subdevice *s,
847                                                struct comedi_insn *insn,
848                                                unsigned int *data)
849 {
850         struct addi_private *devpriv = dev->private;
851         unsigned int ul_Command1 = 0;
852
853         if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
854                 /*  Stores the status of the Watchdog */
855                 data[0] =
856                         inl(devpriv->i_IobaseAmcc +
857                         APCI1564_DIGITAL_OP_WATCHDOG +
858                         APCI1564_TCW_TRIG_STATUS) & 0x1;
859                 data[1] =
860                         inl(devpriv->i_IobaseAmcc +
861                         APCI1564_DIGITAL_OP_WATCHDOG);
862         }                       /*  if  (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG) */
863         else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
864                 /*  Stores the status of the Timer */
865                 data[0] =
866                         inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
867                         APCI1564_TCW_TRIG_STATUS) & 0x1;
868
869                 /*  Stores the Actual value of the Timer */
870                 data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER);
871         }                       /*  else if  (devpriv->b_TimerSelectMode==ADDIDATA_TIMER) */
872         else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
873                 /*  Read the Counter Actual Value. */
874                 data[0] =
875                         inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
876                                         1) * 0x20) +
877                         APCI1564_TCW_SYNC_ENABLEDISABLE);
878                 ul_Command1 =
879                         inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
880                                         1) * 0x20) + APCI1564_TCW_TRIG_STATUS);
881
882       /***********************************/
883                 /* Get the software trigger status */
884       /***********************************/
885                 data[1] = (unsigned char) ((ul_Command1 >> 1) & 1);
886
887       /***********************************/
888                 /* Get the hardware trigger status */
889       /***********************************/
890                 data[2] = (unsigned char) ((ul_Command1 >> 2) & 1);
891
892       /*********************************/
893                 /* Get the software clear status */
894       /*********************************/
895                 data[3] = (unsigned char) ((ul_Command1 >> 3) & 1);
896
897       /***************************/
898                 /* Get the overflow status */
899       /***************************/
900                 data[4] = (unsigned char) ((ul_Command1 >> 0) & 1);
901         }                       /*  else  if  (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER) */
902         else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
903                 && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)
904                 && (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) {
905                 printk("\n Invalid Subdevice !!!\n");
906         }                       /*  else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG)&& (devpriv->b_TimerSelectMode!=ADDIDATA_COUNTER)) */
907         return insn->n;
908 }
909
910 /*
911 +----------------------------------------------------------------------------+
912 | Function   Name   :  int i_APCI1564_ReadInterruptStatus                    |
913 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
914 |                      struct comedi_insn *insn,unsigned int *data)                     |
915 +----------------------------------------------------------------------------+
916 | Task              :Reads the interrupt status register                     |
917 +----------------------------------------------------------------------------+
918 | Input Parameters  :                                                        |
919 +----------------------------------------------------------------------------+
920 | Output Parameters :   --                                                                                                       |
921 +----------------------------------------------------------------------------+
922 | Return Value      :                                                        |
923 |                                                                                |
924 +----------------------------------------------------------------------------+
925 */
926
927 static int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev,
928                                           struct comedi_subdevice *s,
929                                           struct comedi_insn *insn,
930                                           unsigned int *data)
931 {
932         *data = ui_Type;
933         return insn->n;
934 }
935
936 /*
937 +----------------------------------------------------------------------------+
938 | Function   Name   : static void v_APCI1564_Interrupt                                       |
939 |                                         (int irq , void *d)      |
940 +----------------------------------------------------------------------------+
941 | Task              : Interrupt handler for the interruptible digital inputs |
942 +----------------------------------------------------------------------------+
943 | Input Parameters  : int irq                 : irq number                   |
944 |                     void *d                 : void pointer                 |
945 +----------------------------------------------------------------------------+
946 | Output Parameters :   --                                                                                                       |
947 +----------------------------------------------------------------------------+
948 | Return Value      : TRUE  : No error occur                                 |
949 |                           : FALSE : Error occur. Return the error          |
950 |                                                                                |
951 +----------------------------------------------------------------------------+
952 */
953 static void v_APCI1564_Interrupt(int irq, void *d)
954 {
955         struct comedi_device *dev = d;
956         struct addi_private *devpriv = dev->private;
957         unsigned int ui_DO, ui_DI;
958         unsigned int ui_Timer;
959         unsigned int ui_C1, ui_C2, ui_C3, ui_C4;
960         unsigned int ul_Command2 = 0;
961
962         ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
963                 APCI1564_DIGITAL_IP_IRQ) & 0x01;
964         ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
965                 APCI1564_DIGITAL_OP_IRQ) & 0x01;
966         ui_Timer =
967                 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
968                 APCI1564_TCW_IRQ) & 0x01;
969         ui_C1 = inl(devpriv->iobase + APCI1564_COUNTER1 +
970                 APCI1564_TCW_IRQ) & 0x1;
971         ui_C2 = inl(devpriv->iobase + APCI1564_COUNTER2 +
972                 APCI1564_TCW_IRQ) & 0x1;
973         ui_C3 = inl(devpriv->iobase + APCI1564_COUNTER3 +
974                 APCI1564_TCW_IRQ) & 0x1;
975         ui_C4 = inl(devpriv->iobase + APCI1564_COUNTER4 +
976                 APCI1564_TCW_IRQ) & 0x1;
977         if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
978                 && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
979                 printk("\nInterrupt from unknown source\n");
980         }                       /*  if(ui_DI==0 && ui_DO==0 && ui_Timer==0 && ui_C1==0 && ui_C2==0 && ui_C3==0 && ui_C4==0) */
981
982         if (ui_DI == 1) {
983                 ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
984                         APCI1564_DIGITAL_IP_IRQ);
985                 outl(0x0,
986                         devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
987                         APCI1564_DIGITAL_IP_IRQ);
988                 ui_InterruptStatus_1564 =
989                         inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
990                         APCI1564_DIGITAL_IP_INTERRUPT_STATUS);
991                 ui_InterruptStatus_1564 = ui_InterruptStatus_1564 & 0X000FFFF0;
992                 send_sig(SIGIO, devpriv->tsk_Current, 0);       /*  send signal to the sample */
993                 outl(ui_DI, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ);     /* enable the interrupt */
994                 return;
995         }
996
997         if (ui_DO == 1) {
998                 /*  Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt. */
999                 ui_Type =
1000                         inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
1001                         APCI1564_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
1002                 /* Disable the  Interrupt */
1003                 outl(0x0,
1004                         devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
1005                         APCI1564_DIGITAL_OP_INTERRUPT);
1006
1007                 /* Sends signal to user space */
1008                 send_sig(SIGIO, devpriv->tsk_Current, 0);
1009
1010         }                       /*  if  (ui_DO) */
1011
1012         if (ui_Timer == 1) {
1013                 devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
1014                 if (devpriv->b_TimerSelectMode) {
1015
1016                         /*  Disable Timer Interrupt */
1017                         ul_Command2 =
1018                                 inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
1019                                     APCI1564_TCW_PROG);
1020                         outl(0x0,
1021                              devpriv->i_IobaseAmcc + APCI1564_TIMER +
1022                              APCI1564_TCW_PROG);
1023
1024                         /* Send a signal to from kernel to user space */
1025                         send_sig(SIGIO, devpriv->tsk_Current, 0);
1026
1027                         /*  Enable Timer Interrupt */
1028
1029                         outl(ul_Command2,
1030                              devpriv->i_IobaseAmcc + APCI1564_TIMER +
1031                              APCI1564_TCW_PROG);
1032                 }
1033         }/* if  (ui_Timer == 1) */
1034
1035
1036         if (ui_C1 == 1) {
1037                 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
1038                 if (devpriv->b_TimerSelectMode) {
1039
1040                         /*  Disable Counter Interrupt */
1041                         ul_Command2 =
1042                                 inl(devpriv->iobase + APCI1564_COUNTER1 +
1043                                     APCI1564_TCW_PROG);
1044                         outl(0x0,
1045                              devpriv->iobase + APCI1564_COUNTER1 +
1046                              APCI1564_TCW_PROG);
1047
1048                         /* Send a signal to from kernel to user space */
1049                         send_sig(SIGIO, devpriv->tsk_Current, 0);
1050
1051                         /*  Enable Counter Interrupt */
1052                         outl(ul_Command2,
1053                              devpriv->iobase + APCI1564_COUNTER1 +
1054                              APCI1564_TCW_PROG);
1055                 }
1056         } /* if  (ui_C1 == 1) */
1057
1058         if (ui_C2 == 1) {
1059                 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
1060                 if (devpriv->b_TimerSelectMode) {
1061
1062                         /*  Disable Counter Interrupt */
1063                         ul_Command2 =
1064                                 inl(devpriv->iobase + APCI1564_COUNTER2 +
1065                                     APCI1564_TCW_PROG);
1066                         outl(0x0,
1067                              devpriv->iobase + APCI1564_COUNTER2 +
1068                              APCI1564_TCW_PROG);
1069
1070                         /* Send a signal to from kernel to user space */
1071                         send_sig(SIGIO, devpriv->tsk_Current, 0);
1072
1073                         /*  Enable Counter Interrupt */
1074                         outl(ul_Command2,
1075                              devpriv->iobase + APCI1564_COUNTER2 +
1076                              APCI1564_TCW_PROG);
1077                 }
1078         } /*  if  ((ui_C2 == 1) */
1079
1080         if (ui_C3 == 1) {
1081                 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
1082                 if (devpriv->b_TimerSelectMode) {
1083
1084                         /*  Disable Counter Interrupt */
1085                         ul_Command2 =
1086                                 inl(devpriv->iobase + APCI1564_COUNTER3 +
1087                                     APCI1564_TCW_PROG);
1088                         outl(0x0,
1089                              devpriv->iobase + APCI1564_COUNTER3 +
1090                              APCI1564_TCW_PROG);
1091
1092                         /* Send a signal to from kernel to user space */
1093                         send_sig(SIGIO, devpriv->tsk_Current, 0);
1094
1095                         /*  Enable Counter Interrupt */
1096                         outl(ul_Command2,
1097                              devpriv->iobase + APCI1564_COUNTER3 +
1098                              APCI1564_TCW_PROG);
1099                 }
1100         }       /*  if ((ui_C3 == 1) */
1101
1102         if (ui_C4 == 1) {
1103                 devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
1104                 if (devpriv->b_TimerSelectMode) {
1105
1106                         /*  Disable Counter Interrupt */
1107                         ul_Command2 =
1108                                 inl(devpriv->iobase + APCI1564_COUNTER4 +
1109                                     APCI1564_TCW_PROG);
1110                         outl(0x0,
1111                              devpriv->iobase + APCI1564_COUNTER4 +
1112                              APCI1564_TCW_PROG);
1113
1114                         /* Send a signal to from kernel to user space */
1115                         send_sig(SIGIO, devpriv->tsk_Current, 0);
1116
1117                         /*  Enable Counter Interrupt */
1118                         outl(ul_Command2,
1119                              devpriv->iobase + APCI1564_COUNTER4 +
1120                              APCI1564_TCW_PROG);
1121                 }
1122         }       /*  if (ui_C4 == 1) */
1123         return;
1124 }
1125
1126 /*
1127 +----------------------------------------------------------------------------+
1128 | Function   Name   : int i_APCI1564_Reset(struct comedi_device *dev)               |                                                       |
1129 +----------------------------------------------------------------------------+
1130 | Task              :resets all the registers                                |
1131 +----------------------------------------------------------------------------+
1132 | Input Parameters  : struct comedi_device *dev
1133 +----------------------------------------------------------------------------+
1134 | Output Parameters :   --                                                                                                       |
1135 +----------------------------------------------------------------------------+
1136 | Return Value      :                                                        |
1137 |                                                                                |
1138 +----------------------------------------------------------------------------+
1139 */
1140
1141 static int i_APCI1564_Reset(struct comedi_device *dev)
1142 {
1143         struct addi_private *devpriv = dev->private;
1144
1145         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ);     /* disable the interrupts */
1146         inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS);      /* Reset the interrupt status register */
1147         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1); /* Disable the and/or interrupt */
1148         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
1149         devpriv->b_DigitalOutputRegister = 0;
1150         ui_Type = 0;
1151         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP); /* Resets the output channels */
1152         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_INTERRUPT);       /* Disables the interrupt. */
1153         outl(0x0,
1154                 devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
1155                 APCI1564_TCW_RELOAD_VALUE);
1156         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER);
1157         outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
1158
1159         outl(0x0, devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
1160         outl(0x0, devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
1161         outl(0x0, devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
1162         outl(0x0, devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);
1163         return 0;
1164 }