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/*
19a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefDriver: ni_atmio
20a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefDescription: National Instruments AT-MIO-E series
21a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefAuthor: ds
22a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefDevices: [National Instruments] AT-MIO-16E-1 (ni_atmio),
23a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef  AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
24a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef  AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
25a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefStatus: works
26a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefUpdated: Thu May  1 20:03:02 CDT 2003
27a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
28a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefThe driver has 2.6 kernel isapnp support, and
29a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefwill automatically probe for a supported board if the
30a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefI/O base is left unspecified with comedi_config.
31a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefHowever, many of
32a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefthe isapnp id numbers are unknown.  If your board is not
33a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefrecognized, please send the output of 'cat /proc/isapnp'
34a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef(you may need to modprobe the isa-pnp module for
35a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/proc/isapnp to exist) so the
36a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefid numbers for your board can be added to the driver.
37a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
38a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefOtherwise, you can use the isapnptools package to configure
39a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefyour board.  Use isapnp to
40a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefconfigure the I/O base and IRQ for the board, and then pass
41a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefthe same values as
42a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefparameters in comedi_config.  A sample isapnp.conf file is included
43a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefin the etc/ directory of Comedilib.
44a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
45a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefComedilib includes a utility to autocalibrate these boards.  The
46a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefboards seem to boot into a state where the all calibration DACs
47a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefare at one extreme of their range, thus the default calibration
48a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefis terrible.  Calibration at boot is strongly encouraged.
49a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
50a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefTo use the extended digital I/O on some of the boards, enable the
51a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef8255 driver when configuring the Comedi source tree.
52a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
53a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefExternal triggering is supported for some events.  The channel index
54a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef(scan_begin_arg, etc.) maps to PFI0 - PFI9.
55a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
56a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefSome of the more esoteric triggering possibilities of these boards
57a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefare not supported.
58a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef*/
59a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/*
60a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	The real guts of the driver is in ni_mio_common.c, which is included
61a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	both here and in ni_pcimio.c
62a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
63a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	Interrupt support added by Truxton Fulton <trux@truxton.com>
64a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
65a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	References for specifications:
66a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
67a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   340747b.pdf  Register Level Programmer Manual (obsolete)
68a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   340747c.pdf  Register Level Programmer Manual (new)
69a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   DAQ-STC reference manual
70a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
71a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	Other possibly relevant info:
72a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
73a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   320517c.pdf  User manual (obsolete)
74a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   320517f.pdf  User manual (new)
75a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   320889a.pdf  delete
76a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   320906c.pdf  maximum signal ratings
77a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321066a.pdf  about 16x
78a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321791a.pdf  discontinuation of at-mio-16e-10 rev. c
79a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321808a.pdf  about at-mio-16e-10 rev P
80a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321837a.pdf  discontinuation of at-mio-16de-10 rev d
81a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	   321838a.pdf  about at-mio-16de-10 rev N
82a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
83a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	ISSUES:
84a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
85a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	need to deal with external reference for DAC, and other DAC
86a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	properties in board properties
87a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
88a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	deal with at-mio-16de-10 revision D to N changes, etc.
89a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
90a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef*/
91a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
92ce157f8032bbd46d9427034c335b0afd751da25dH Hartley Sweeten#include <linux/module.h>
9325436dc9d84f1be60ff549c9ab712bba2835f284Greg Kroah-Hartman#include <linux/interrupt.h>
94a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include "../comedidev.h"
95a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
96a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include <linux/isapnp.h>
97a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
98a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include "ni_stc.h"
99a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef#include "8255.h"
100a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
101a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef/*
102a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef *  AT specific setup
103a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef */
104a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
1058ab41df0d7399567372d75d1a3c552dccb42063dBill Pembertonstatic const struct ni_board_struct ni_boards[] = {
106252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten	{
107b674f9df207dc7da7b77ada82e0fb072ba06267cH Hartley Sweeten		.name		= "at-mio-16e-1",
108252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.device_id	= 44,
109252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.isapnp_id	= 0x0000,	/* XXX unknown */
110252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_adchan	= 16,
111db2255f5a0394fc5bc295a4b3e96667c46a7b9efH Hartley Sweeten		.ai_maxdata	= 0x0fff,
112252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_fifo_depth	= 8192,
113252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.gainlkup	= ai_gain_16,
114252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_speed	= 800,
115252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_aochan	= 2,
116c5f26499998476edf599b599cd88163305dee5b2H Hartley Sweeten		.ao_maxdata	= 0x0fff,
117252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_fifo_depth	= 2048,
118252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_range_table	= &range_ni_E_ao_ext,
119252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_speed	= 1000,
120252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.caldac		= { mb88341 },
121252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten	}, {
122b674f9df207dc7da7b77ada82e0fb072ba06267cH Hartley Sweeten		.name		= "at-mio-16e-2",
123252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.device_id	= 25,
124252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.isapnp_id	= 0x1900,
125252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_adchan	= 16,
126db2255f5a0394fc5bc295a4b3e96667c46a7b9efH Hartley Sweeten		.ai_maxdata	= 0x0fff,
127252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_fifo_depth	= 2048,
128252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.gainlkup	= ai_gain_16,
129252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_speed	= 2000,
130252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_aochan	= 2,
131c5f26499998476edf599b599cd88163305dee5b2H Hartley Sweeten		.ao_maxdata	= 0x0fff,
132252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_fifo_depth	= 2048,
133252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_range_table	= &range_ni_E_ao_ext,
134252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_speed	= 1000,
135252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.caldac		= { mb88341 },
136252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten	}, {
137b674f9df207dc7da7b77ada82e0fb072ba06267cH Hartley Sweeten		.name		= "at-mio-16e-10",
138252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.device_id	= 36,
139252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.isapnp_id	= 0x2400,
140252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_adchan	= 16,
141db2255f5a0394fc5bc295a4b3e96667c46a7b9efH Hartley Sweeten		.ai_maxdata	= 0x0fff,
142252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_fifo_depth	= 512,
143252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.gainlkup	= ai_gain_16,
144252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_speed	= 10000,
145252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_aochan	= 2,
146c5f26499998476edf599b599cd88163305dee5b2H Hartley Sweeten		.ao_maxdata	= 0x0fff,
147252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_range_table	= &range_ni_E_ao_ext,
148252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_speed	= 10000,
149252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.caldac		= { ad8804_debug },
150252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten	}, {
151b674f9df207dc7da7b77ada82e0fb072ba06267cH Hartley Sweeten		.name		= "at-mio-16de-10",
152252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.device_id	= 37,
153252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.isapnp_id	= 0x2500,
154252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_adchan	= 16,
155db2255f5a0394fc5bc295a4b3e96667c46a7b9efH Hartley Sweeten		.ai_maxdata	= 0x0fff,
156252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_fifo_depth	= 512,
157252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.gainlkup	= ai_gain_16,
158252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_speed	= 10000,
159252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_aochan	= 2,
160c5f26499998476edf599b599cd88163305dee5b2H Hartley Sweeten		.ao_maxdata	= 0x0fff,
161252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_range_table	= &range_ni_E_ao_ext,
162252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_speed	= 10000,
163252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.caldac		= { ad8804_debug },
164252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.has_8255	= 1,
165252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten	}, {
166b674f9df207dc7da7b77ada82e0fb072ba06267cH Hartley Sweeten		.name		= "at-mio-64e-3",
167252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.device_id	= 38,
168252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.isapnp_id	= 0x2600,
169252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_adchan	= 64,
170db2255f5a0394fc5bc295a4b3e96667c46a7b9efH Hartley Sweeten		.ai_maxdata	= 0x0fff,
171252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_fifo_depth	= 2048,
172252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.gainlkup	= ai_gain_16,
173252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_speed	= 2000,
174252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_aochan	= 2,
175c5f26499998476edf599b599cd88163305dee5b2H Hartley Sweeten		.ao_maxdata	= 0x0fff,
176252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_fifo_depth	= 2048,
177252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_range_table	= &range_ni_E_ao_ext,
178252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_speed	= 1000,
179252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.caldac		= { ad8804_debug },
180252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten	}, {
181b674f9df207dc7da7b77ada82e0fb072ba06267cH Hartley Sweeten		.name		= "at-mio-16xe-50",
182252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.device_id	= 39,
183252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.isapnp_id	= 0x2700,
184252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_adchan	= 16,
185db2255f5a0394fc5bc295a4b3e96667c46a7b9efH Hartley Sweeten		.ai_maxdata	= 0xffff,
186252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_fifo_depth	= 512,
187252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.alwaysdither	= 1,
188252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.gainlkup	= ai_gain_8,
189252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_speed	= 50000,
190252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_aochan	= 2,
191c5f26499998476edf599b599cd88163305dee5b2H Hartley Sweeten		.ao_maxdata	= 0x0fff,
192252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_range_table	= &range_bipolar10,
193252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_speed	= 50000,
194252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.caldac		= { dac8800, dac8043 },
195252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten	}, {
196b674f9df207dc7da7b77ada82e0fb072ba06267cH Hartley Sweeten		.name		= "at-mio-16xe-10",
197252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.device_id	= 50,
198252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.isapnp_id	= 0x0000,	/* XXX unknown */
199252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_adchan	= 16,
200db2255f5a0394fc5bc295a4b3e96667c46a7b9efH Hartley Sweeten		.ai_maxdata	= 0xffff,
201252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_fifo_depth	= 512,
202252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.alwaysdither	= 1,
203252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.gainlkup	= ai_gain_14,
204252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_speed	= 10000,
205252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_aochan	= 2,
206c5f26499998476edf599b599cd88163305dee5b2H Hartley Sweeten		.ao_maxdata	= 0xffff,
207252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_fifo_depth	= 2048,
208252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_range_table	= &range_ni_E_ao_ext,
209252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ao_speed	= 1000,
210252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.caldac		= { dac8800, dac8043, ad8522 },
211252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten	}, {
212b674f9df207dc7da7b77ada82e0fb072ba06267cH Hartley Sweeten		.name		= "at-ai-16xe-10",
213252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.device_id	= 51,
214252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.isapnp_id	= 0x0000,	/* XXX unknown */
215252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.n_adchan	= 16,
216db2255f5a0394fc5bc295a4b3e96667c46a7b9efH Hartley Sweeten		.ai_maxdata	= 0xffff,
217252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_fifo_depth	= 512,
218252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.alwaysdither	= 1,	/* unknown */
219252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.gainlkup	= ai_gain_14,
220252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.ai_speed	= 10000,
221252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten		.caldac		= { dac8800, dac8043, ad8522 },
222252948517c56e70f2c6abe50c368e7707417a140H Hartley Sweeten	},
223a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef};
224a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
225963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burtonstatic const int ni_irqpin[] = {
226963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burton	-1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7
227963ff7740d52586a0fb79f459abebf39997d3ae6Jake Burton};
228a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
229ac63baf5517cb7c22d63e2c5d269994f3002c7e0H Hartley Sweeten#include "ni_mio_common.c"
230a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
231a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefstatic struct pnp_device_id device_ids[] = {
232bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC1900", .driver_data = 0},
233bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC2400", .driver_data = 0},
234bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC2500", .driver_data = 0},
235bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC2600", .driver_data = 0},
236bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	{.id = "NIC2700", .driver_data = 0},
237a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	{.id = ""}
238a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef};
239a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
240a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid SchleefMODULE_DEVICE_TABLE(pnp, device_ids);
241a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
242a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleefstatic int ni_isapnp_find_board(struct pnp_dev **dev)
243a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef{
244a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	struct pnp_dev *isapnp_dev = NULL;
245a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	int i;
246a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
247ca4d4aa6b79f143f4c8606c60bad005405623faaH Hartley Sweeten	for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
248a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		isapnp_dev = pnp_find_dev(NULL,
2490a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  ISAPNP_VENDOR('N', 'I', 'C'),
2500a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral					  ISAPNP_FUNCTION(ni_boards[i].
2510a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral							  isapnp_id), NULL);
252a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
253a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		if (isapnp_dev == NULL || isapnp_dev->card == NULL)
254a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			continue;
255a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
256ee68d168cbfe0d8cdee8ea4b1d21a64dc24a621bH Hartley Sweeten		if (pnp_device_attach(isapnp_dev) < 0)
257a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			continue;
258ee68d168cbfe0d8cdee8ea4b1d21a64dc24a621bH Hartley Sweeten
259a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		if (pnp_activate_dev(isapnp_dev) < 0) {
260a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			pnp_device_detach(isapnp_dev);
261a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return -EAGAIN;
262a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		}
263ee68d168cbfe0d8cdee8ea4b1d21a64dc24a621bH Hartley Sweeten
264ee68d168cbfe0d8cdee8ea4b1d21a64dc24a621bH Hartley Sweeten		if (!pnp_port_valid(isapnp_dev, 0) ||
265ee68d168cbfe0d8cdee8ea4b1d21a64dc24a621bH Hartley Sweeten		    !pnp_irq_valid(isapnp_dev, 0)) {
266a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			pnp_device_detach(isapnp_dev);
267a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return -ENOMEM;
268a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		}
269a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		break;
270a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
271ca4d4aa6b79f143f4c8606c60bad005405623faaH Hartley Sweeten	if (i == ARRAY_SIZE(ni_boards))
272a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		return -ENODEV;
273a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	*dev = isapnp_dev;
274a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	return 0;
275a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef}
276a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
2775aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweetenstatic int ni_getboardtype(struct comedi_device *dev)
2785aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten{
2795aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	int device_id = ni_read_eeprom(dev, 511);
2805aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	int i;
2815aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten
282ca4d4aa6b79f143f4c8606c60bad005405623faaH Hartley Sweeten	for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
2835aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten		if (ni_boards[i].device_id == device_id)
2845aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten			return i;
2855aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten
2865aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	}
2875aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	if (device_id == 255)
288b252ebfccf61ccd6bbb04cdfd3ec1c33ea65b5dbH Hartley Sweeten		dev_err(dev->class_dev, "can't find board\n");
2895aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	 else if (device_id == 0)
290b252ebfccf61ccd6bbb04cdfd3ec1c33ea65b5dbH Hartley Sweeten		dev_err(dev->class_dev,
291b252ebfccf61ccd6bbb04cdfd3ec1c33ea65b5dbH Hartley Sweeten			"EEPROM read error (?) or device not found\n");
2925aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	 else
293b252ebfccf61ccd6bbb04cdfd3ec1c33ea65b5dbH Hartley Sweeten		dev_err(dev->class_dev,
294b252ebfccf61ccd6bbb04cdfd3ec1c33ea65b5dbH Hartley Sweeten			"unknown device ID %d -- contact author\n", device_id);
2955aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten
2965aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	return -1;
2975aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten}
2985aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten
2990a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukralstatic int ni_atmio_attach(struct comedi_device *dev,
3000a85b6f0ab0d2edb0d41b32697111ce0e4f43496Mithlesh Thukral			   struct comedi_devconfig *it)
301a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef{
302ca4d4aa6b79f143f4c8606c60bad005405623faaH Hartley Sweeten	const struct ni_board_struct *boardtype;
3030e05c55226bffcdd3f1393d5ab74cd0d9faff385H Hartley Sweeten	struct ni_private *devpriv;
304a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	struct pnp_dev *isapnp_dev;
305a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	int ret;
306a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	unsigned long iobase;
307a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	int board;
308a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	unsigned int irq;
309a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
310c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton	ret = ni_alloc_private(dev);
3110e05c55226bffcdd3f1393d5ab74cd0d9faff385H Hartley Sweeten	if (ret)
312a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		return ret;
3130e05c55226bffcdd3f1393d5ab74cd0d9faff385H Hartley Sweeten	devpriv = dev->private;
314c3744138715045adb316284ee7a1e608f0278f6cBill Pemberton
315a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	iobase = it->options[0];
316a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	irq = it->options[1];
317a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	isapnp_dev = NULL;
318a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (iobase == 0) {
319a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		ret = ni_isapnp_find_board(&isapnp_dev);
320a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		if (ret < 0)
321a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return ret;
322a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
323a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		iobase = pnp_port_start(isapnp_dev, 0);
324a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		irq = pnp_irq(isapnp_dev, 0);
325ffd0a782bae3ac8355963a1c2e8028a73c666018H Hartley Sweeten		comedi_set_hw_dev(dev, &isapnp_dev->dev);
326a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
327a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
328551d793943c39bc8e9d548ac454cd0df32688211H Hartley Sweeten	ret = comedi_request_region(dev, iobase, 0x20);
329b1bc9276047d0b410dc0676edc12ce3c31e96a36H Hartley Sweeten	if (ret)
330b1bc9276047d0b410dc0676edc12ce3c31e96a36H Hartley Sweeten		return ret;
331a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
332a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	/* get board type */
333a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
334a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	board = ni_getboardtype(dev);
335a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (board < 0)
336a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		return -EIO;
337a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
338a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	dev->board_ptr = ni_boards + board;
339af169cf1e215e213e8616774fc018547fabbbb26Ian Abbott	boardtype = dev->board_ptr;
340ca4d4aa6b79f143f4c8606c60bad005405623faaH Hartley Sweeten	dev->board_name = boardtype->name;
341a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
342a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	/* irq stuff */
343a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
344a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	if (irq != 0) {
345221fa08c53261f7694b07c22e91d43fdbef09b62H Hartley Sweeten		if (irq > 15 || ni_irqpin[irq] == -1)
346a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return -EINVAL;
34732d878a285250fd30acda57033a9e51e77ab50a3H Hartley Sweeten		ret = request_irq(irq, ni_E_interrupt, 0,
34871e068743a5e4061a7a3c42cc3ac6dbda7a7f76eH Hartley Sweeten				  dev->board_name, dev);
349221fa08c53261f7694b07c22e91d43fdbef09b62H Hartley Sweeten		if (ret < 0)
350a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef			return -EINVAL;
351a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		dev->irq = irq;
352a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	}
353a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
354a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	/* generic E series stuff in ni_mio_common.c */
355a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
3561fa955ba355bfa6eb83b8fd9cc6064a561291d1fH Hartley Sweeten	ret = ni_E_init(dev, ni_irqpin[dev->irq], 0);
357bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe	if (ret < 0)
358a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef		return ret;
359bc2955ddf48d2da94019680fa46deae88d39b40eGraham M Howe
360a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
361a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef	return 0;
362a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef}
363a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef
364484ecc95d9cdfa8b2f7029e2f3409cf078aed4abH Hartley Sweetenstatic void ni_atmio_detach(struct comedi_device *dev)
365a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef{
366ffd0a782bae3ac8355963a1c2e8028a73c666018H Hartley Sweeten	struct pnp_dev *isapnp_dev;
3670e05c55226bffcdd3f1393d5ab74cd0d9faff385H Hartley Sweeten
3685aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	mio_common_detach(dev);
369a32c6d0084992d3e58a93120c9ce9527e80c651eH Hartley Sweeten	comedi_legacy_detach(dev);
370ffd0a782bae3ac8355963a1c2e8028a73c666018H Hartley Sweeten
371ffd0a782bae3ac8355963a1c2e8028a73c666018H Hartley Sweeten	isapnp_dev = dev->hw_dev ? to_pnp_dev(dev->hw_dev) : NULL;
372ffd0a782bae3ac8355963a1c2e8028a73c666018H Hartley Sweeten	if (isapnp_dev)
373ffd0a782bae3ac8355963a1c2e8028a73c666018H Hartley Sweeten		pnp_device_detach(isapnp_dev);
374a8b774308dd803437106e3d2b4fb6d9a3c7bfc7cDavid Schleef}
3755aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten
3765aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweetenstatic struct comedi_driver ni_atmio_driver = {
3775aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	.driver_name	= "ni_atmio",
3785aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	.module		= THIS_MODULE,
3795aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	.attach		= ni_atmio_attach,
3805aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten	.detach		= ni_atmio_detach,
3815aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweeten};
3825aac8294de60cd2ffac3236c7052571ed6c2d56dH Hartley Sweetenmodule_comedi_driver(ni_atmio_driver);
383