Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-fixes
[pandora-kernel.git] / drivers / staging / comedi / drivers / addi-data / hwdrv_apci2032.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-2032       | Compiler   : GCC                      |
33   | Module name : hwdrv_apci2032.c| Version    : 2.96                     |
34   +-------------------------------+---------------------------------------+
35   | Project manager: Eric Stolz   | Date       :  02/12/2002              |
36   +-------------------------------+---------------------------------------+
37   | Description :   Hardware Layer Acces For APCI-2032                    |
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 "hwdrv_apci2032.h"
56 static unsigned int ui_InterruptData, ui_Type;
57 /*
58 +----------------------------------------------------------------------------+
59 | Function   Name   : int i_APCI2032_ConfigDigitalOutput                     |
60 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
61 |                      struct comedi_insn *insn,unsigned int *data)                     |
62 +----------------------------------------------------------------------------+
63 | Task              : Configures The Digital Output Subdevice.               |
64 +----------------------------------------------------------------------------+
65 | Input Parameters  : struct comedi_device *dev : Driver handle                     |
66 |                     unsigned int *data         : Data Pointer contains             |
67 |                                          configuration parameters as below |
68 |                                                                            |
69 |                                         data[1]            : 1 Enable  VCC  Interrupt  |
70 |                                                                                  0 Disable VCC  Interrupt  |
71 |                                         data[2]            : 1 Enable  CC  Interrupt   |
72 |                                                                                  0 Disable CC  Interrupt   |
73 |                                                                                                                                        |
74 +----------------------------------------------------------------------------+
75 | Output Parameters :   --                                                                                                       |
76 +----------------------------------------------------------------------------+
77 | Return Value      : TRUE  : No error occur                                 |
78 |                           : FALSE : Error occur. Return the error          |
79 |                                                                                |
80 +----------------------------------------------------------------------------+
81 */
82 int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
83         struct comedi_insn *insn, unsigned int *data)
84 {
85         unsigned int ul_Command = 0;
86         devpriv->tsk_Current = current;
87
88         if ((data[0] != 0) && (data[0] != 1)) {
89                 comedi_error(dev,
90                         "Not a valid Data !!! ,Data should be 1 or 0\n");
91                 return -EINVAL;
92         }                       /* if  ( (data[0]!=0) && (data[0]!=1) ) */
93         if (data[0]) {
94                 devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
95         }                       /*  if  (data[0]) */
96         else {
97                 devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
98         }                       /* else if  (data[0]) */
99
100         if (data[1] == ADDIDATA_ENABLE) {
101                 ul_Command = ul_Command | 0x1;
102         }                       /* if  (data[1] == ADDIDATA_ENABLE) */
103         else {
104                 ul_Command = ul_Command & 0xFFFFFFFE;
105         }                       /* elseif  (data[1] == ADDIDATA_ENABLE) */
106         if (data[2] == ADDIDATA_ENABLE) {
107                 ul_Command = ul_Command | 0x2;
108         }                       /* if  (data[2] == ADDIDATA_ENABLE) */
109         else {
110                 ul_Command = ul_Command & 0xFFFFFFFD;
111         }                       /* elseif  (data[2] == ADDIDATA_ENABLE) */
112         outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
113         ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
114         return insn->n;
115 }
116
117 /*
118 +----------------------------------------------------------------------------+
119 | Function   Name   : int i_APCI2032_WriteDigitalOutput                      |
120 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
121 |                      struct comedi_insn *insn,unsigned int *data)                     |
122 +----------------------------------------------------------------------------+
123 | Task              : Writes port value  To the selected port                |
124 +----------------------------------------------------------------------------+
125 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
126 |                     unsigned int ui_NoOfChannels    : No Of Channels To Write      |
127 |                     unsigned int *data              : Data Pointer to read status  |
128 +----------------------------------------------------------------------------+
129 | Output Parameters :   --                                                                                                       |
130 +----------------------------------------------------------------------------+
131 | Return Value      : TRUE  : No error occur                                 |
132 |                           : FALSE : Error occur. Return the error          |
133 |                                                                                |
134 +----------------------------------------------------------------------------+
135 */
136
137 int i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
138         struct comedi_insn *insn, unsigned int *data)
139 {
140         unsigned int ui_Temp, ui_Temp1;
141         unsigned int ui_NoOfChannel = CR_CHAN(insn->chanspec);  /*  get the channel */
142         if (devpriv->b_OutputMemoryStatus) {
143                 ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP);
144
145         }                       /* if(devpriv->b_OutputMemoryStatus ) */
146         else {
147                 ui_Temp = 0;
148         }                       /* if(devpriv->b_OutputMemoryStatus ) */
149         if (data[3] == 0) {
150                 if (data[1] == 0) {
151                         data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
152                         outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP);
153                 }               /* if(data[1]==0) */
154                 else {
155                         if (data[1] == 1) {
156                                 switch (ui_NoOfChannel) {
157
158                                 case 2:
159                                         data[0] =
160                                                 (data[0] << (2 *
161                                                         data[2])) | ui_Temp;
162                                         break;
163
164                                 case 4:
165                                         data[0] =
166                                                 (data[0] << (4 *
167                                                         data[2])) | ui_Temp;
168                                         break;
169
170                                 case 8:
171                                         data[0] =
172                                                 (data[0] << (8 *
173                                                         data[2])) | ui_Temp;
174                                         break;
175
176                                 case 16:
177                                         data[0] =
178                                                 (data[0] << (16 *
179                                                         data[2])) | ui_Temp;
180                                         break;
181                                 case 31:
182                                         data[0] = data[0] | ui_Temp;
183                                         break;
184
185                                 default:
186                                         comedi_error(dev, " chan spec wrong");
187                                         return -EINVAL; /*  "sorry channel spec wrong " */
188
189                                 }       /* switch(ui_NoOfChannels) */
190
191                                 outl(data[0],
192                                         devpriv->iobase + APCI2032_DIGITAL_OP);
193                         }       /*  if(data[1]==1) */
194                         else {
195                                 printk("\nSpecified channel not supported\n");
196                         }       /* else if(data[1]==1) */
197                 }               /* elseif(data[1]==0) */
198         }                       /* if(data[3]==0) */
199         else {
200                 if (data[3] == 1) {
201                         if (data[1] == 0) {
202                                 data[0] = ~data[0] & 0x1;
203                                 ui_Temp1 = 1;
204                                 ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
205                                 ui_Temp = ui_Temp | ui_Temp1;
206                                 data[0] =
207                                         (data[0] << ui_NoOfChannel) ^
208                                         0xffffffff;
209                                 data[0] = data[0] & ui_Temp;
210                                 outl(data[0],
211                                         devpriv->iobase + APCI2032_DIGITAL_OP);
212                         }       /* if(data[1]==0) */
213                         else {
214                                 if (data[1] == 1) {
215                                         switch (ui_NoOfChannel) {
216
217                                         case 2:
218                                                 data[0] = ~data[0] & 0x3;
219                                                 ui_Temp1 = 3;
220                                                 ui_Temp1 =
221                                                         ui_Temp1 << 2 * data[2];
222                                                 ui_Temp = ui_Temp | ui_Temp1;
223                                                 data[0] =
224                                                         ((data[0] << (2 *
225                                                                         data
226                                                                         [2])) ^
227                                                         0xffffffff) & ui_Temp;
228                                                 break;
229
230                                         case 4:
231                                                 data[0] = ~data[0] & 0xf;
232                                                 ui_Temp1 = 15;
233                                                 ui_Temp1 =
234                                                         ui_Temp1 << 4 * data[2];
235                                                 ui_Temp = ui_Temp | ui_Temp1;
236                                                 data[0] =
237                                                         ((data[0] << (4 *
238                                                                         data
239                                                                         [2])) ^
240                                                         0xffffffff) & ui_Temp;
241                                                 break;
242
243                                         case 8:
244                                                 data[0] = ~data[0] & 0xff;
245                                                 ui_Temp1 = 255;
246                                                 ui_Temp1 =
247                                                         ui_Temp1 << 8 * data[2];
248                                                 ui_Temp = ui_Temp | ui_Temp1;
249                                                 data[0] =
250                                                         ((data[0] << (8 *
251                                                                         data
252                                                                         [2])) ^
253                                                         0xffffffff) & ui_Temp;
254                                                 break;
255
256                                         case 16:
257                                                 data[0] = ~data[0] & 0xffff;
258                                                 ui_Temp1 = 65535;
259                                                 ui_Temp1 =
260                                                         ui_Temp1 << 16 *
261                                                         data[2];
262                                                 ui_Temp = ui_Temp | ui_Temp1;
263                                                 data[0] =
264                                                         ((data[0] << (16 *
265                                                                         data
266                                                                         [2])) ^
267                                                         0xffffffff) & ui_Temp;
268                                                 break;
269
270                                         case 31:
271                                                 break;
272                                         default:
273                                                 comedi_error(dev,
274                                                         " chan spec wrong");
275                                                 return -EINVAL; /*  "sorry channel spec wrong " */
276
277                                         }       /* switch(ui_NoOfChannels) */
278
279                                         outl(data[0],
280                                                 devpriv->iobase +
281                                                 APCI2032_DIGITAL_OP);
282                                 }       /*  if(data[1]==1) */
283                                 else {
284                                         printk("\nSpecified channel not supported\n");
285                                 }       /* else if(data[1]==1) */
286                         }       /* elseif(data[1]==0) */
287                 }               /* if(data[3]==1); */
288                 else {
289                         printk("\nSpecified functionality does not exist\n");
290                         return -EINVAL;
291                 }               /* if else data[3]==1) */
292         }                       /* if else data[3]==0) */
293         return insn->n;
294 }
295
296 /*
297 +----------------------------------------------------------------------------+
298 | Function   Name   : int i_APCI2032_ReadDigitalOutput                       |
299 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
300 |                      struct comedi_insn *insn,unsigned int *data)                     |
301 +----------------------------------------------------------------------------+
302 | Task              : Read  value  of the selected channel or port           |
303 +----------------------------------------------------------------------------+
304 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
305 |                     unsigned int ui_NoOfChannels    : No Of Channels To read       |
306 |                     unsigned int *data              : Data Pointer to read status  |
307 +----------------------------------------------------------------------------+
308 | Output Parameters :   --                                                                                                       |
309 +----------------------------------------------------------------------------+
310 | Return Value      : TRUE  : No error occur                                 |
311 |                           : FALSE : Error occur. Return the error          |
312 |                                                                                |
313 +----------------------------------------------------------------------------+
314 */
315
316 int i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
317         struct comedi_insn *insn, unsigned int *data)
318 {
319         unsigned int ui_Temp;
320         unsigned int ui_NoOfChannel;
321         ui_NoOfChannel = CR_CHAN(insn->chanspec);
322         ui_Temp = data[0];
323         *data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW);
324         if (ui_Temp == 0) {
325                 *data = (*data >> ui_NoOfChannel) & 0x1;
326         }                       /* if  (ui_Temp==0) */
327         else {
328                 if (ui_Temp == 1) {
329                         switch (ui_NoOfChannel) {
330
331                         case 2:
332                                 *data = (*data >> (2 * data[1])) & 3;
333                                 break;
334
335                         case 4:
336                                 *data = (*data >> (4 * data[1])) & 15;
337                                 break;
338
339                         case 8:
340                                 *data = (*data >> (8 * data[1])) & 255;
341                                 break;
342
343                         case 16:
344                                 *data = (*data >> (16 * data[1])) & 65535;
345                                 break;
346
347                         case 31:
348                                 break;
349
350                         default:
351                                 comedi_error(dev, " chan spec wrong");
352                                 return -EINVAL; /*  "sorry channel spec wrong " */
353
354                         }       /* switch(ui_NoOfChannels) */
355                 }               /* if  (ui_Temp==1) */
356                 else {
357                         printk("\nSpecified channel not supported \n");
358                 }               /* elseif  (ui_Temp==1) */
359         }
360         return insn->n;
361 }
362
363 /*
364 +----------------------------------------------------------------------------+
365 | Function   Name   : int i_APCI2032_ConfigWatchdog(comedi_device
366 |                   *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
367 |                                                                                    |
368 +----------------------------------------------------------------------------+
369 | Task              : Configures The Watchdog                                |
370 +----------------------------------------------------------------------------+
371 | Input Parameters  : struct comedi_device *dev      : Driver handle                |
372 |                     struct comedi_subdevice *s,   :pointer to subdevice structure
373 |                      struct comedi_insn *insn      :pointer to insn structure      |
374 |                     unsigned int *data          : Data Pointer to read status                                                                                                             |
375 +----------------------------------------------------------------------------+
376 | Output Parameters :   --                                                                                                       |
377 +----------------------------------------------------------------------------+
378 | Return Value      : TRUE  : No error occur                                 |
379 |                           : FALSE : Error occur. Return the error          |
380 |                                                                                |
381 +----------------------------------------------------------------------------+
382 */
383 int i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
384         struct comedi_insn *insn, unsigned int *data)
385 {
386         if (data[0] == 0) {
387                 /* Disable the watchdog */
388                 outl(0x0,
389                         devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
390                         APCI2032_TCW_PROG);
391                 /* Loading the Reload value */
392                 outl(data[1],
393                         devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
394                         APCI2032_TCW_RELOAD_VALUE);
395         } else {
396                 printk("\nThe input parameters are wrong\n");
397                 return -EINVAL;
398         }
399
400         return insn->n;
401 }
402
403  /*
404     +----------------------------------------------------------------------------+
405     | Function   Name   : int i_APCI2032_StartStopWriteWatchdog                  |
406     |                           (struct comedi_device *dev,struct comedi_subdevice *s,
407     struct comedi_insn *insn,unsigned int *data);                      |
408     +----------------------------------------------------------------------------+
409     | Task              : Start / Stop The Watchdog                              |
410     +----------------------------------------------------------------------------+
411     | Input Parameters  : struct comedi_device *dev      : Driver handle                |
412     |                     struct comedi_subdevice *s,   :pointer to subdevice structure
413     struct comedi_insn *insn      :pointer to insn structure      |
414     |                     unsigned int *data          : Data Pointer to read status  |
415     +----------------------------------------------------------------------------+
416     | Output Parameters :       --                                                                                                       |
417     +----------------------------------------------------------------------------+
418     | Return Value      : TRUE  : No error occur                                 |
419     |                       : FALSE : Error occur. Return the error          |
420     |                                                                            |
421     +----------------------------------------------------------------------------+
422   */
423
424 int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
425         struct comedi_insn *insn, unsigned int *data)
426 {
427         switch (data[0]) {
428         case 0:         /* stop the watchdog */
429                 outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG);  /* disable the watchdog */
430                 break;
431         case 1:         /* start the watchdog */
432                 outl(0x0001,
433                         devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
434                         APCI2032_TCW_PROG);
435                 break;
436         case 2:         /* Software trigger */
437                 outl(0x0201,
438                         devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
439                         APCI2032_TCW_PROG);
440                 break;
441         default:
442                 printk("\nSpecified functionality does not exist\n");
443                 return -EINVAL;
444         }
445         return insn->n;
446 }
447
448 /*
449 +----------------------------------------------------------------------------+
450 | Function   Name   : int i_APCI2032_ReadWatchdog                            |
451 |                       (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
452 |                    unsigned int *data);                                            |
453 +----------------------------------------------------------------------------+
454 | Task              : Read The Watchdog                                      |
455 +----------------------------------------------------------------------------+
456 | Input Parameters  :   struct comedi_device *dev      : Driver handle              |
457 |                     struct comedi_subdevice *s,   :pointer to subdevice structure
458 |                      struct comedi_insn *insn      :pointer to insn structure      |
459 |                     unsigned int *data          : Data Pointer to read status  |
460 +----------------------------------------------------------------------------+
461 | Output Parameters :   --                                                                                                       |
462 +----------------------------------------------------------------------------+
463 | Return Value      : TRUE  : No error occur                                 |
464 |                           : FALSE : Error occur. Return the error          |
465 |                                                                                |
466 +----------------------------------------------------------------------------+
467 */
468
469 int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
470         struct comedi_insn *insn, unsigned int *data)
471 {
472
473         data[0] =
474                 inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
475                 APCI2032_TCW_TRIG_STATUS) & 0x1;
476         return insn->n;
477 }
478
479 /*
480 +----------------------------------------------------------------------------+
481 | Function   Name   :  void v_APCI2032_Interrupt                                                 |
482 |                                         (int irq , void *d)      |
483 +----------------------------------------------------------------------------+
484 | Task              : Writes port value  To the selected port                |
485 +----------------------------------------------------------------------------+
486 | Input Parameters  : int irq                 : irq number                   |
487 |                     void *d                 : void pointer                 |
488 +----------------------------------------------------------------------------+
489 | Output Parameters :   --                                                                                                       |
490 +----------------------------------------------------------------------------+
491 | Return Value      : TRUE  : No error occur                                 |
492 |                           : FALSE : Error occur. Return the error          |
493 |                                                                                |
494 +----------------------------------------------------------------------------+
495 */
496 void v_APCI2032_Interrupt(int irq, void *d)
497 {
498         struct comedi_device *dev = d;
499         unsigned int ui_DO;
500
501         ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1;   /* Check if VCC OR CC interrupt has occured. */
502
503         if (ui_DO == 0) {
504                 printk("\nInterrupt from unKnown source\n");
505         }                       /*  if(ui_DO==0) */
506         if (ui_DO) {
507                 /*  Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt. */
508                 ui_Type =
509                         inl(devpriv->iobase +
510                         APCI2032_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
511                 outl(0x0,
512                         devpriv->iobase + APCI2032_DIGITAL_OP +
513                         APCI2032_DIGITAL_OP_INTERRUPT);
514                 if (ui_Type == 1) {
515                         /* Sends signal to user space */
516                         send_sig(SIGIO, devpriv->tsk_Current, 0);
517                 }               /*  if (ui_Type==1) */
518                 else {
519                         if (ui_Type == 2) {
520                                 /*  Sends signal to user space */
521                                 send_sig(SIGIO, devpriv->tsk_Current, 0);
522                         }       /* if (ui_Type==2) */
523                 }               /* else if (ui_Type==1) */
524         }                       /* if(ui_DO) */
525
526         return;
527
528 }
529
530 /*
531 +----------------------------------------------------------------------------+
532 | Function   Name   :  int i_APCI2032_ReadInterruptStatus                    |
533 |                         (struct comedi_device *dev,struct comedi_subdevice *s,               |
534 |                      struct comedi_insn *insn,unsigned int *data)                     |
535 +----------------------------------------------------------------------------+
536 | Task              :Reads the interrupt status register                     |
537 +----------------------------------------------------------------------------+
538 | Input Parameters  :                                                        |
539 +----------------------------------------------------------------------------+
540 | Output Parameters :   --                                                                                                       |
541 +----------------------------------------------------------------------------+
542 | Return Value      :                                                        |
543 |                                                                                |
544 +----------------------------------------------------------------------------+
545 */
546
547 int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
548         struct comedi_insn *insn, unsigned int *data)
549 {
550         *data = ui_Type;
551         return insn->n;
552 }
553
554 /*
555 +----------------------------------------------------------------------------+
556 | Function   Name   :  int i_APCI2032_Reset(struct comedi_device *dev)                       |
557 |                                                                                        |
558 +----------------------------------------------------------------------------+
559 | Task              :Resets the registers of the card                        |
560 +----------------------------------------------------------------------------+
561 | Input Parameters  :                                                        |
562 +----------------------------------------------------------------------------+
563 | Output Parameters :   --                                                                                                       |
564 +----------------------------------------------------------------------------+
565 | Return Value      :                                                        |
566 |                                                                                |
567 +----------------------------------------------------------------------------+
568 */
569
570 int i_APCI2032_Reset(struct comedi_device *dev)
571 {
572         devpriv->b_DigitalOutputRegister = 0;
573         ui_Type = 0;
574         outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP);       /* Resets the output channels */
575         outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);     /* Disables the interrupt. */
576         outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG);  /* disable the watchdog */
577         outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE);  /* reload=0 */
578         return 0;
579 }