ni_pcidio.c revision 25436dc9d84f1be60ff549c9ab712bba2835f284
1e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/*
2e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    comedi/drivers/ni_pcidio.c
3e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    driver for National Instruments PCI-DIO-96/PCI-6508
4e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef               National Instruments PCI-DIO-32HS
5e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef               National Instruments PCI-6503
6e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
7e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    COMEDI - Linux Control and Measurement Device Interface
8e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
9e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
10e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    This program is free software; you can redistribute it and/or modify
11e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    it under the terms of the GNU General Public License as published by
12e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    the Free Software Foundation; either version 2 of the License, or
13e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    (at your option) any later version.
14e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
15e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    This program is distributed in the hope that it will be useful,
16e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    but WITHOUT ANY WARRANTY; without even the implied warranty of
17e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    GNU General Public License for more details.
19e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
20e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    You should have received a copy of the GNU General Public License
21e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    along with this program; if not, write to the Free Software
22e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
24e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef*/
25e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/*
26e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefDriver: ni_pcidio
27e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefDescription: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503
28e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefAuthor: ds
29e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefStatus: works
30e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefDevices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533,
31e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef  PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,
32e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef  PXI-6503, PCI-6533, PCI-6534
33e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefUpdated: Sun, 21 Apr 2002 21:03:38 -0700
34e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
35e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefThe DIO-96 appears as four 8255 subdevices.  See the 8255
36e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefdriver notes for details.
37e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
38e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefThe DIO32HS board appears as one subdevice, with 32 channels.
39e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefEach channel is individually I/O configurable.  The channel order
40e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefis 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0.  The driver only
41e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefsupports simple digital I/O; no handshaking is supported.
42e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
43e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefDMA mostly works for the PCI-DIO32HS, but only in timed input mode.
44e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
45e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefThis driver could be easily modified to support AT-MIO32HS and
46e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefAT-MIO96.
47e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
48e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefThe PCI-6534 requires a firmware upload after power-up to work, the
49e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleeffirmware data and instructions for loading it with comedi_config
50e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefit are contained in the
51e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefcomedi_nonfree_firmware tarball available from http://www.comedi.org
52e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef*/
53e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
54e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/*
55e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef   This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96,
56e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef   which have very different architectures.  But, since the '96 is
57e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef   so simple, it is included here.
58e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
59e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef   Manuals (available from ftp://ftp.natinst.com/support/manuals)
60e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
61e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	320938c.pdf	PCI-DIO-96/PXI-6508/PCI-6503 User Manual
62e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	321464b.pdf	AT/PCI-DIO-32HS User Manual
63e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	341329A.pdf	PCI-6533 Register-Level Programmer Manual
64e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	341330A.pdf	DAQ-DIO Technical Reference Manual
65e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
66e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef */
67e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
68e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define USE_DMA
6956e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton/* #define DEBUG 1 */
7056e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton/* #define DEBUG_FLAGS */
71e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
7225436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h>
73e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#include "../comedidev.h"
74e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
75e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#include "mite.h"
76e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#include "8255.h"
77e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
78e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#undef DPRINTK
79e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef DEBUG
80e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DPRINTK(format, args...)	printk(format, ## args)
81e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#else
82e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DPRINTK(format, args...)
83e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif
84e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
85e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define PCI_VENDOR_ID_NATINST	0x1093
86e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
87e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define PCI_DIO_SIZE 4096
88e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define PCI_MITE_SIZE 4096
89e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
90e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/* defines for the PCI-DIO-96 */
91e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
92e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_8255_BASE(x)	((x)*4)
93e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_A 0
94e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_B 4
95e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_C 8
96e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define NIDIO_D 12
97e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
98e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/* defines for the PCI-DIO-32HS */
99e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
100e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Window_Address			4	/* W */
101e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Interrupt_And_Window_Status	4	/* R */
102e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IntStatus1				(1<<0)
103e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IntStatus2				(1<<1)
104e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define WindowAddressStatus_mask		0x7c
105e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
106e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Master_DMA_And_Interrupt_Control 5	/* W */
107e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InterruptLine(x)			((x)&3)
108e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define OpenInt				(1<<2)
109e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_Status			5	/* R */
110e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DataLeft				(1<<0)
111e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Req					(1<<2)
112e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define StopTrig				(1<<3)
113e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
114e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_1_Flags			6	/* R */
115e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_2_Flags			7	/* R */
116e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define TransferReady				(1<<0)
117e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define CountExpired				(1<<1)
118e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Waited				(1<<5)
119e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define PrimaryTC				(1<<6)
120e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define SecondaryTC				(1<<7)
12156e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton  /* #define SerialRose */
12256e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton  /* #define ReqRose */
12356e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton  /* #define Paused */
124e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
125e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_1_First_Clear		6	/* W */
126e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_2_First_Clear		7	/* W */
127e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearWaited				(1<<3)
128e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearPrimaryTC			(1<<4)
129e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearSecondaryTC			(1<<5)
130e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DMAReset				(1<<6)
131e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOReset				(1<<7)
132e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearAll				0xf8
133e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
134e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_1_FIFO			8	/* W */
135e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_2_FIFO			12	/* W */
136e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
137e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Transfer_Count			20
138e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Chip_ID_D			24
139e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Chip_ID_I			25
140e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Chip_ID_O			26
141e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Chip_Version			27
142e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_IO(x)			(28+(x))
143e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_Pin_Directions(x)		(32+(x))
144e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_Pin_Mask(x)		(36+(x))
145e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_Pin_Polarities(x)		(40+(x))
146e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
147e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Master_Clock_Routing		45
148e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define RTSIClocking(x)			(((x)&3)<<4)
149e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
150e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_1_Second_Clear		46	/* W */
151e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Group_2_Second_Clear		47	/* W */
152e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClearExpired				(1<<0)
153e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
154e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Port_Pattern(x)			(48+(x))
155e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
156e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Data_Path			64
157e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOEnableA		(1<<0)
158e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOEnableB		(1<<1)
159e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOEnableC		(1<<2)
160e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFOEnableD		(1<<3)
161e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Funneling(x)		(((x)&3)<<4)
162e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define GroupDirection	(1<<7)
163e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
164e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_1		65
165e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define OpMode				Protocol_Register_1
166e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define RunMode(x)		((x)&7)
167e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Numbered		(1<<3)
168e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
169e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_2		66
170e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClockReg			Protocol_Register_2
171e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClockLine(x)		(((x)&3)<<5)
172e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertStopTrig	(1<<7)
173e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DataLatching(x)       (((x)&3)<<5)
174e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
175e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_3		67
176e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Sequence			Protocol_Register_3
177e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
178e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_14		68	/* 16 bit */
179e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ClockSpeed			Protocol_Register_14
180e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
181e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_4		70
182e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqReg				Protocol_Register_4
183e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqConditioning(x)	(((x)&7)<<3)
184e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
185e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_5		71
186e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define BlockMode			Protocol_Register_5
187e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
188e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define FIFO_Control			72
189e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReadyLevel(x)		((x)&7)
190e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
191e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_6		73
192e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define LinePolarities			Protocol_Register_6
193e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertAck		(1<<0)
194e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertReq		(1<<1)
195e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertClock		(1<<2)
196e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertSerial		(1<<3)
197e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define OpenAck		(1<<4)
198e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define OpenClock		(1<<5)
199e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
200e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_7		74
201e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define AckSer				Protocol_Register_7
202e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define AckLine(x)		(((x)&3)<<2)
203e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ExchangePins		(1<<7)
204e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
205e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Interrupt_Control		75
206e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef  /* bits same as flags */
207e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
208e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DMA_Line_Control_Group1		76
209e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DMA_Line_Control_Group2		108
21056e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton/* channel zero is none */
211e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic inline unsigned primary_DMAChannel_bits(unsigned channel)
212e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
213e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return channel & 0x3;
214e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
215e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic inline unsigned secondary_DMAChannel_bits(unsigned channel)
216e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
217e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return (channel << 2) & 0xc;
218e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
219e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
220e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Transfer_Size_Control		77
221e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define TransferWidth(x)	((x)&3)
222e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define TransferLength(x)	(((x)&3)<<3)
223e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define RequireRLevel		(1<<5)
224e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
225e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_15		79
226e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DAQOptions			Protocol_Register_15
227e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define StartSource(x)			((x)&0x3)
228e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertStart				(1<<2)
229e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define StopSource(x)				(((x)&0x3)<<3)
230e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqStart				(1<<6)
231e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define PreStart				(1<<7)
232e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
233e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Pattern_Detection		81
234e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define DetectionMethod			(1<<0)
235e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define InvertMatch				(1<<1)
236e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IE_Pattern_Detection			(1<<2)
237e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
238e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_9		82
239e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqDelay			Protocol_Register_9
240e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
241e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_10		83
242e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ReqNotDelay			Protocol_Register_10
243e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
244e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_11		84
245e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define AckDelay			Protocol_Register_11
246e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
247e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_12		85
248e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define AckNotDelay			Protocol_Register_12
249e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
250e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_13		86
251e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Data1Delay			Protocol_Register_13
252e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
253e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define Protocol_Register_8		88	/* 32 bit */
254e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define StartDelay			Protocol_Register_8
255e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
256e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefenum pci_6534_firmware_registers {	/* 16 bit */
257e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	Firmware_Control_Register = 0x100,
258e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	Firmware_Status_Register = 0x104,
259e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	Firmware_Data_Register = 0x108,
260e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	Firmware_Mask_Register = 0x10c,
261e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	Firmware_Debug_Register = 0x110,
262e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef};
263e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef/* main fpga registers (32 bit)*/
264e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefenum pci_6534_fpga_registers {
265e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_Control1_Register = 0x200,
266e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_Control2_Register = 0x204,
267e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_Irq_Mask_Register = 0x208,
268e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_Status_Register = 0x20c,
269e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_Signature_Register = 0x210,
270e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_SCALS_Counter_Register = 0x280,	/*write-clear */
271e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_SCAMS_Counter_Register = 0x284,	/*write-clear */
272e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_SCBLS_Counter_Register = 0x288,	/*write-clear */
273e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_SCBMS_Counter_Register = 0x28c,	/*write-clear */
274e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_Temp_Control_Register = 0x2a0,
275e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_DAR_Register = 0x2a8,
276e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_ELC_Read_Register = 0x2b8,
277e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_ELC_Write_Register = 0x2bc,
278e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef};
279e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefenum FPGA_Control_Bits {
280e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	FPGA_Enable_Bit = 0x8000,
281e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef};
282e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
283e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define TIMER_BASE 50		/* nanoseconds */
284e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
285e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef USE_DMA
286e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
287e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#else
288e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
289e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif
290e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
291da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it);
292da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int nidio_detach(struct comedi_device *dev);
293da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_pcidio_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
294e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
295139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_pcidio = {
29668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.driver_name = "ni_pcidio",
29768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.module = THIS_MODULE,
29868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.attach = nidio_attach,
29968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.detach = nidio_detach,
300e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef};
301e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
302a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pembertonstruct nidio_board {
303a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pemberton
304e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int dev_id;
305e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	const char *name;
306e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int n_8255;
307e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned int is_diodaq:1;
308e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned int uses_firmware:1;
309a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pemberton};
310a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pemberton
311a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pembertonstatic const struct nidio_board nidio_boards[] = {
312e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
31368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x1150,
31468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pci-dio-32hs",
31568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 0,
31668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 1,
317e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
318e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
31968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x1320,
32068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pxi-6533",
32168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 0,
32268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 1,
323e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
324e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
32568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x12b0,
32668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pci-6534",
32768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 0,
32868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 1,
32968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.uses_firmware = 1,
330e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
331e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
33268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x0160,
33368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pci-dio-96",
33468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 4,
33568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 0,
336e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
337e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
33868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x1630,
33968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pci-dio-96b",
34068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 4,
34168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 0,
342e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
343e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
34468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x13c0,
34568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pxi-6508",
34668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 4,
34768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 0,
348e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
349e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
35068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x0400,
35168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pci-6503",
35268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 1,
35368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 0,
354e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
355e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
35668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x1250,
35768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pci-6503b",
35868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 1,
35968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 0,
360e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
361e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
36268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x17d0,
36368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pci-6503x",
36468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 1,
36568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 0,
366e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
367e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
36868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.dev_id = 0x1800,
36968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.name = "pxi-6503",
37068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.n_8255 = 1,
37168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.is_diodaq = 0,
372e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		},
373e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef};
374e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
375e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define n_nidio_boards (sizeof(nidio_boards)/sizeof(nidio_boards[0]))
376a7195f3d92f5fc560e597598a56d9c394b65ee81Bill Pemberton#define this_board ((const struct nidio_board *)dev->board_ptr)
377e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
378e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
379e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x1150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
380e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x1320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
381e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x12b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
382e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x0160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
383e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x1630, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
384e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x13c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
385e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x0400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
386e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x1250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
387e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x17d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
388e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{PCI_VENDOR_ID_NATINST, 0x1800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
389e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{0}
390e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef};
391e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
392e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefMODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
393e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
3942e93aa5b5b8050090a22e162f9af6b18ca3ec47aBill Pembertonstruct nidio96_private {
395e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	struct mite_struct *mite;
396e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int boardtype;
397e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int dio;
398e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned short OpModeBits;
399e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	struct mite_channel *di_mite_chan;
400e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	struct mite_dma_descriptor_ring *di_mite_ring;
401e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	spinlock_t mite_channel_lock;
4022e93aa5b5b8050090a22e162f9af6b18ca3ec47aBill Pemberton};
4032e93aa5b5b8050090a22e162f9af6b18ca3ec47aBill Pemberton#define devpriv ((struct nidio96_private *)dev->private)
404e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
405da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_pcidio_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
406da91b2692e0939b307f9047192d2b9fe07793e7aBill Pemberton	struct comedi_cmd *cmd);
407da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
408da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_pcidio_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
409e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned int trignum);
410da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int nidio_find_device(struct comedi_device *dev, int bus, int slot);
411e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
412da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s);
413e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
414e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef DEBUG_FLAGS
415e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic void ni_pcidio_print_flags(unsigned int flags);
416e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic void ni_pcidio_print_status(unsigned int status);
417e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#else
418e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ni_pcidio_print_flags(x)
419e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define ni_pcidio_print_status(x)
420e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif
421e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
422da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
423e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
424e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned long flags;
425e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
4265f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
427e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	BUG_ON(devpriv->di_mite_chan);
428e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	devpriv->di_mite_chan =
429e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		mite_request_channel_in_range(devpriv->mite,
430e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->di_mite_ring, 1, 2);
431e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (devpriv->di_mite_chan == NULL) {
4325f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
433e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		comedi_error(dev, "failed to reserve mite dma channel.");
434e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return -EBUSY;
435e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
436e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
437e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
438e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
439e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	mmiowb();
4405f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
441e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
442e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
443e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
444da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
445e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
446e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned long flags;
447e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
4485f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
449e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (devpriv->di_mite_chan) {
450e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		mite_dma_disarm(devpriv->di_mite_chan);
451e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		mite_dma_reset(devpriv->di_mite_chan);
452e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		mite_release_channel(devpriv->di_mite_chan);
453e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->di_mite_chan = NULL;
454e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(primary_DMAChannel_bits(0) |
455e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			secondary_DMAChannel_bits(0),
456e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
457e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		mmiowb();
458e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
4595f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
460e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
461e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
462e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase)
463e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
464e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (dir) {
465e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(data, (void *)(iobase + port));
466e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return 0;
467e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	} else {
468e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return readb((void *)(iobase + port));
469e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
470e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
471e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
472da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonvoid ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s)
473e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
474e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (s->async->
475e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
476e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
477e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		ni_pcidio_cancel(dev, s);
478e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
479e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	comedi_event(dev, s);
480e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
481e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
48270265d24e3404fe798b6edd55a02016b1edb49d7Jiri Slabystatic irqreturn_t nidio_interrupt(int irq, void *d)
483e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
48471b5f4f11971dea972832ad63a994c7e5b45db6bBill Pemberton	struct comedi_device *dev = d;
48534c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s = dev->subdevices;
486d163679ceec20c50f9aee880fa76c0c1185244a8Bill Pemberton	struct comedi_async *async = s->async;
487e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	struct mite_struct *mite = devpriv->mite;
488e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
48956e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton	/* int i, j; */
490e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	long int AuxData = 0;
491790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	short data1 = 0;
492790c55415aa31f4c732729f94d2c3a54f7d3bfc2Bill Pemberton	short data2 = 0;
493e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int flags;
494e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int status;
495e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int work = 0;
496e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned int m_status = 0;
497e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned long irq_flags;
498e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
49956e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton	/* interrupcions parasites */
500e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (dev->attached == 0) {
50156e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton		/* assume it's from another card */
502e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return IRQ_NONE;
503e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
504e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
505e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	status = readb(devpriv->mite->daq_io_addr +
506e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		Interrupt_And_Window_Status);
507e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
508e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
509e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
510e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		status, flags);
511e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ni_pcidio_print_flags(flags);
512e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ni_pcidio_print_status(status);
513e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
51456e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton	/* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */
51556e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton	/* printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096)); */
516e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
5175f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
518e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (devpriv->di_mite_chan)
519e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		m_status = mite_get_status(devpriv->di_mite_chan);
520e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef MITE_DEBUG
521e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	mite_print_chsr(m_status);
522e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif
52356e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton	/* printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN)); */
52456e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton	/* mite_dump_regs(mite); */
525e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (m_status & CHSR_INT) {
526e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (m_status & CHSR_LINKC) {
527e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			writel(CHOR_CLRLC,
528e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				mite->mite_io_addr +
529e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				MITE_CHOR(devpriv->di_mite_chan->channel));
530e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			mite_sync_input_dma(devpriv->di_mite_chan, s->async);
531e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			/* XXX need to byteswap */
532e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
533e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
534e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				CHSR_DRQ1 | CHSR_MRDY)) {
535e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			DPRINTK("unknown mite interrupt, disabling IRQ\n");
536e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
537e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			disable_irq(dev->irq);
538e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
539e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
5405f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
541e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
542e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	while (status & DataLeft) {
543e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		work++;
544e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (work > 20) {
545e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			DPRINTK("too much work in interrupt\n");
546e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			writeb(0x00,
547e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				devpriv->mite->daq_io_addr +
548e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				Master_DMA_And_Interrupt_Control);
549e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			break;
550e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
551e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
552e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		flags &= IntEn;
553e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
554e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (flags & TransferReady) {
55556e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton			/* DPRINTK("TransferReady\n"); */
556e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			while (flags & TransferReady) {
557e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				work++;
558e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				if (work > 100) {
559e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef					DPRINTK("too much work in interrupt\n");
560e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef					writeb(0x00,
561e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef						devpriv->mite->daq_io_addr +
562e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef						Master_DMA_And_Interrupt_Control);
563e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef					goto out;
564e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				}
565e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				AuxData =
566e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef					readl(devpriv->mite->daq_io_addr +
567e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef					Group_1_FIFO);
568e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				data1 = AuxData & 0xffff;
569e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				data2 = (AuxData & 0xffff0000) >> 16;
570e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				comedi_buf_put(async, data1);
571e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				comedi_buf_put(async, data2);
57256e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton				/* DPRINTK("read:%d, %d\n",data1,data2); */
573e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				flags = readb(devpriv->mite->daq_io_addr +
574e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef					Group_1_Flags);
575e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			}
57656e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton			/* DPRINTK("buf_int_count: %d\n",async->buf_int_count); */
57756e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton			/* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status); */
57856e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton			/* ni_pcidio_print_flags(flags); */
57956e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton			/* ni_pcidio_print_status(status); */
580e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			async->events |= COMEDI_CB_BLOCK;
581e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
582e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
583e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (flags & CountExpired) {
584e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			DPRINTK("CountExpired\n");
585e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			writeb(ClearExpired,
586e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				devpriv->mite->daq_io_addr +
587e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				Group_1_Second_Clear);
588e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			async->events |= COMEDI_CB_EOA;
589e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
590e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
591e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			break;
592e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		} else if (flags & Waited) {
593e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			DPRINTK("Waited\n");
594e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			writeb(ClearWaited,
595e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				devpriv->mite->daq_io_addr +
596e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				Group_1_First_Clear);
597e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
598e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			break;
599e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		} else if (flags & PrimaryTC) {
600e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			DPRINTK("PrimaryTC\n");
601e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			writeb(ClearPrimaryTC,
602e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				devpriv->mite->daq_io_addr +
603e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				Group_1_First_Clear);
604e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			async->events |= COMEDI_CB_EOA;
605e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		} else if (flags & SecondaryTC) {
606e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			DPRINTK("SecondaryTC\n");
607e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			writeb(ClearSecondaryTC,
608e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				devpriv->mite->daq_io_addr +
609e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				Group_1_First_Clear);
610e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			async->events |= COMEDI_CB_EOA;
611e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
612e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#if 0
613e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		else {
614e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			printk("ni_pcidio: unknown interrupt\n");
615e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
616e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			writeb(0x00,
617e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				devpriv->mite->daq_io_addr +
618e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				Master_DMA_And_Interrupt_Control);
619e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
620e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif
621e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
622e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		status = readb(devpriv->mite->daq_io_addr +
623e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			Interrupt_And_Window_Status);
62456e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton		/* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n", */
62556e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton		/* IntEn,flags,status); */
62656e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton		/* ni_pcidio_print_flags(flags); */
62756e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton		/* ni_pcidio_print_status(status); */
628e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
629e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
630e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef      out:
631e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ni_pcidio_event(dev, s);
632e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#if 0
633e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (!tag) {
634e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x03,
635e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->mite->daq_io_addr +
636e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			Master_DMA_And_Interrupt_Control);
637e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
638e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif
639e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return IRQ_HANDLED;
640e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
641e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
642e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef DEBUG_FLAGS
643e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic const char *const flags_strings[] = {
644e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	"TransferReady", "CountExpired", "2", "3",
645e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	"4", "Waited", "PrimaryTC", "SecondaryTC",
646e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef};
647e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic void ni_pcidio_print_flags(unsigned int flags)
648e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
649e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int i;
650e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
651e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	printk("group_1_flags:");
652e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	for (i = 7; i >= 0; i--) {
653e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (flags & (1 << i)) {
654e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			printk(" %s", flags_strings[i]);
655e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
656e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
657e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	printk("\n");
658e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
659e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic char *status_strings[] = {
660e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	"DataLeft1", "Reserved1", "Req1", "StopTrig1",
661e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	"DataLeft2", "Reserved2", "Req2", "StopTrig2",
662e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef};
663e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic void ni_pcidio_print_status(unsigned int flags)
664e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
665e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int i;
666e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
667e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	printk("group_status:");
668e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	for (i = 7; i >= 0; i--) {
669e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (flags & (1 << i)) {
670e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			printk(" %s", status_strings[i]);
671e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
672e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
673e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	printk("\n");
674e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
675e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif
676e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
677e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef unused
67871b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic void debug_int(struct comedi_device * dev)
679e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
680e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int a, b;
681e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	static int n_int = 0;
682e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	struct timeval tv;
683e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
684e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	do_gettimeofday(&tv);
685e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	a = readb(devpriv->mite->daq_io_addr + Group_Status);
686e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
687e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
688e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (n_int < 10) {
689e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
690e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			(int)tv.tv_usec);
691e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
692e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
693e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	while (b & 1) {
694e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
695e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
696e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
697e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
698e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
699e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
700e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (n_int < 10) {
701e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		DPRINTK("new status 0x%02x\n", b);
702e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		n_int++;
703e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
704e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
705e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif
706e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
70734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int ni_pcidio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
70890035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton	struct comedi_insn * insn, unsigned int * data)
709e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
710e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (insn->n != 1)
711e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return -EINVAL;
712e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	switch (data[0]) {
713e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	case INSN_CONFIG_DIO_OUTPUT:
714e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->io_bits |= 1 << CR_CHAN(insn->chanspec);
715e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		break;
716e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	case INSN_CONFIG_DIO_INPUT:
717e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
718e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		break;
719e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	case INSN_CONFIG_DIO_QUERY:
720e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		data[1] =
721e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			(s->io_bits & (1 << CR_CHAN(insn->
722e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef					chanspec))) ? COMEDI_OUTPUT :
723e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			COMEDI_INPUT;
724e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return insn->n;
725e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		break;
726e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	default:
727e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return -EINVAL;
728e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
729e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
730e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
731e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 1;
732e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
733e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
73434c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int ni_pcidio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
73590035c0886b256d75bced13b3b3cea5234aff136Bill Pemberton	struct comedi_insn * insn, unsigned int * data)
736e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
737e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (insn->n != 2)
738e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return -EINVAL;
739e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (data[0]) {
740e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->state &= ~data[0];
741e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->state |= (data[0] & data[1]);
742e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
743e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
744e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
745e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
746e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 2;
747e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
748e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
74934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
750ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton	struct comedi_cmd * cmd)
751e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
752e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int err = 0;
753e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int tmp;
754e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
755e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	/* step 1: make sure trigger sources are trivially valid */
756e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
757e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	tmp = cmd->start_src;
758e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	cmd->start_src &= TRIG_NOW | TRIG_INT;
759e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (!cmd->start_src || tmp != cmd->start_src)
760e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
761e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
762e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	tmp = cmd->scan_begin_src;
763e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
764e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
765e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
766e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
767e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	tmp = cmd->convert_src;
768e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	cmd->convert_src &= TRIG_NOW;
769e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (!cmd->convert_src || tmp != cmd->convert_src)
770e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
771e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
772e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	tmp = cmd->scan_end_src;
773e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	cmd->scan_end_src &= TRIG_COUNT;
774e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
775e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
776e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
777e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	tmp = cmd->stop_src;
778e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
779e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (!cmd->stop_src || tmp != cmd->stop_src)
780e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
781e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
782e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (err)
783e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return 1;
784e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
785e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	/* step 2: make sure trigger sources are unique and mutually compatible */
786e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
787e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	/* note that mutual compatiblity is not an issue here */
788e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
789e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
790e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->scan_begin_src != TRIG_TIMER &&
791e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		cmd->scan_begin_src != TRIG_EXT)
792e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
793e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
794e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (err)
795e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return 2;
796e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
797e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	/* step 3: make sure arguments are trivially compatible */
798e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
799e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->start_arg != 0) {
800e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* same for both TRIG_INT and TRIG_NOW */
801e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		cmd->start_arg = 0;
802e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
803e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
804e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#define MAX_SPEED	(TIMER_BASE)	/* in nanoseconds */
805e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
806e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->scan_begin_src == TRIG_TIMER) {
807e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (cmd->scan_begin_arg < MAX_SPEED) {
808e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			cmd->scan_begin_arg = MAX_SPEED;
809e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			err++;
810e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
811e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* no minumum speed */
812e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	} else {
813e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* TRIG_EXT */
814e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* should be level/edge, hi/lo specification here */
815e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (cmd->scan_begin_arg != 0) {
816e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			cmd->scan_begin_arg = 0;
817e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			err++;
818e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
819e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
820e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->convert_arg != 0) {
821e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		cmd->convert_arg = 0;
822e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
823e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
824e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
825e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->scan_end_arg != cmd->chanlist_len) {
826e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		cmd->scan_end_arg = cmd->chanlist_len;
827e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		err++;
828e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
829e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->stop_src == TRIG_COUNT) {
830e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* no limit */
831e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	} else {
832e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* TRIG_NONE */
833e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (cmd->stop_arg != 0) {
834e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			cmd->stop_arg = 0;
835e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			err++;
836e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
837e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
838e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
839e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (err)
840e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return 3;
841e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
842e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	/* step 4: fix up any arguments */
843e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
844e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->scan_begin_src == TRIG_TIMER) {
845e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		tmp = cmd->scan_begin_arg;
846e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
847e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			cmd->flags & TRIG_ROUND_MASK);
848e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (tmp != cmd->scan_begin_arg)
849e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			err++;
850e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
851e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
852e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (err)
853e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return 4;
854e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
855e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
856e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
857e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
858e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleefstatic int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
859e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
860e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int divider, base;
861e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
862e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	base = TIMER_BASE;
863e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
864e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	switch (round_mode) {
865e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	case TRIG_ROUND_NEAREST:
866e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	default:
867e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		divider = (*nanosec + base / 2) / base;
868e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		break;
869e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	case TRIG_ROUND_DOWN:
870e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		divider = (*nanosec) / base;
871e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		break;
872e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	case TRIG_ROUND_UP:
873e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		divider = (*nanosec + base - 1) / base;
874e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		break;
875e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
876e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
877e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	*nanosec = base * divider;
878e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return divider;
879e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
880e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
88134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
882e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
883ea6d0d4cab4f4f2d6a88f3bce4707fe92696fd3fBill Pemberton	struct comedi_cmd *cmd = &s->async->cmd;
884e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
885e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	/* XXX configure ports for input */
886e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
887e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
888e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (1) {
889e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* enable fifos A B C D */
890e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
891e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
892e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* set transfer width a 32 bits */
893e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(TransferWidth(0) | TransferLength(0),
894e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->mite->daq_io_addr + Transfer_Size_Control);
895e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	} else {
896e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
897e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(TransferWidth(3) | TransferLength(0),
898e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->mite->daq_io_addr + Transfer_Size_Control);
899e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
900e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
901e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	/* protocol configuration */
902e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->scan_begin_src == TRIG_TIMER) {
903e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* page 4-5, "input with internal REQs" */
904e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0, devpriv->mite->daq_io_addr + OpMode);
905e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
906e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(1, devpriv->mite->daq_io_addr + Sequence);
907e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
908e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
909e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
910e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
911e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
912e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				TRIG_ROUND_NEAREST),
913e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->mite->daq_io_addr + StartDelay);
914e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
915e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
916e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
917e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
918e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
919e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* manual, page 4-5: ClockSpeed comment is incorrectly listed
920e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		 * on DAQOptions */
921e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
922e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
923e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	} else {
924e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* TRIG_EXT */
925e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* page 4-5, "input with external REQs" */
926e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0, devpriv->mite->daq_io_addr + OpMode);
927e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
928e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0, devpriv->mite->daq_io_addr + Sequence);
929e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
930e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(4, devpriv->mite->daq_io_addr + BlockMode);
931e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
932e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
933e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writel(1, devpriv->mite->daq_io_addr + StartDelay);
934e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
935e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
936e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(1, devpriv->mite->daq_io_addr + AckDelay);
937e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
938e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
939e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
940e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
941e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
942e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
943e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->stop_src == TRIG_COUNT) {
944e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writel(cmd->stop_arg,
945e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->mite->daq_io_addr + Transfer_Count);
946e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	} else {
947e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* XXX */
948e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
949e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
950e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#ifdef USE_DMA
951e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writeb(ClearPrimaryTC | ClearSecondaryTC,
952e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->mite->daq_io_addr + Group_1_First_Clear);
953e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
954e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	{
955e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		int retval = setup_mite_dma(dev, s);
956e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (retval)
957e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			return retval;
958e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
959e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#else
960e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
961e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef#endif
962e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
963e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
964e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	/* clear and enable interrupts */
965e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
96656e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton	/* writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
967e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
968e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
969e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writeb(0x03,
970e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
971e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
972e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->stop_src == TRIG_NONE) {
973e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->OpModeBits = DataLatching(0) | RunMode(7);
97456e9e16619a0c14dc948cf88b3a7aaa70ac92b45Bill Pemberton	} else {		/* TRIG_TIMER */
975e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->OpModeBits = Numbered | RunMode(7);
976e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
977e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (cmd->start_src == TRIG_NOW) {
978e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* start */
979e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(devpriv->OpModeBits,
980e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->mite->daq_io_addr + OpMode);
981e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->async->inttrig = NULL;
982e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	} else {
983e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* TRIG_INT */
984e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->async->inttrig = ni_pcidio_inttrig;
985e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
986e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
987e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	DPRINTK("ni_pcidio: command started\n");
988e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
989e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
990e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
99134c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s)
992e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
993e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int retval;
994e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
995e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	retval = ni_pcidio_request_di_mite_channel(dev);
996e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (retval)
997e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return retval;
998e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
999e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	devpriv->di_mite_chan->dir = COMEDI_INPUT;
1000e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1001e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	mite_prep_dma(devpriv->di_mite_chan, 32, 32);
1002e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1003e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	mite_dma_arm(devpriv->di_mite_chan);
1004e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
1005e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1006e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
100734c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
1008e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned int trignum)
1009e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1010e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (trignum != 0)
1011e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return -EINVAL;
1012e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1013e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
1014e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	s->async->inttrig = NULL;
1015e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1016e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 1;
1017e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1018e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
101934c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
1020e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1021e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writeb(0x00,
1022e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
1023e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ni_pcidio_release_di_mite_channel(dev);
1024e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1025e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
1026e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1027e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
102834c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pembertonstatic int ni_pcidio_change(struct comedi_device * dev, struct comedi_subdevice * s,
1029e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned long new_size)
1030e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1031e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int ret;
1032e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1033e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ret = mite_buf_change(devpriv->di_mite_ring, s->async);
1034e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (ret < 0)
1035e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return ret;
1036e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1037e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
1038e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1039e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
1040e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1041e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
104271b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int pci_6534_load_fpga(struct comedi_device * dev, int fpga_index, u8 * data,
1043e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int data_len)
1044e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1045e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	static const int timeout = 1000;
1046e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int i, j;
1047e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writew(0x80 | fpga_index,
1048e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->mite->daq_io_addr + Firmware_Control_Register);
1049e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writew(0xc0 | fpga_index,
1050e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->mite->daq_io_addr + Firmware_Control_Register);
1051e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	for (i = 0;
1052e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		(readw(devpriv->mite->daq_io_addr +
1053e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				Firmware_Status_Register) & 0x2) == 0
1054e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		&& i < timeout; ++i) {
1055e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		udelay(1);
1056e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1057e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (i == timeout) {
1058e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		printk("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n", fpga_index);
1059e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return -EIO;
1060e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1061e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writew(0x80 | fpga_index,
1062e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		devpriv->mite->daq_io_addr + Firmware_Control_Register);
1063e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	for (i = 0;
1064e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
1065e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		0x3 && i < timeout; ++i) {
1066e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		udelay(1);
1067e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1068e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (i == timeout) {
1069e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		printk("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n", fpga_index);
1070e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return -EIO;
1071e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1072e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	for (j = 0; j + 1 < data_len;) {
1073e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		unsigned int value = data[j++];
1074e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		value |= data[j++] << 8;
1075e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writew(value,
1076e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->mite->daq_io_addr + Firmware_Data_Register);
1077e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		for (i = 0;
1078e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			(readw(devpriv->mite->daq_io_addr +
1079e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef					Firmware_Status_Register) & 0x2) == 0
1080e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			&& i < timeout; ++i) {
1081e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			udelay(1);
1082e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
1083e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (i == timeout) {
1084e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			printk("ni_pcidio: failed to load word into fpga %i\n",
1085e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				fpga_index);
1086e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			return -EIO;
1087e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
1088e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (need_resched())
1089e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			schedule();
1090e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1091e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1092e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
1093e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1094e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
109571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int pci_6534_reset_fpga(struct comedi_device * dev, int fpga_index)
1096e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1097e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
1098e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1099e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
110071b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int pci_6534_reset_fpgas(struct comedi_device * dev)
1101e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1102e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int ret;
1103e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int i;
1104e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1105e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	for (i = 0; i < 3; ++i) {
1106e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		ret = pci_6534_reset_fpga(dev, i);
1107e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (ret < 0)
1108e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			break;
1109e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1110e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
1111e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return ret;
1112e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1113e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
111471b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic void pci_6534_init_main_fpga(struct comedi_device * dev)
1115e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1116e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
1117e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
1118e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
1119e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
1120e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
1121e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
1122e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1123e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
112471b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int pci_6534_upload_firmware(struct comedi_device * dev, int options[])
1125e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1126e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int ret;
1127e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	void *main_fpga_data, *scarab_a_data, *scarab_b_data;
1128e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len;
1129e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1130e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0)
1131e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return 0;
1132e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ret = pci_6534_reset_fpgas(dev);
1133e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (ret < 0)
1134e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return ret;
1135e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	main_fpga_data = comedi_aux_data(options, 0);
1136e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
1137e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len);
1138e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (ret < 0)
1139e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return ret;
1140e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	pci_6534_init_main_fpga(dev);
1141e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	scarab_a_data = comedi_aux_data(options, 1);
1142e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
1143e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len);
1144e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (ret < 0)
1145e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return ret;
1146e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	scarab_b_data = comedi_aux_data(options, 2);
1147e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
1148e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len);
1149e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (ret < 0)
1150e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return ret;
1151e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
1152e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1153e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
11540707bb04be89b18ee83b5a997e36cc585f0b988dBill Pembertonstatic int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
1155e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
115634c43922e62708d45e9660eee4b4f1fb7b4bf2c7Bill Pemberton	struct comedi_subdevice *s;
1157e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int i;
1158e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int ret;
1159e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int n_subdevices;
1160e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	unsigned int irq;
1161e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1162e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	printk("comedi%d: nidio:", dev->minor);
1163e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
11642e93aa5b5b8050090a22e162f9af6b18ca3ec47aBill Pemberton	if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0)
1165e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return ret;
1166e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	spin_lock_init(&devpriv->mite_channel_lock);
1167e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1168e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ret = nidio_find_device(dev, it->options[0], it->options[1]);
1169e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (ret < 0)
1170e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return ret;
1171e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1172e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	ret = mite_setup(devpriv->mite);
1173e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (ret < 0) {
1174e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		printk("error setting up mite\n");
1175e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return ret;
1176e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1177e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
1178e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
1179e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (devpriv->di_mite_ring == NULL)
1180e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return -ENOMEM;
1181e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1182e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	dev->board_name = this_board->name;
1183e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	irq = mite_irq(devpriv->mite);
1184e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	printk(" %s", dev->board_name);
1185e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (this_board->uses_firmware) {
1186e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		ret = pci_6534_upload_firmware(dev, it->options);
1187e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (ret < 0)
1188e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			return ret;
1189e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1190e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (!this_board->is_diodaq) {
1191e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		n_subdevices = this_board->n_8255;
1192e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	} else {
1193e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		n_subdevices = 1;
1194e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1195e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
1196e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		return ret;
1197e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1198e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (!this_board->is_diodaq) {
1199e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		for (i = 0; i < this_board->n_8255; i++) {
1200e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			subdev_8255_init(dev, dev->subdevices + i,
1201e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				nidio96_8255_cb,
1202e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				(unsigned long)(devpriv->mite->daq_io_addr +
1203e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef					NIDIO_8255_BASE(i)));
1204e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
1205e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	} else {
1206e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1207e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		printk(" rev=%d",
1208e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			readb(devpriv->mite->daq_io_addr + Chip_Version));
1209e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1210e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s = dev->subdevices + 0;
1211e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1212e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		dev->read_subdev = s;
1213e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->type = COMEDI_SUBD_DIO;
1214e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->subdev_flags =
1215e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
1216e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			SDF_CMD_READ;
1217e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->n_chan = 32;
1218e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->range_table = &range_digital;
1219e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->maxdata = 1;
1220e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->insn_config = &ni_pcidio_insn_config;
1221e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->insn_bits = &ni_pcidio_insn_bits;
1222e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->do_cmd = &ni_pcidio_cmd;
1223e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->do_cmdtest = &ni_pcidio_cmdtest;
1224e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->cancel = &ni_pcidio_cancel;
1225e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->len_chanlist = 32;	/* XXX */
1226e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->buf_change = &ni_pcidio_change;
1227e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		s->async_dma_dir = DMA_BIDIRECTIONAL;
1228e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1229e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
1230e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
1231e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));
1232e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1233e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		/* disable interrupts on board */
1234e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		writeb(0x00,
1235e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->mite->daq_io_addr +
1236e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			Master_DMA_And_Interrupt_Control);
1237e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
12385f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
12395f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				  "ni_pcidio", dev);
1240e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (ret < 0) {
1241e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			printk(" irq not available");
1242e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
1243e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		dev->irq = irq;
1244e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1245e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1246e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	printk("\n");
1247e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1248e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
1249e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1250e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
125171b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int nidio_detach(struct comedi_device * dev)
1252e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1253e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int i;
1254e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1255e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (this_board && !this_board->is_diodaq) {
1256e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		for (i = 0; i < this_board->n_8255; i++) {
1257e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			subdev_8255_cleanup(dev, dev->subdevices + i);
1258e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
1259e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1260e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1261e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (dev->irq)
12625f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		free_irq(dev->irq, dev);
1263e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1264e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	if (devpriv) {
1265e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (devpriv->di_mite_ring) {
1266e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			mite_free_ring(devpriv->di_mite_ring);
1267e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			devpriv->di_mite_ring = NULL;
1268e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
1269e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (devpriv->mite)
1270e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			mite_unsetup(devpriv->mite);
1271e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1272e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return 0;
1273e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1274e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
127571b5f4f11971dea972832ad63a994c7e5b45db6bBill Pembertonstatic int nidio_find_device(struct comedi_device * dev, int bus, int slot)
1276e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef{
1277e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	struct mite_struct *mite;
1278e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	int i;
1279e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1280e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	for (mite = mite_devices; mite; mite = mite->next) {
1281e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (mite->used)
1282e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			continue;
1283e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		if (bus || slot) {
1284e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			if (bus != mite->pcidev->bus->number ||
1285e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				slot != PCI_SLOT(mite->pcidev->devfn))
1286e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				continue;
1287e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
1288e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		for (i = 0; i < n_nidio_boards; i++) {
1289e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			if (mite_device_id(mite) == nidio_boards[i].dev_id) {
1290e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				dev->board_ptr = nidio_boards + i;
1291e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				devpriv->mite = mite;
1292e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1293e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef				return 0;
1294e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef			}
1295e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef		}
1296e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	}
1297e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	printk("no device found\n");
1298e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	mite_list_devices();
1299e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef	return -EIO;
1300e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef}
1301e20903165f0f11827657e0c5d3bfbfdaed13207bDavid Schleef
1302e20903165f0f11827657e0c5d3bfbfdaed13207bDavid SchleefCOMEDI_PCI_INITCLEANUP(driver_pcidio, ni_pcidio_pci_table);
1303