1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44#include "../comedidev.h"
45
46#include <linux/delay.h>
47
48#include "ni_stc.h"
49#include "8255.h"
50
51#include <pcmcia/cistpl.h>
52#include <pcmcia/ds.h>
53
54#undef DEBUG
55
56#define ATMIO 1
57#undef PCIMIO
58
59
60
61
62
63#define NI_SIZE 0x20
64
65#define MAX_N_CALDACS 32
66
67static const struct ni_board_struct ni_boards[] = {
68 {
69 .device_id = 0x010d,
70 .name = "DAQCard-ai-16xe-50",
71 .n_adchan = 16,
72 .adbits = 16,
73 .ai_fifo_depth = 1024,
74 .gainlkup = ai_gain_8,
75 .ai_speed = 5000,
76 .num_p0_dio_channels = 8,
77 .caldac = { dac8800, dac8043 },
78 }, {
79 .device_id = 0x010c,
80 .name = "DAQCard-ai-16e-4",
81 .n_adchan = 16,
82 .adbits = 12,
83 .ai_fifo_depth = 1024,
84 .gainlkup = ai_gain_16,
85 .ai_speed = 4000,
86 .num_p0_dio_channels = 8,
87 .caldac = { mb88341 },
88 }, {
89 .device_id = 0x02c4,
90 .name = "DAQCard-6062E",
91 .n_adchan = 16,
92 .adbits = 12,
93 .ai_fifo_depth = 8192,
94 .gainlkup = ai_gain_16,
95 .ai_speed = 2000,
96 .n_aochan = 2,
97 .aobits = 12,
98 .ao_fifo_depth = 2048,
99 .ao_range_table = &range_bipolar10,
100 .ao_speed = 1176,
101 .num_p0_dio_channels = 8,
102 .caldac = { ad8804_debug },
103 }, {
104
105 .device_id = 0x075e,
106 .name = "DAQCard-6024E",
107 .n_adchan = 16,
108 .adbits = 12,
109 .ai_fifo_depth = 1024,
110 .gainlkup = ai_gain_4,
111 .ai_speed = 5000,
112 .n_aochan = 2,
113 .aobits = 12,
114 .ao_range_table = &range_bipolar10,
115 .ao_speed = 1000000,
116 .num_p0_dio_channels = 8,
117 .caldac = { ad8804_debug },
118 }, {
119
120 .device_id = 0x0245,
121 .name = "DAQCard-6036E",
122 .n_adchan = 16,
123 .adbits = 16,
124 .ai_fifo_depth = 1024,
125 .alwaysdither = 1,
126 .gainlkup = ai_gain_4,
127 .ai_speed = 5000,
128 .n_aochan = 2,
129 .aobits = 16,
130 .ao_range_table = &range_bipolar10,
131 .ao_speed = 1000000,
132 .num_p0_dio_channels = 8,
133 .caldac = { ad8804_debug },
134 },
135#if 0
136 {
137 .device_id = 0x0000,
138 .name = "DAQCard-6715",
139 .n_aochan = 8,
140 .aobits = 12,
141 .ao_671x = 8192,
142 .num_p0_dio_channels = 8,
143 .caldac = { mb88341, mb88341 },
144 },
145#endif
146};
147
148#define interrupt_pin(a) 0
149
150#define IRQ_POLARITY 1
151
152struct ni_private {
153
154 struct pcmcia_device *link;
155
156NI_PRIVATE_COMMON};
157
158
159
160#define ni_writel(a, b) (outl((a), (b)+dev->iobase))
161#define ni_readl(a) (inl((a)+dev->iobase))
162#define ni_writew(a, b) (outw((a), (b)+dev->iobase))
163#define ni_readw(a) (inw((a)+dev->iobase))
164#define ni_writeb(a, b) (outb((a), (b)+dev->iobase))
165#define ni_readb(a) (inb((a)+dev->iobase))
166
167
168
169
170
171
172
173static void mio_cs_win_out(struct comedi_device *dev, uint16_t data, int addr)
174{
175 struct ni_private *devpriv = dev->private;
176 unsigned long flags;
177
178 spin_lock_irqsave(&devpriv->window_lock, flags);
179 if (addr < 8) {
180 ni_writew(data, addr * 2);
181 } else {
182 ni_writew(addr, Window_Address);
183 ni_writew(data, Window_Data);
184 }
185 spin_unlock_irqrestore(&devpriv->window_lock, flags);
186}
187
188static uint16_t mio_cs_win_in(struct comedi_device *dev, int addr)
189{
190 struct ni_private *devpriv = dev->private;
191 unsigned long flags;
192 uint16_t ret;
193
194 spin_lock_irqsave(&devpriv->window_lock, flags);
195 if (addr < 8) {
196 ret = ni_readw(addr * 2);
197 } else {
198 ni_writew(addr, Window_Address);
199 ret = ni_readw(Window_Data);
200 }
201 spin_unlock_irqrestore(&devpriv->window_lock, flags);
202
203 return ret;
204}
205
206#include "ni_mio_common.c"
207
208static const void *ni_getboardtype(struct comedi_device *dev,
209 struct pcmcia_device *link)
210{
211 static const struct ni_board_struct *board;
212 int i;
213
214 for (i = 0; i < ARRAY_SIZE(ni_boards); i++) {
215 board = &ni_boards[i];
216 if (board->device_id == link->card_id)
217 return board;
218 }
219 return NULL;
220}
221
222static int mio_pcmcia_config_loop(struct pcmcia_device *p_dev, void *priv_data)
223{
224 int base, ret;
225
226 p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
227 p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
228
229 for (base = 0x000; base < 0x400; base += 0x20) {
230 p_dev->resource[0]->start = base;
231 ret = pcmcia_request_io(p_dev);
232 if (!ret)
233 return 0;
234 }
235 return -ENODEV;
236}
237
238static int mio_cs_auto_attach(struct comedi_device *dev,
239 unsigned long context)
240{
241 struct pcmcia_device *link = comedi_to_pcmcia_dev(dev);
242 static const struct ni_board_struct *board;
243 struct ni_private *devpriv;
244 int ret;
245
246 board = ni_getboardtype(dev, link);
247 if (!board)
248 return -ENODEV;
249 dev->board_ptr = board;
250 dev->board_name = board->name;
251
252 link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ;
253 ret = comedi_pcmcia_enable(dev, mio_pcmcia_config_loop);
254 if (ret)
255 return ret;
256 dev->iobase = link->resource[0]->start;
257
258 link->priv = dev;
259 ret = pcmcia_request_irq(link, ni_E_interrupt);
260 if (ret)
261 return ret;
262 dev->irq = link->irq;
263
264 ret = ni_alloc_private(dev);
265 if (ret)
266 return ret;
267
268 devpriv = dev->private;
269 devpriv->stc_writew = mio_cs_win_out;
270 devpriv->stc_readw = mio_cs_win_in;
271 devpriv->stc_writel = win_out2;
272 devpriv->stc_readl = win_in2;
273
274 return ni_E_init(dev);
275}
276
277static void mio_cs_detach(struct comedi_device *dev)
278{
279 mio_common_detach(dev);
280 comedi_pcmcia_disable(dev);
281}
282
283static struct comedi_driver driver_ni_mio_cs = {
284 .driver_name = "ni_mio_cs",
285 .module = THIS_MODULE,
286 .auto_attach = mio_cs_auto_attach,
287 .detach = mio_cs_detach,
288};
289
290static int cs_attach(struct pcmcia_device *link)
291{
292 return comedi_pcmcia_auto_config(link, &driver_ni_mio_cs);
293}
294
295static const struct pcmcia_device_id ni_mio_cs_ids[] = {
296 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010d),
297 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010c),
298 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x02c4),
299 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x075e),
300 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0245),
301 PCMCIA_DEVICE_NULL
302};
303MODULE_DEVICE_TABLE(pcmcia, ni_mio_cs_ids);
304
305static struct pcmcia_driver ni_mio_cs_driver = {
306 .name = "ni_mio_cs",
307 .owner = THIS_MODULE,
308 .id_table = ni_mio_cs_ids,
309 .probe = cs_attach,
310 .remove = comedi_pcmcia_auto_unconfig,
311};
312module_comedi_pcmcia_driver(driver_ni_mio_cs, ni_mio_cs_driver);
313
314MODULE_DESCRIPTION("Comedi driver for National Instruments DAQCard E series");
315MODULE_AUTHOR("David A. Schleef <ds@schleef.org>");
316MODULE_LICENSE("GPL");
317