1ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef/*
2ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    comedi/drivers/ni_6527.c
3ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    driver for National Instruments PCI-6527
4ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
5ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    COMEDI - Linux Control and Measurement Device Interface
6ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
7ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
8ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    This program is free software; you can redistribute it and/or modify
9ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    it under the terms of the GNU General Public License as published by
10ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    the Free Software Foundation; either version 2 of the License, or
11ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    (at your option) any later version.
12ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
13ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    This program is distributed in the hope that it will be useful,
14ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    but WITHOUT ANY WARRANTY; without even the implied warranty of
15ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    GNU General Public License for more details.
17ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
18ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    You should have received a copy of the GNU General Public License
19ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    along with this program; if not, write to the Free Software
20ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
22ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef*/
23ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef/*
24ef2ccffba409c4ab73edd78191b503a2c34b5965David SchleefDriver: ni_6527
25ef2ccffba409c4ab73edd78191b503a2c34b5965David SchleefDescription: National Instruments 6527
26ef2ccffba409c4ab73edd78191b503a2c34b5965David SchleefAuthor: ds
27ef2ccffba409c4ab73edd78191b503a2c34b5965David SchleefStatus: works
28ef2ccffba409c4ab73edd78191b503a2c34b5965David SchleefDevices: [National Instruments] PCI-6527 (ni6527), PXI-6527
29ef2ccffba409c4ab73edd78191b503a2c34b5965David SchleefUpdated: Sat, 25 Jan 2003 13:24:40 -0800
30ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
31ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
32ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef*/
33ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
34ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef/*
35ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef   Manuals (available from ftp://ftp.natinst.com/support/manuals)
36ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
37ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	370106b.pdf	6527 Register Level Programmer Manual
38ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
39ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef */
40ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
41ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define DEBUG 1
42ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define DEBUG_FLAGS
43ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
4425436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h>
45ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#include "../comedidev.h"
46ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
47ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#include "mite.h"
48ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
49ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define NI6527_DIO_SIZE 4096
50ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define NI6527_MITE_SIZE 4096
51ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
52ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define Port_Register(x)			(0x00+(x))
53ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define ID_Register				0x06
54ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
55ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define Clear_Register				0x07
56ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define ClrEdge				0x08
57ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define ClrOverflow			0x04
58ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define ClrFilter			0x02
59ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define ClrInterval			0x01
60ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
61ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define Filter_Interval(x)			(0x08+(x))
62ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define Filter_Enable(x)			(0x0c+(x))
63ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
64ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define Change_Status				0x14
65ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define MasterInterruptStatus		0x04
66ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define Overflow			0x02
67ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define EdgeStatus			0x01
68ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
69ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define Master_Interrupt_Control		0x15
70ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define FallingEdgeIntEnable		0x10
71ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define RisingEdgeIntEnable		0x08
72ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define MasterInterruptEnable		0x04
73ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define OverflowIntEnable		0x02
74ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define EdgeIntEnable			0x01
75ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
76ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define Rising_Edge_Detection_Enable(x)		(0x018+(x))
77ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef#define Falling_Edge_Detection_Enable(x)	(0x020+(x))
78ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni6527_attach(struct comedi_device *dev,
800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			 struct comedi_devconfig *it);
81da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni6527_detach(struct comedi_device *dev);
82139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_ni6527 = {
8368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.driver_name = "ni6527",
8468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.module = THIS_MODULE,
8568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.attach = ni6527_attach,
8668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.detach = ni6527_detach,
87ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef};
88ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
8916d38ca3514bfcfad78f97dc136c955616303bf4Bill Pembertonstruct ni6527_board {
9016d38ca3514bfcfad78f97dc136c955616303bf4Bill Pemberton
91ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	int dev_id;
92ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	const char *name;
9316d38ca3514bfcfad78f97dc136c955616303bf4Bill Pemberton};
9416d38ca3514bfcfad78f97dc136c955616303bf4Bill Pemberton
9516d38ca3514bfcfad78f97dc136c955616303bf4Bill Pembertonstatic const struct ni6527_board ni6527_boards[] = {
96ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	{
970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .dev_id = 0x2b20,
980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "pci-6527",
990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
100ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	{
1010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .dev_id = 0x2b10,
1020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "pxi-6527",
1030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
104ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef};
105ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
106b6ac161364eccce1bea4a23a9de395883e90d7abStoyan Gaydarov#define n_ni6527_boards ARRAY_SIZE(ni6527_boards)
10716d38ca3514bfcfad78f97dc136c955616303bf4Bill Pemberton#define this_board ((const struct ni6527_board *)dev->board_ptr)
108ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
109ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleefstatic DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
1104e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b10)},
1114e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman	{PCI_DEVICE(PCI_VENDOR_ID_NI, 0x2b20)},
1124e40cee9c8a46d4231d28ae7ae6d9938cf0526d5Greg Kroah-Hartman	{0}
113ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef};
114ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
115ef2ccffba409c4ab73edd78191b503a2c34b5965David SchleefMODULE_DEVICE_TABLE(pci, ni6527_pci_table);
116ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
117f4c6b31958afecc08c8e83f3bc25161ce4442542Bill Pembertonstruct ni6527_private {
118ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	struct mite_struct *mite;
119ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	unsigned int filter_interval;
120ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	unsigned int filter_enable;
121f4c6b31958afecc08c8e83f3bc25161ce4442542Bill Pemberton};
122f4c6b31958afecc08c8e83f3bc25161ce4442542Bill Pemberton
123f4c6b31958afecc08c8e83f3bc25161ce4442542Bill Pemberton#define devpriv ((struct ni6527_private *)dev->private)
124ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
125da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni6527_find_device(struct comedi_device *dev, int bus, int slot);
126ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
1270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni6527_di_insn_config(struct comedi_device *dev,
1280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				 struct comedi_subdevice *s,
1290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				 struct comedi_insn *insn, unsigned int *data)
130ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
131ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	int chan = CR_CHAN(insn->chanspec);
132ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	unsigned int interval;
133ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
134ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (insn->n != 2)
135ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return -EINVAL;
136ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
137ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (data[0] != INSN_CONFIG_FILTER)
138ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return -EINVAL;
139ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
140ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (data[1]) {
141ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		interval = (data[1] + 100) / 200;
142ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		data[1] = interval * 200;
143ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
144ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		if (interval != devpriv->filter_interval) {
145ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			writeb(interval & 0xff,
1460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       devpriv->mite->daq_io_addr + Filter_Interval(0));
147ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			writeb((interval >> 8) & 0xff,
1480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       devpriv->mite->daq_io_addr + Filter_Interval(1));
149ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			writeb((interval >> 16) & 0x0f,
1500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       devpriv->mite->daq_io_addr + Filter_Interval(2));
151ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
152ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			writeb(ClrInterval,
1530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       devpriv->mite->daq_io_addr + Clear_Register);
154ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
155ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			devpriv->filter_interval = interval;
156ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		}
157ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
158ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		devpriv->filter_enable |= 1 << chan;
159ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	} else {
160ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		devpriv->filter_enable &= ~(1 << chan);
161ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	}
162ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
163ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(devpriv->filter_enable,
1640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Filter_Enable(0));
165ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(devpriv->filter_enable >> 8,
1660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Filter_Enable(1));
167ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(devpriv->filter_enable >> 16,
1680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Filter_Enable(2));
169ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
170ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 2;
171ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
172ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
1730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni6527_di_insn_bits(struct comedi_device *dev,
1740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       struct comedi_subdevice *s,
1750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       struct comedi_insn *insn, unsigned int *data)
176ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
177ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (insn->n != 2)
178ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return -EINVAL;
179ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
180ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0));
181ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8;
182ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16;
183ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
184ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 2;
185ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
186ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
1870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni6527_do_insn_bits(struct comedi_device *dev,
1880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       struct comedi_subdevice *s,
1890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       struct comedi_insn *insn, unsigned int *data)
190ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
191ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (insn->n != 2)
192ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return -EINVAL;
193ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (data[0]) {
194ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		s->state &= ~data[0];
195ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		s->state |= (data[0] & data[1]);
196ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
197ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		/* The open relay state on the board cooresponds to 1,
198ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		 * but in Comedi, it is represented by 0. */
199ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		if (data[0] & 0x0000ff) {
200ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			writeb((s->state ^ 0xff),
2010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       devpriv->mite->daq_io_addr + Port_Register(3));
202ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		}
203ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		if (data[0] & 0x00ff00) {
204ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			writeb((s->state >> 8) ^ 0xff,
2050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       devpriv->mite->daq_io_addr + Port_Register(4));
206ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		}
207ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		if (data[0] & 0xff0000) {
208ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			writeb((s->state >> 16) ^ 0xff,
2090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       devpriv->mite->daq_io_addr + Port_Register(5));
210ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		}
211ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	}
212ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	data[1] = s->state;
213ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
214ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 2;
215ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
216ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
21770265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t ni6527_interrupt(int irq, void *d)
218ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
21971b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton	struct comedi_device *dev = d;
22034c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s = dev->subdevices + 2;
221ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	unsigned int status;
222ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
223ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	status = readb(devpriv->mite->daq_io_addr + Change_Status);
224ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if ((status & MasterInterruptStatus) == 0)
225ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return IRQ_NONE;
226ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if ((status & EdgeStatus) == 0)
227ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return IRQ_NONE;
228ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
229ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(ClrEdge | ClrOverflow,
2300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Clear_Register);
231ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
232ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	comedi_buf_put(s->async, 0);
233ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->async->events |= COMEDI_CB_EOS;
234ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	comedi_event(dev, s);
235ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return IRQ_HANDLED;
236ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
237ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
2380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni6527_intr_cmdtest(struct comedi_device *dev,
2390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       struct comedi_subdevice *s,
2400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       struct comedi_cmd *cmd)
241ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
242ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	int err = 0;
243ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	int tmp;
244ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
245ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	/* step 1: make sure trigger sources are trivially valid */
246ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
247ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	tmp = cmd->start_src;
248ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	cmd->start_src &= TRIG_NOW;
249ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (!cmd->start_src || tmp != cmd->start_src)
250ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
251ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
252ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	tmp = cmd->scan_begin_src;
253ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	cmd->scan_begin_src &= TRIG_OTHER;
254ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
255ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
256ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
257ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	tmp = cmd->convert_src;
258ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	cmd->convert_src &= TRIG_FOLLOW;
259ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (!cmd->convert_src || tmp != cmd->convert_src)
260ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
261ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
262ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	tmp = cmd->scan_end_src;
263ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	cmd->scan_end_src &= TRIG_COUNT;
264ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
265ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
266ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
267ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	tmp = cmd->stop_src;
268ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	cmd->stop_src &= TRIG_COUNT;
269ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (!cmd->stop_src || tmp != cmd->stop_src)
270ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
271ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
272ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (err)
273ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return 1;
274ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
275a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	/* step 2: make sure trigger sources are unique and */
276a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	/*         are mutually compatible */
277ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
278ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (err)
279ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return 2;
280ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
281ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	/* step 3: make sure arguments are trivially compatible */
282ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
283ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (cmd->start_arg != 0) {
284ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		cmd->start_arg = 0;
285ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
286ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	}
287ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (cmd->scan_begin_arg != 0) {
288ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		cmd->scan_begin_arg = 0;
289ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
290ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	}
291ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (cmd->convert_arg != 0) {
292ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		cmd->convert_arg = 0;
293ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
294ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	}
295ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
296ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (cmd->scan_end_arg != 1) {
297ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		cmd->scan_end_arg = 1;
298ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
299ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	}
300ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (cmd->stop_arg != 0) {
301ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		cmd->stop_arg = 0;
302ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		err++;
303ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	}
304ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
305ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (err)
306ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return 3;
307ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
308ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	/* step 4: fix up any arguments */
309ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
310ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (err)
311ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return 4;
312ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
313ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 0;
314ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
315ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
3160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni6527_intr_cmd(struct comedi_device *dev,
3170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   struct comedi_subdevice *s)
318ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
3192696fb57e6af653dd8b4df41b16754579f42fc78Bill Pemberton	/* struct comedi_cmd *cmd = &s->async->cmd; */
320ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
321ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(ClrEdge | ClrOverflow,
3220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Clear_Register);
323ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
3240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       MasterInterruptEnable | EdgeIntEnable,
3250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Master_Interrupt_Control);
326ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
327ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 0;
328ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
329ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
3300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni6527_intr_cancel(struct comedi_device *dev,
3310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			      struct comedi_subdevice *s)
332ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
333ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
334ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
335ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 0;
336ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
337ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
3380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni6527_intr_insn_bits(struct comedi_device *dev,
3390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				 struct comedi_subdevice *s,
3400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				 struct comedi_insn *insn, unsigned int *data)
341ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
342ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (insn->n < 1)
343ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return -EINVAL;
344ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
345ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	data[1] = 0;
346ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 2;
347ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
348ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
3490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni6527_intr_insn_config(struct comedi_device *dev,
3500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				   struct comedi_subdevice *s,
3510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral				   struct comedi_insn *insn, unsigned int *data)
352ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
353ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (insn->n < 1)
354ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return -EINVAL;
355ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
356ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return -EINVAL;
357ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
358ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(data[1],
3590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
360ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(data[1] >> 8,
3610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
362ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(data[1] >> 16,
3630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
364ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
365ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(data[2],
3660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
367ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(data[2] >> 8,
3680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
369ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(data[2] >> 16,
3700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
371ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
372ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 2;
373ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
374ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
375da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni6527_attach(struct comedi_device *dev, struct comedi_devconfig *it)
376ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
37734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
378ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	int ret;
379ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
380a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	printk(KERN_INFO "comedi%d: ni6527\n", dev->minor);
381ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
382c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = alloc_private(dev, sizeof(struct ni6527_private));
383c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	if (ret < 0)
384ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return ret;
385ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
386ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	ret = ni6527_find_device(dev, it->options[0], it->options[1]);
387ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (ret < 0)
388ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return ret;
389ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
390ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	ret = mite_setup(devpriv->mite);
391ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	if (ret < 0) {
392a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend		printk(KERN_ERR "comedi: error setting up mite\n");
393ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return ret;
394ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	}
395ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
396ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	dev->board_name = this_board->name;
397a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	printk(KERN_INFO "comedi board: %s, ID=0x%02x\n", dev->board_name,
398a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend		readb(devpriv->mite->daq_io_addr + ID_Register));
399ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
400c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = alloc_subdevices(dev, 3);
401c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	if (ret < 0)
402ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		return ret;
403ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
404ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s = dev->subdevices + 0;
405ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->type = COMEDI_SUBD_DI;
406ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->subdev_flags = SDF_READABLE;
407ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->n_chan = 24;
408ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->range_table = &range_digital;
409ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->maxdata = 1;
410ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->insn_config = ni6527_di_insn_config;
411ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->insn_bits = ni6527_di_insn_bits;
412ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
413ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s = dev->subdevices + 1;
414ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->type = COMEDI_SUBD_DO;
415ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
416ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->n_chan = 24;
417a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	s->range_table = &range_unknown;  /* FIXME: actually conductance */
418ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->maxdata = 1;
419ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->insn_bits = ni6527_do_insn_bits;
420ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
421ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s = dev->subdevices + 2;
422ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	dev->read_subdev = s;
423ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->type = COMEDI_SUBD_DI;
424ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
425ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->n_chan = 1;
426ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->range_table = &range_unknown;
427ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->maxdata = 1;
428ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->do_cmdtest = ni6527_intr_cmdtest;
429ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->do_cmd = ni6527_intr_cmd;
430ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->cancel = ni6527_intr_cancel;
431ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->insn_bits = ni6527_intr_insn_bits;
432ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	s->insn_config = ni6527_intr_insn_config;
433ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
434ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0));
435ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(1));
436ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
437ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
438ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
4390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	       devpriv->mite->daq_io_addr + Clear_Register);
440ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
441ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
4425f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	ret = request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
4435f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman			  IRQF_SHARED, "ni6527", dev);
444a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	if (ret < 0)
445a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend		printk(KERN_WARNING "comedi i6527 irq not available\n");
446a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	else
447ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		dev->irq = mite_irq(devpriv->mite);
448ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
449ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 0;
450ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
451ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
452da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni6527_detach(struct comedi_device *dev)
453ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
454a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr)
455ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		writeb(0x00,
4560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		       devpriv->mite->daq_io_addr + Master_Interrupt_Control);
457ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
458a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	if (dev->irq)
4595f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		free_irq(dev->irq, dev);
460ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
461a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	if (devpriv && devpriv->mite)
462ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		mite_unsetup(devpriv->mite);
463ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
464ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return 0;
465ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
466ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
467da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni6527_find_device(struct comedi_device *dev, int bus, int slot)
468ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef{
469ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	struct mite_struct *mite;
470ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	int i;
471ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
472ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	for (mite = mite_devices; mite; mite = mite->next) {
473ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		if (mite->used)
474ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			continue;
475ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		if (bus || slot) {
476ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			if (bus != mite->pcidev->bus->number ||
4770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			    slot != PCI_SLOT(mite->pcidev->devfn))
478ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef				continue;
479ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		}
480ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		for (i = 0; i < n_ni6527_boards; i++) {
481ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			if (mite_device_id(mite) == ni6527_boards[i].dev_id) {
482ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef				dev->board_ptr = ni6527_boards + i;
483ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef				devpriv->mite = mite;
484ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef				return 0;
485ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef			}
486ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef		}
487ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	}
488a8c5c198c757c187a904d01b9d74af7d9d91df7fKlaas van Gend	printk(KERN_ERR "comedi 6527: no device found\n");
489ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	mite_list_devices();
490ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef	return -EIO;
491ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef}
492ef2ccffba409c4ab73edd78191b503a2c34b5965David Schleef
493727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __devinit driver_ni6527_pci_probe(struct pci_dev *dev,
494727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas					     const struct pci_device_id *ent)
495727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{
496727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	return comedi_pci_auto_config(dev, driver_ni6527.driver_name);
497727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}
498727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
499727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __devexit driver_ni6527_pci_remove(struct pci_dev *dev)
500727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{
501727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	comedi_pci_auto_unconfig(dev);
502727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}
503727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
504727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic struct pci_driver driver_ni6527_pci_driver = {
505727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	.id_table = ni6527_pci_table,
506727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	.probe = &driver_ni6527_pci_probe,
507727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	.remove = __devexit_p(&driver_ni6527_pci_remove)
508727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas};
509727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
510727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic int __init driver_ni6527_init_module(void)
511727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{
512727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	int retval;
513727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
514727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	retval = comedi_driver_register(&driver_ni6527);
515727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	if (retval < 0)
516727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas		return retval;
517727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
518727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	driver_ni6527_pci_driver.name = (char *)driver_ni6527.driver_name;
519727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	return pci_register_driver(&driver_ni6527_pci_driver);
520727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}
521727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
522727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasstatic void __exit driver_ni6527_cleanup_module(void)
523727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas{
524727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	pci_unregister_driver(&driver_ni6527_pci_driver);
525727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas	comedi_driver_unregister(&driver_ni6527);
526727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas}
527727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomas
528727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_init(driver_ni6527_init_module);
529727b286b44ea359d66f47d241cc2cdad36ed7bdcArun Thomasmodule_exit(driver_ni6527_cleanup_module);
5303c323c01b6bd5fd01be21a8f0cdc11e55997aa06Ian Abbott
5313c323c01b6bd5fd01be21a8f0cdc11e55997aa06Ian AbbottMODULE_AUTHOR("Comedi http://www.comedi.org");
5323c323c01b6bd5fd01be21a8f0cdc11e55997aa06Ian AbbottMODULE_DESCRIPTION("Comedi low-level driver");
5333c323c01b6bd5fd01be21a8f0cdc11e55997aa06Ian AbbottMODULE_LICENSE("GPL");
534