addi_apci_2032.c revision b3b7dab7580982a7d0b55395a8b116808447f85a
1d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten/*
2d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * addi_apci_2032.c
3d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
4d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Project manager: Eric Stolz
5d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
6d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *	ADDI-DATA GmbH
7d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *	Dieselstrasse 3
8d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *	D-77833 Ottersweier
9d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *	Tel: +19(0)7223/9493-0
10d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *	Fax: +49(0)7223/9493-92
11d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *	http://www.addi-data.com
12d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *	info@addi-data.com
13d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
14d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * This program is free software; you can redistribute it and/or modify it
15d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * under the terms of the GNU General Public License as published by the
16d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * Free Software Foundation; either version 2 of the License, or (at your
17d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * option) any later version.
18d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
19d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * This program is distributed in the hope that it will be useful, but WITHOUT
20d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
22d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * more details.
23d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
24d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * You should have received a copy of the GNU General Public License along
25d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * with this program; if not, write to the Free Software Foundation, Inc.,
26d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten *
28d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * You should also find the complete GPL in the COPYING file accompanying
29d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * this source code.
30d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten */
31d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
323d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "../comedidev.h"
333d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten#include "comedi_fc.h"
343d41c44370a9a1e78e53c9997289347ec97d46eeH Hartley Sweeten
35d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten/*
36d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten * PCI bar 1 I/O Register map
37d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten */
387180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_DO_REG			0x00
397180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_CTRL_REG		0x04
407180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_CTRL_VCC_ENA	(1 << 0)
417180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_CTRL_CC_ENA	(1 << 1)
427180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_STATUS_REG		0x08
437180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_STATUS_VCC		(1 << 0)
447180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_INT_STATUS_CC		(1 << 1)
457180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_STATUS_REG		0x0c
467180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_STATUS_IRQ		(1 << 0)
477180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_REG		0x10
487180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_RELOAD_REG	0x14
497180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_TIMEBASE		0x18
507180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_CTRL_REG		0x1c
517180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_CTRL_ENABLE	(1 << 0)
527180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_CTRL_SW_TRIG	(1 << 9)
537180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_STATUS_REG	0x20
547180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_STATUS_ENABLED	(1 << 0)
557180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten#define APCI2032_WDOG_STATUS_SW_TRIG	(1 << 1)
56d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
57d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweetenstatic unsigned int ui_InterruptData, ui_Type;
58d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
5923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstruct apci2032_private {
6023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	unsigned int wdog_ctrl;
6123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten};
6223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
63d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweetenstatic int apci2032_do_insn_bits(struct comedi_device *dev,
64d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten				 struct comedi_subdevice *s,
65d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten				 struct comedi_insn *insn,
66d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten				 unsigned int *data)
67d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{
68d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	unsigned int mask = data[0];
69d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	unsigned int bits = data[1];
70d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
717180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	s->state = inl(dev->iobase + APCI2032_DO_REG);
72d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	if (mask) {
73d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		s->state &= ~mask;
74d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		s->state |= (bits & mask);
75d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
767180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten		outl(s->state, dev->iobase + APCI2032_DO_REG);
77d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	}
78d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
79d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	data[1] = s->state;
80d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
81d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	return insn->n;
82d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten}
83d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
8423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten/*
8523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * The watchdog subdevice is configured with two INSN_CONFIG instructions:
8623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten *
8723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * Enable the watchdog and set the reload timeout:
8823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten *	data[0] = INSN_CONFIG_ARM
8923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten *	data[1] = timeout reload value
9023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten *
9123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten * Disable the watchdog:
9223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten *	data[0] = INSN_CONFIG_DISARM
9323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten */
9423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstatic int apci2032_wdog_insn_config(struct comedi_device *dev,
95d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten				     struct comedi_subdevice *s,
96d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten				     struct comedi_insn *insn,
97d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten				     unsigned int *data)
98d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{
9923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	struct apci2032_private *devpriv = dev->private;
10023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	unsigned int reload;
10123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
10223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	switch (data[0]) {
10323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	case INSN_CONFIG_ARM:
10423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		devpriv->wdog_ctrl = APCI2032_WDOG_CTRL_ENABLE;
10523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		reload = data[1] & s->maxdata;
10623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		outw(reload, dev->iobase + APCI2032_WDOG_RELOAD_REG);
10723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
10823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		/* Time base is 20ms, let the user know the timeout */
10923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		dev_info(dev->class_dev, "watchdog enabled, timeout:%dms\n",
11023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten			20 * reload + 20);
11123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		break;
11223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	case INSN_CONFIG_DISARM:
11323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		devpriv->wdog_ctrl = 0;
11423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		break;
11523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	default:
116d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		return -EINVAL;
117d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	}
118d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
11923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	outw(devpriv->wdog_ctrl, dev->iobase + APCI2032_WDOG_CTRL_REG);
12023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
121d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	return insn->n;
122d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten}
123d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
12423fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstatic int apci2032_wdog_insn_write(struct comedi_device *dev,
12523fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten				    struct comedi_subdevice *s,
12623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten				    struct comedi_insn *insn,
12723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten				    unsigned int *data)
128d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{
12923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	struct apci2032_private *devpriv = dev->private;
13023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	int i;
13123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
13223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	if (devpriv->wdog_ctrl == 0) {
13323fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		dev_warn(dev->class_dev, "watchdog is disabled\n");
134d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		return -EINVAL;
135d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	}
13623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
13723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	/* "ping" the watchdog */
13823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	for (i = 0; i < insn->n; i++) {
13923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		outw(devpriv->wdog_ctrl | APCI2032_WDOG_CTRL_SW_TRIG,
14023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten			dev->iobase + APCI2032_WDOG_CTRL_REG);
14123fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	}
14223fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
143d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	return insn->n;
144d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten}
145d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
14623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweetenstatic int apci2032_wdog_insn_read(struct comedi_device *dev,
147d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten				   struct comedi_subdevice *s,
148d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten				   struct comedi_insn *insn,
149d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten				   unsigned int *data)
150d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{
1517b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten	int i;
1527b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten
1537b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten	for (i = 0; i < insn->n; i++)
1547b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten		data[i] = inl(dev->iobase + APCI2032_WDOG_STATUS_REG);
1557b5dd1cc988cf34341319c81bb0c7ddc21a2f8eeH Hartley Sweeten
156d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	return insn->n;
157d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten}
158d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
159b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweetenstatic int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev,
160b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten					  struct comedi_subdevice *s,
161b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten					  struct comedi_insn *insn,
162b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten					  unsigned int *data)
163b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten{
164b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	unsigned int ul_Command = 0;
165b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten
166b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	if ((data[0] != 0) && (data[0] != 1)) {
167b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten		comedi_error(dev,
168b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten			"Not a valid Data !!! ,Data should be 1 or 0\n");
169b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten		return -EINVAL;
170b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	}
171b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten
172b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	if (data[1] == 1)
173b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten		ul_Command |= APCI2032_INT_CTRL_VCC_ENA;
174b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	else
175b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten		ul_Command &= ~APCI2032_INT_CTRL_VCC_ENA;
176b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten
177b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	if (data[2] == 1)
178b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten		ul_Command |= APCI2032_INT_CTRL_CC_ENA;
179b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	else
180b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten		ul_Command &= ~APCI2032_INT_CTRL_CC_ENA;
181b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten
182b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	outl(ul_Command, dev->iobase + APCI2032_INT_CTRL_REG);
183b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	ui_InterruptData = inl(dev->iobase + APCI2032_INT_CTRL_REG);
184b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten
185b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten	return insn->n;
186b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten}
187b3b7dab7580982a7d0b55395a8b116808447f85aH Hartley Sweeten
188d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweetenstatic int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev,
189d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten					  struct comedi_subdevice *s,
190d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten					  struct comedi_insn *insn,
191d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten					  unsigned int *data)
192d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{
193d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	*data = ui_Type;
194d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	return insn->n;
195d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten}
1967180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten
197d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweetenstatic void v_APCI2032_Interrupt(int irq, void *d)
198d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten{
199d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	struct comedi_device *dev = d;
200d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	unsigned int ui_DO;
201d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
2027180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	/* Check if VCC OR CC interrupt has occurred */
2037180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	ui_DO = inl(dev->iobase + APCI2032_STATUS_REG) & APCI2032_STATUS_IRQ;
204d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
205d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	if (ui_DO == 0) {
206d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		printk("\nInterrupt from unKnown source\n");
207d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	}			/*  if(ui_DO==0) */
208d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten	if (ui_DO) {
209d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten		/*  Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt. */
2107180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten		ui_Type = inl(dev->iobase + APCI2032_INT_STATUS_REG);
2117180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten		ui_Type &= (APCI2032_INT_STATUS_VCC | APCI2032_INT_STATUS_CC);
2127180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten		outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG);
213d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten
2147180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten		if (ui_Type)
215dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten			; /* send an event to indicate the interrupt */
2167180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	}
217d02178b7fb1f2545ebe1004dc8f1f4436a9d37c1H Hartley Sweeten}
218317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten
21925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweetenstatic irqreturn_t v_ADDI_Interrupt(int irq, void *d)
22025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{
221c0c3c7dfc1fd5c970b9893e68796314e8551124fH Hartley Sweeten	v_APCI2032_Interrupt(irq, d);
22225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	return IRQ_RETVAL(1);
22325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten}
22425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
225791c9792ff2d12a02f0ab1c47fd7f7a94828b05bH Hartley Sweetenstatic int apci2032_reset(struct comedi_device *dev)
22625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{
227791c9792ff2d12a02f0ab1c47fd7f7a94828b05bH Hartley Sweeten	ui_Type = 0;
2287180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	outl(0x0, dev->iobase + APCI2032_DO_REG);
2297180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	outl(0x0, dev->iobase + APCI2032_INT_CTRL_REG);
2307180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	outl(0x0, dev->iobase + APCI2032_WDOG_CTRL_REG);
2317180eb30deee6c05b8924348a7ac7d4deefcf56eH Hartley Sweeten	outl(0x0, dev->iobase + APCI2032_WDOG_RELOAD_REG);
23225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
23325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	return 0;
23425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten}
23525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
23625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweetenstatic int apci2032_auto_attach(struct comedi_device *dev,
23725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten				unsigned long context_unused)
23825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{
23925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
24023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	struct apci2032_private *devpriv;
24125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	struct comedi_subdevice *s;
2420c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten	int ret;
24325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
244c0c3c7dfc1fd5c970b9893e68796314e8551124fH Hartley Sweeten	dev->board_name = dev->driver->driver_name;
24525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
24623fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
24723fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	if (!devpriv)
24823fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten		return -ENOMEM;
24923fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten	dev->private = devpriv;
25023fb174746057b6d13539735241390eb9e3fdb46H Hartley Sweeten
25125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	ret = comedi_pci_enable(pcidev, dev->board_name);
25225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	if (ret)
25325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten		return ret;
25470ff406599a5debfa6e5ef243e5e093f63a9ed69H Hartley Sweeten	dev->iobase = pci_resource_start(pcidev, 1);
25525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
25625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	if (pcidev->irq > 0) {
25725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten		ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
25825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten				  dev->board_name, dev);
25925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten		if (ret == 0)
26025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten			dev->irq = pcidev->irq;
26125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	}
26225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
2630c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten	ret = comedi_alloc_subdevices(dev, 2);
26425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	if (ret)
26525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten		return ret;
26625adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
2670c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten	/* Initialize the digital output subdevice */
26825adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	s = &dev->subdevices[0];
269cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->type		= COMEDI_SUBD_DO;
270cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->subdev_flags	= SDF_WRITEABLE;
271cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->n_chan	= 32;
272cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->maxdata	= 1;
273cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->range_table	= &range_digital;
274cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->insn_config	= i_APCI2032_ConfigDigitalOutput;
275cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->insn_bits	= apci2032_do_insn_bits;
276cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->insn_read	= i_APCI2032_ReadInterruptStatus;
27725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
2780c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten	/* Initialize the watchdog subdevice */
2790c33bdd01abf1d6722792b2022b974116151a572H Hartley Sweeten	s = &dev->subdevices[1];
280cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->type		= COMEDI_SUBD_TIMER;
281cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->subdev_flags	= SDF_WRITEABLE;
282cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->n_chan	= 1;
283cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->maxdata	= 0xff;
284cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->insn_write	= apci2032_wdog_insn_write;
285cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->insn_read	= apci2032_wdog_insn_read;
286cf11088242f0f73cb616ab66fb16c2da3d626fffH Hartley Sweeten	s->insn_config	= apci2032_wdog_insn_config;
28725adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
288791c9792ff2d12a02f0ab1c47fd7f7a94828b05bH Hartley Sweeten	apci2032_reset(dev);
28925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	return 0;
29025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten}
29125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
29225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweetenstatic void apci2032_detach(struct comedi_device *dev)
29325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten{
29425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
29525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
296dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten	if (dev->iobase)
297dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten		apci2032_reset(dev);
298dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten	if (dev->irq)
299dce10abc499ec5e53ea01683fdb2181f24d6776dH Hartley Sweeten		free_irq(dev->irq, dev);
30025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	if (pcidev) {
30125adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten		if (dev->iobase)
30225adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten			comedi_pci_disable(pcidev);
30325adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	}
30425adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten}
30525adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten
30620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct comedi_driver apci2032_driver = {
30720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.driver_name	= "addi_apci_2032",
30820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.module		= THIS_MODULE,
30925adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	.auto_attach	= apci2032_auto_attach,
31025adf2ccf68814fade52f70ed2888b65db1e5156H Hartley Sweeten	.detach		= apci2032_detach,
31120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten};
31220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten
313a690b7e535f2f97a3a05ee570715abeb60a8910fBill Pembertonstatic int apci2032_pci_probe(struct pci_dev *dev,
31420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten					const struct pci_device_id *ent)
31520a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{
31620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	return comedi_pci_auto_config(dev, &apci2032_driver);
31720a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}
31820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten
31953b800198592b0ff96577ecc5f116f7d902a4362Bill Pembertonstatic void apci2032_pci_remove(struct pci_dev *dev)
32020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten{
32120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	comedi_pci_auto_unconfig(dev);
32220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten}
32320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten
32420a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic DEFINE_PCI_DEVICE_TABLE(apci2032_pci_table) = {
325317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten	{ PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x1004) },
326317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten	{ 0 }
327317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten};
32820a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley SweetenMODULE_DEVICE_TABLE(pci, apci2032_pci_table);
329317285d71acccbda2fbab7e53d6b33c52a151a32H Hartley Sweeten
33020a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenstatic struct pci_driver apci2032_pci_driver = {
33120a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.name		= "addi_apci_2032",
33220a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.id_table	= apci2032_pci_table,
33320a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten	.probe		= apci2032_pci_probe,
334a471eace7baa40cdf16d3f26b2f78ddce613ca8fBill Pemberton	.remove		= apci2032_pci_remove,
33520a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweeten};
33620a22b706b8ee37d1a2282f2c9bf7f2c73a5a7a5H Hartley Sweetenmodule_comedi_pci_driver(apci2032_driver, apci2032_pci_driver);
33790f703d30dd3e0c16ff80f35e34e511385a05ad5Arun Thomas
33890f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_AUTHOR("Comedi http://www.comedi.org");
33990f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_DESCRIPTION("Comedi low-level driver");
34090f703d30dd3e0c16ff80f35e34e511385a05ad5Arun ThomasMODULE_LICENSE("GPL");
341