1a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/*
2a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    comedi/drivers/ni_atmio.c
3a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    Hardware driver for NI AT-MIO E series cards
4a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
5a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    COMEDI - Linux Control and Measurement Device Interface
6a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
7a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
8a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    This program is free software; you can redistribute it and/or modify
9a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    it under the terms of the GNU General Public License as published by
10a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    the Free Software Foundation; either version 2 of the License, or
11a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    (at your option) any later version.
12a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
13a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    This program is distributed in the hope that it will be useful,
14a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    but WITHOUT ANY WARRANTY; without even the implied warranty of
15a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    GNU General Public License for more details.
17a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
18a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    You should have received a copy of the GNU General Public License
19a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    along with this program; if not, write to the Free Software
20a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef*/
22a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/*
23a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefDriver: ni_atmio
24a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefDescription: National Instruments AT-MIO-E series
25a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefAuthor: ds
26a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefDevices: [National Instruments] AT-MIO-16E-1 (ni_atmio),
27a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef  AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
28a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef  AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
29a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefStatus: works
30a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefUpdated: Thu May  1 20:03:02 CDT 2003
31a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
32a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefThe driver has 2.6 kernel isapnp support, and
33a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefwill automatically probe for a supported board if the
34a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefI/O base is left unspecified with comedi_config.
35a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefHowever, many of
36a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefthe isapnp id numbers are unknown.  If your board is not
37a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefrecognized, please send the output of 'cat /proc/isapnp'
38a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef(you may need to modprobe the isa-pnp module for
39a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/proc/isapnp to exist) so the
40a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefid numbers for your board can be added to the driver.
41a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
42a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefOtherwise, you can use the isapnptools package to configure
43a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefyour board.  Use isapnp to
44a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefconfigure the I/O base and IRQ for the board, and then pass
45a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefthe same values as
46a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefparameters in comedi_config.  A sample isapnp.conf file is included
47a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefin the etc/ directory of Comedilib.
48a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
49a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefComedilib includes a utility to autocalibrate these boards.  The
50a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefboards seem to boot into a state where the all calibration DACs
51a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefare at one extreme of their range, thus the default calibration
52a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefis terrible.  Calibration at boot is strongly encouraged.
53a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
54a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefTo use the extended digital I/O on some of the boards, enable the
55a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef8255 driver when configuring the Comedi source tree.
56a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
57a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefExternal triggering is supported for some events.  The channel index
58a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef(scan_begin_arg, etc.) maps to PFI0 - PFI9.
59a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
60a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefSome of the more esoteric triggering possibilities of these boards
61a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefare not supported.
62a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef*/
63a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/*
64a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	The real guts of the driver is in ni_mio_common.c, which is included
65a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	both here and in ni_pcimio.c
66a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
67a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	Interrupt support added by Truxton Fulton <trux@truxton.com>
68a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
69a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	References for specifications:
70a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
71a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   340747b.pdf  Register Level Programmer Manual (obsolete)
72a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   340747c.pdf  Register Level Programmer Manual (new)
73a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   DAQ-STC reference manual
74a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
75a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	Other possibly relevant info:
76a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
77a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   320517c.pdf  User manual (obsolete)
78a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   320517f.pdf  User manual (new)
79a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   320889a.pdf  delete
80a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   320906c.pdf  maximum signal ratings
81a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321066a.pdf  about 16x
82a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321791a.pdf  discontinuation of at-mio-16e-10 rev. c
83a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321808a.pdf  about at-mio-16e-10 rev P
84a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321837a.pdf  discontinuation of at-mio-16de-10 rev d
85a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321838a.pdf  about at-mio-16de-10 rev N
86a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
87a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	ISSUES:
88a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
89a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	need to deal with external reference for DAC, and other DAC
90a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	properties in board properties
91a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
92a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	deal with at-mio-16de-10 revision D to N changes, etc.
93a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
94a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef*/
95a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
9625436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h>
97a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include "../comedidev.h"
98a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
99a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include <linux/delay.h>
100a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include <linux/isapnp.h>
101a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
102a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include "ni_stc.h"
103a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include "8255.h"
104a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
105a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#undef DEBUG
106a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
107a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#define ATMIO 1
108a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#undef PCIMIO
109a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
110a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/*
111a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef *  AT specific setup
112a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef */
113a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
114a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#define NI_SIZE 0x20
115a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
116a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#define MAX_N_CALDACS 32
117a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
1188ab41df0d7399567372d75d1a3c552dccb42063dBill Pembertonstatic const struct ni_board_struct ni_boards[] = {
11968c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	{.device_id = 44,
1200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .isapnp_id = 0x0000,	/* XXX unknown */
1210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "at-mio-16e-1",
1220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_adchan = 16,
1230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .adbits = 12,
1240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_fifo_depth = 8192,
1250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .alwaysdither = 0,
1260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .gainlkup = ai_gain_16,
1270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_speed = 800,
1280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_aochan = 2,
1290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .aobits = 12,
1300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_fifo_depth = 2048,
1310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_range_table = &range_ni_E_ao_ext,
1320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_unipolar = 1,
1330a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_speed = 1000,
1340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .has_8255 = 0,
1350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .num_p0_dio_channels = 8,
1360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .caldac = {mb88341},
1370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
13868c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	{.device_id = 25,
1390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .isapnp_id = 0x1900,
1400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "at-mio-16e-2",
1410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_adchan = 16,
1420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .adbits = 12,
1430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_fifo_depth = 2048,
1440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .alwaysdither = 0,
1450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .gainlkup = ai_gain_16,
1460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_speed = 2000,
1470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_aochan = 2,
1480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .aobits = 12,
1490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_fifo_depth = 2048,
1500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_range_table = &range_ni_E_ao_ext,
1510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_unipolar = 1,
1520a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_speed = 1000,
1530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .has_8255 = 0,
1540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .num_p0_dio_channels = 8,
1550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .caldac = {mb88341},
1560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
15768c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	{.device_id = 36,
1580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .isapnp_id = 0x2400,
1590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "at-mio-16e-10",
1600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_adchan = 16,
1610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .adbits = 12,
1620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_fifo_depth = 512,
1630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .alwaysdither = 0,
1640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .gainlkup = ai_gain_16,
1650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_speed = 10000,
1660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_aochan = 2,
1670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .aobits = 12,
1680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_fifo_depth = 0,
1690a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_range_table = &range_ni_E_ao_ext,
1700a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_unipolar = 1,
1710a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_speed = 10000,
1720a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .num_p0_dio_channels = 8,
1730a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .caldac = {ad8804_debug},
1740a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .has_8255 = 0,
1750a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
17668c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	{.device_id = 37,
1770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .isapnp_id = 0x2500,
1780a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "at-mio-16de-10",
1790a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_adchan = 16,
1800a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .adbits = 12,
1810a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_fifo_depth = 512,
1820a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .alwaysdither = 0,
1830a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .gainlkup = ai_gain_16,
1840a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_speed = 10000,
1850a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_aochan = 2,
1860a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .aobits = 12,
1870a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_fifo_depth = 0,
1880a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_range_table = &range_ni_E_ao_ext,
1890a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_unipolar = 1,
1900a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_speed = 10000,
1910a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .num_p0_dio_channels = 8,
1920a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .caldac = {ad8804_debug},
1930a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .has_8255 = 1,
1940a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
19568c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	{.device_id = 38,
1960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .isapnp_id = 0x2600,
1970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "at-mio-64e-3",
1980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_adchan = 64,
1990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .adbits = 12,
2000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_fifo_depth = 2048,
2010a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .alwaysdither = 0,
2020a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .gainlkup = ai_gain_16,
2030a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_speed = 2000,
2040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_aochan = 2,
2050a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .aobits = 12,
2060a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_fifo_depth = 2048,
2070a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_range_table = &range_ni_E_ao_ext,
2080a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_unipolar = 1,
2090a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_speed = 1000,
2100a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .has_8255 = 0,
2110a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .num_p0_dio_channels = 8,
2120a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .caldac = {ad8804_debug},
2130a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
21468c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	{.device_id = 39,
2150a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .isapnp_id = 0x2700,
2160a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "at-mio-16xe-50",
2170a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_adchan = 16,
2180a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .adbits = 16,
2190a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_fifo_depth = 512,
2200a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .alwaysdither = 1,
2210a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .gainlkup = ai_gain_8,
2220a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_speed = 50000,
2230a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_aochan = 2,
2240a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .aobits = 12,
2250a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_fifo_depth = 0,
2260a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_range_table = &range_bipolar10,
2270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_unipolar = 0,
2280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_speed = 50000,
2290a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .num_p0_dio_channels = 8,
2300a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .caldac = {dac8800, dac8043},
2310a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .has_8255 = 0,
2320a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
23368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	{.device_id = 50,
2340a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .isapnp_id = 0x0000,	/* XXX unknown */
2350a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "at-mio-16xe-10",
2360a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_adchan = 16,
2370a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .adbits = 16,
2380a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_fifo_depth = 512,
2390a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .alwaysdither = 1,
2400a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .gainlkup = ai_gain_14,
2410a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_speed = 10000,
2420a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_aochan = 2,
2430a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .aobits = 16,
2440a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_fifo_depth = 2048,
2450a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_range_table = &range_ni_E_ao_ext,
2460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_unipolar = 1,
2470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_speed = 1000,
2480a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .num_p0_dio_channels = 8,
2490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .caldac = {dac8800, dac8043, ad8522},
2500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .has_8255 = 0,
2510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 },
25268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	{.device_id = 51,
2530a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .isapnp_id = 0x0000,	/* XXX unknown */
2540a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .name = "at-ai-16xe-10",
2550a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_adchan = 16,
2560a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .adbits = 16,
2570a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_fifo_depth = 512,
2580a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .alwaysdither = 1,	/* unknown */
2590a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .gainlkup = ai_gain_14,
2600a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ai_speed = 10000,
2610a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .n_aochan = 0,
2620a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .aobits = 0,
2630a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_fifo_depth = 0,
2640a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .ao_unipolar = 0,
2650a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .num_p0_dio_channels = 8,
2660a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .caldac = {dac8800, dac8043, ad8522},
2670a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 .has_8255 = 0,
2680a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral	 }
269a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef};
270a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
271963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burtonstatic const int ni_irqpin[] = {
272963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burton	-1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7
273963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burton};
274a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
275a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#define interrupt_pin(a)	(ni_irqpin[(a)])
276a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
277a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#define IRQ_POLARITY 0
278a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
279a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#define NI_E_IRQ_FLAGS		0
280a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
2813301cc76656c5fee5b638378d9057e93796d490fBill Pembertonstruct ni_private {
282a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	struct pnp_dev *isapnp_dev;
283963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burton	NI_PRIVATE_COMMON
284963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burton
285963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burton};
286963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burton
2873301cc76656c5fee5b638378d9057e93796d490fBill Pemberton#define devpriv ((struct ni_private *)dev->private)
288a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
289a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/* How we access registers */
290a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
291f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton#define ni_writel(a, b)		(outl((a), (b)+dev->iobase))
292a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#define ni_readl(a)		(inl((a)+dev->iobase))
293f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton#define ni_writew(a, b)		(outw((a), (b)+dev->iobase))
294a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#define ni_readw(a)		(inw((a)+dev->iobase))
295f7cbd7aad063b2a4b7aff6a743b2b00015ce3c3eBill Pemberton#define ni_writeb(a, b)		(outb((a), (b)+dev->iobase))
296a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#define ni_readb(a)		(inb((a)+dev->iobase))
297a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
298a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/* How we access windowed registers */
299a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
300a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/* We automatically take advantage of STC registers that can be
301a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef * read/written directly in the I/O space of the board.  The
302a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef * AT-MIO devices map the low 8 STC registers to iobase+addr*2. */
303a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
304da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic void ni_atmio_win_out(struct comedi_device *dev, uint16_t data, int addr)
305a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef{
306a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	unsigned long flags;
307a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
3085f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&devpriv->window_lock, flags);
309a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if ((addr) < 8) {
310a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		ni_writew(data, addr * 2);
311a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	} else {
312a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		ni_writew(addr, Window_Address);
313a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		ni_writew(data, Window_Data);
314a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
3155f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&devpriv->window_lock, flags);
316a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef}
317a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
318da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic uint16_t ni_atmio_win_in(struct comedi_device *dev, int addr)
319a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef{
320a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	unsigned long flags;
321a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	uint16_t ret;
322a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
3235f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_lock_irqsave(&devpriv->window_lock, flags);
324a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (addr < 8) {
325a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		ret = ni_readw(addr * 2);
326a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	} else {
327a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		ni_writew(addr, Window_Address);
328a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		ret = ni_readw(Window_Data);
329a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
3305f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman	spin_unlock_irqrestore(&devpriv->window_lock, flags);
331a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
332a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	return ret;
333a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef}
334a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
335a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefstatic struct pnp_device_id device_ids[] = {
336bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC1900", .driver_data = 0},
337bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC2400", .driver_data = 0},
338bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC2500", .driver_data = 0},
339bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC2600", .driver_data = 0},
340bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC2700", .driver_data = 0},
341a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	{.id = ""}
342a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef};
343a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
344a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefMODULE_DEVICE_TABLE(pnp, device_ids);
345a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
3460a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_atmio_attach(struct comedi_device *dev,
3470a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   struct comedi_devconfig *it);
348da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_atmio_detach(struct comedi_device *dev);
349139dfbdfacb02e3ef3df936d2fabd1ad5f14ea88Bill Pembertonstatic struct comedi_driver driver_atmio = {
35068c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.driver_name = "ni_atmio",
35168c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.module = THIS_MODULE,
35268c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.attach = ni_atmio_attach,
35368c3dbff9fc9f25872408d0e95980d41733d48d0Bill Pemberton	.detach = ni_atmio_detach,
354a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef};
355a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
3567114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic int __init driver_atmio_init_module(void)
3577114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
3587114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	return comedi_driver_register(&driver_atmio);
3597114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
3607114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
3617114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasstatic void __exit driver_atmio_cleanup_module(void)
3627114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas{
3637114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas	comedi_driver_unregister(&driver_atmio);
3647114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas}
3657114a28011f9d5f3d981731ad341177c21f9d948Arun Thomas
3667114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_init(driver_atmio_init_module);
3677114a28011f9d5f3d981731ad341177c21f9d948Arun Thomasmodule_exit(driver_atmio_cleanup_module);
368a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
369a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include "ni_mio_common.c"
370a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
371da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_getboardtype(struct comedi_device *dev);
372a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
373a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/* clean up allocated resources */
374da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_atmio_detach(struct comedi_device *dev)
375a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef{
376a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	mio_common_detach(dev);
377a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
378a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (dev->iobase)
379a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		release_region(dev->iobase, NI_SIZE);
380bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	if (dev->irq)
3815f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		free_irq(dev->irq, dev);
382bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe
383a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (devpriv->isapnp_dev)
384a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		pnp_device_detach(devpriv->isapnp_dev);
385a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
386a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	return 0;
387a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef}
388a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
389a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefstatic int ni_isapnp_find_board(struct pnp_dev **dev)
390a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef{
391a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	struct pnp_dev *isapnp_dev = NULL;
392a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	int i;
393a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
394a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	for (i = 0; i < n_ni_boards; i++) {
395a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		isapnp_dev = pnp_find_dev(NULL,
3960a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  ISAPNP_VENDOR('N', 'I', 'C'),
3970a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  ISAPNP_FUNCTION(ni_boards[i].
3980a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  isapnp_id), NULL);
399a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
400a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		if (isapnp_dev == NULL || isapnp_dev->card == NULL)
401a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			continue;
402a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
403a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		if (pnp_device_attach(isapnp_dev) < 0) {
4040a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			printk
405bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe			 ("ni_atmio: %s found but already active, skipping.\n",
406bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe			  ni_boards[i].name);
407a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			continue;
408a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		}
409a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		if (pnp_activate_dev(isapnp_dev) < 0) {
410a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			pnp_device_detach(isapnp_dev);
411a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return -EAGAIN;
412a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		}
413a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		if (!pnp_port_valid(isapnp_dev, 0)
4140a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral		    || !pnp_irq_valid(isapnp_dev, 0)) {
415a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			pnp_device_detach(isapnp_dev);
416a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			printk("ni_atmio: pnp invalid port or irq, aborting\n");
417a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return -ENOMEM;
418a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		}
419a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		break;
420a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
421a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (i == n_ni_boards)
422a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		return -ENODEV;
423a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	*dev = isapnp_dev;
424a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	return 0;
425a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef}
426a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
4270a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_atmio_attach(struct comedi_device *dev,
4280a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   struct comedi_devconfig *it)
429a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef{
430a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	struct pnp_dev *isapnp_dev;
431a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	int ret;
432a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	unsigned long iobase;
433a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	int board;
434a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	unsigned int irq;
435a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
436a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	/* allocate private area */
437c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = ni_alloc_private(dev);
438c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	if (ret < 0)
439a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		return ret;
440c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton
441a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	devpriv->stc_writew = &ni_atmio_win_out;
442a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	devpriv->stc_readw = &ni_atmio_win_in;
443a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	devpriv->stc_writel = &win_out2;
444a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	devpriv->stc_readl = &win_in2;
445a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
446a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	iobase = it->options[0];
447a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	irq = it->options[1];
448a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	isapnp_dev = NULL;
449a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (iobase == 0) {
450a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		ret = ni_isapnp_find_board(&isapnp_dev);
451a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		if (ret < 0)
452a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return ret;
453a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
454a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		iobase = pnp_port_start(isapnp_dev, 0);
455a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		irq = pnp_irq(isapnp_dev, 0);
456a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		devpriv->isapnp_dev = isapnp_dev;
457a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
458a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
459a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	/* reserve our I/O region */
460a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
461a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	printk("comedi%d: ni_atmio: 0x%04lx", dev->minor, iobase);
462a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (!request_region(iobase, NI_SIZE, "ni_atmio")) {
463a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		printk(" I/O port conflict\n");
464a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		return -EIO;
465a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
466a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
467a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	dev->iobase = iobase;
468a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
469a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#ifdef DEBUG
470a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	/* board existence sanity check */
471a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	{
472a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		int i;
473a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
474a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		printk(" board fingerprint:");
475a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		for (i = 0; i < 16; i += 2) {
476a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			printk(" %04x %02x", inw(dev->iobase + i),
4770a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			       inb(dev->iobase + i + 1));
478a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		}
479a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
480a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#endif
481a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
482a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	/* get board type */
483a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
484a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	board = ni_getboardtype(dev);
485a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (board < 0)
486a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		return -EIO;
487a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
488a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	dev->board_ptr = ni_boards + board;
489a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
490a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	printk(" %s", boardtype.name);
491a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	dev->board_name = boardtype.name;
492a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
493a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	/* irq stuff */
494a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
495a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (irq != 0) {
496a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		if (irq > 15 || ni_irqpin[irq] == -1) {
497a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			printk(" invalid irq %u\n", irq);
498a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return -EINVAL;
499a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		}
500a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		printk(" ( irq = %u )", irq);
5015f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman		ret = request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
5025f74ea14c07fee91d3bdbaad88bff6264c6200e6Greg Kroah-Hartman				  "ni_atmio", dev);
503c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton
504c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton		if (ret < 0) {
505a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			printk(" irq not available\n");
506a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return -EINVAL;
507a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		}
508a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		dev->irq = irq;
509a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
510a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
511a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	/* generic E series stuff in ni_mio_common.c */
512a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
513c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = ni_E_init(dev, it);
514bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	if (ret < 0)
515a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		return ret;
516bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe
517a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
518a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	return 0;
519a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef}
520a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
521da91b2692e0939b307f9047192d2b9fe07793e7aBill Pembertonstatic int ni_getboardtype(struct comedi_device *dev)
522a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef{
523a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	int device_id = ni_read_eeprom(dev, 511);
524a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	int i;
525a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
526a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	for (i = 0; i < n_ni_boards; i++) {
527bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe		if (ni_boards[i].device_id == device_id)
528a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return i;
529bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe
530a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
531bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	if (device_id == 255)
532a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		printk(" can't find board\n");
533bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	 else if (device_id == 0)
534a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		printk(" EEPROM read error (?) or device not found\n");
535bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	 else
536a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		printk(" unknown device ID %d -- contact author\n", device_id);
537bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe
538a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	return -1;
539a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef}
540