050232b202a393d1fa10b597fe648b690c803210
[comedi.git] / comedi / drivers / ni_pcimio.c
1 /*
2     module/ni_pcimio.c
3     Hardware driver for NI PCI-MIO E series cards
4
5     COMEDI - Linux Control and Measurement Device Interface
6     Copyright (C) 1997-8 David A. Schleef <ds@stm.lbl.gov>
7
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23 /*
24 Driver: ni_pcimio.o
25 Description: National Instruments PCI-MIO-E series (all boards)
26 Author: ds
27 Status: mainly limited by Comedi infrastructure
28 Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
29   PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6040E,
30   PXI-6040E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E,
31   PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E,
32   PCI-6110E, PCI-6111E, PCI-6711, PCI-6713, PXI-6071E, PXI-6070E,
33   PXI-6052E, PCI-6036E, PCI-6731, PCI-6733
34
35 These boards are almost identical to the AT-MIO E series, except that
36 they use the PCI bus instead of ISA (i.e., AT).  See the notes above for
37 ni_atmio.o for additional information about these boards.
38
39 Autocalibration is supported on many of the devices, using the
40 calibration utility in Comedilib.
41
42 By default, the driver uses DMA to transfer analog input data to
43 memory.  When DMA is enabled, not all triggering features are
44 supported.
45
46 Streaming analog output is not supported on PCI-671x and PCI-673x.
47
48 PCI IDs are not known for PCI-6731 and PCI-6733.  Digital I/O may not
49 work on 673x.
50
51 Information (number of channels, bits, etc.) for some devices may be
52 incorrect.
53
54 Bugs:
55  - Driver doesn't stop correctly when DMA is enabled.
56
57 */
58 /*
59         The PCI-MIO E series driver was originally written by
60         Tomasz Motylewski <...>, and ported to comedi by ds.
61
62
63         References for specifications:
64         
65            341079b.pdf  PCI E Series Register-Level Programmer Manual
66            340934b.pdf  DAQ-STC reference manual
67
68         Other possibly relevant info:
69         
70            320517c.pdf  User manual (obsolete)
71            320517f.pdf  User manual (new)
72
73            322080b.pdf  6711/6713/6715 User Manual
74         
75         ISSUES:
76
77         need to deal with external reference for DAC, and other DAC
78         properties in board properties
79         
80         deal with at-mio-16de-10 revision D to N changes, etc.
81         
82         need to add other CALDAC type
83         
84         need to slow down DAC loading.  I don't trust NI's claim that
85         two writes to the PCI bus slows IO enough.  I would prefer to
86         use udelay().  Timing specs: (clock)
87                 AD8522          30ns
88                 DAC8043         120ns
89                 DAC8800         60ns
90                 MB88341         ?
91
92 */
93
94 #include <linux/kernel.h>
95 #include <linux/module.h>
96 #include <linux/errno.h>
97 #include <linux/ioport.h>
98 #include <linux/delay.h>
99 #include <linux/mm.h>
100 #include <linux/interrupt.h>
101 #include <linux/slab.h>
102 #include <linux/comedidev.h>
103 #include <linux/init.h>
104
105 #include <asm/io.h>
106
107 #include "ni_stc.h"
108 #include "mite.h"
109
110 #define PCI_DEBUG
111
112 #define PCIDMA
113
114 #define PCIMIO 1
115 #undef ATMIO
116
117 #define MAX_N_CALDACS (16+16+2)
118
119 /* The following two tables must be in the same order */
120 static struct pci_device_id ni_pci_table[] __devinitdata = {
121         { PCI_VENDOR_ID_NATINST, 0x0162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
122         { PCI_VENDOR_ID_NATINST, 0x1170, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
123         { PCI_VENDOR_ID_NATINST, 0x11d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
124         { PCI_VENDOR_ID_NATINST, 0x1180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
125         { PCI_VENDOR_ID_NATINST, 0x1190, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
126         { PCI_VENDOR_ID_NATINST, 0x11c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
127         { PCI_VENDOR_ID_NATINST, 0x1330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
128         { PCI_VENDOR_ID_NATINST, 0x1270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
129         { PCI_VENDOR_ID_NATINST, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
130         { PCI_VENDOR_ID_NATINST, 0x1350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
131         { PCI_VENDOR_ID_NATINST, 0x2a60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
132         { PCI_VENDOR_ID_NATINST, 0x2a70, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
133         { PCI_VENDOR_ID_NATINST, 0x2a80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
134         { PCI_VENDOR_ID_NATINST, 0x2ab0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
135         { PCI_VENDOR_ID_NATINST, 0x2ca0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
136         { PCI_VENDOR_ID_NATINST, 0x2c80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
137         { PCI_VENDOR_ID_NATINST, 0x18b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
138         { PCI_VENDOR_ID_NATINST, 0x14e0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
139         { PCI_VENDOR_ID_NATINST, 0x14f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
140         { PCI_VENDOR_ID_NATINST, 0x1880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
141         { PCI_VENDOR_ID_NATINST, 0x1870, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
142         { PCI_VENDOR_ID_NATINST, 0x15b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
143         { PCI_VENDOR_ID_NATINST, 0x11b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
144         { PCI_VENDOR_ID_NATINST, 0x18c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
145         { PCI_VENDOR_ID_NATINST, 0x1580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
146         { PCI_VENDOR_ID_NATINST, 0x2890, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
147         { 0 }
148 };
149 MODULE_DEVICE_TABLE(pci, ni_pci_table);
150
151 static ni_board ni_boards[]={
152         {       device_id:      0x0162, // NI also says 0x1620.  typo?
153                 name:           "pci-mio-16xe-50",
154                 n_adchan:       16,
155                 adbits:         16,
156                 ai_fifo_depth:  2048,
157                 alwaysdither:   1,
158                 gainlkup:       ai_gain_8,
159                 ai_speed:       50000,
160                 n_aochan:       2,
161                 aobits:         12,
162                 ao_fifo_depth:  0,
163                 ao_unipolar:    0,
164                 caldac:         {dac8800,dac8043},
165                 has_8255:       0,
166         },
167         {       device_id:      0x1170,
168                 name:           "pci-mio-16xe-10",
169                 n_adchan:       16,
170                 adbits:         16,
171                 ai_fifo_depth:  512,
172                 alwaysdither:   1,
173                 gainlkup:       ai_gain_14,
174                 ai_speed:       10000,
175                 n_aochan:       2,
176                 aobits:         16,
177                 ao_fifo_depth:  2048,
178                 ao_unipolar:    1,
179                 caldac:         {dac8800,dac8043,ad8522},
180                 has_8255:       0,
181         },
182         {       device_id:      0x11d0,
183                 name:           "pxi-6030e",
184                 n_adchan:       16,
185                 adbits:         16,
186                 ai_fifo_depth:  512,
187                 alwaysdither:   1,
188                 gainlkup:       ai_gain_14,
189                 ai_speed:       10000,
190                 n_aochan:       2,
191                 aobits:         16,
192                 ao_fifo_depth:  2048,
193                 ao_unipolar:    1,
194                 caldac:         {dac8800,dac8043,ad8522},
195                 has_8255:       0,
196         },
197
198         {       device_id:      0x1180,
199                 name:           "pci-mio-16e-1",
200                 n_adchan:       16,
201                 adbits:         12,
202                 ai_fifo_depth:  512,
203                 alwaysdither:   0,
204                 gainlkup:       ai_gain_16,
205                 ai_speed:       800,
206                 n_aochan:       2,
207                 aobits:         12,
208                 ao_fifo_depth:  2048,
209                 ao_unipolar:    1,
210                 caldac:         {mb88341},
211                 has_8255:       0,
212         },
213         {       device_id:      0x1190,
214                 name:           "pci-mio-16e-4", /* aka pci-6040e */
215                 n_adchan:       16,
216                 adbits:         12,
217                 ai_fifo_depth:  512,
218                 alwaysdither:   0,
219                 gainlkup:       ai_gain_16,
220                 ai_speed:       2000,
221                 n_aochan:       2,
222                 aobits:         12,
223                 ao_fifo_depth:  512,
224                 ao_unipolar:    1,
225                 caldac:         {mb88341},
226                 has_8255:       0,
227         },
228         {       device_id:      0x11c0,
229                 name:           "pxi-6040e",
230                 n_adchan:       16,
231                 adbits:         12,
232                 ai_fifo_depth:  512,
233                 alwaysdither:   0,
234                 gainlkup:       ai_gain_16,
235                 ai_speed:       2000,
236                 n_aochan:       2,
237                 aobits:         12,
238                 ao_fifo_depth:  512,
239                 ao_unipolar:    1,
240                 caldac:         {mb88341},
241                 has_8255:       0,
242         },
243
244         {       device_id:      0x1330,
245                 name:           "pci-6031e",
246                 n_adchan:       64,
247                 adbits:         16,
248                 ai_fifo_depth:  512,
249                 alwaysdither:   1,
250                 gainlkup:       ai_gain_14,
251                 ai_speed:       10000,
252                 n_aochan:       2,
253                 aobits:         16,
254                 ao_fifo_depth:  2048,
255                 ao_unipolar:    1,
256                 caldac:         {dac8800,dac8043,ad8522},
257                 has_8255:       0,
258         },
259         {       device_id:      0x1270,
260                 name:           "pci-6032e",
261                 n_adchan:       16,
262                 adbits:         16,
263                 ai_fifo_depth:  512,
264                 alwaysdither:   1,
265                 gainlkup:       ai_gain_14,
266                 ai_speed:       10000,
267                 n_aochan:       0,
268                 aobits:         0,
269                 ao_fifo_depth:  0,
270                 ao_unipolar:    1,
271                 caldac:         {dac8800,dac8043,ad8522},
272                 has_8255:       0,
273         },
274         {       device_id:      0x1340,
275                 name:           "pci-6033e",
276                 n_adchan:       64,
277                 adbits:         16,
278                 ai_fifo_depth:  512,
279                 alwaysdither:   1,
280                 gainlkup:       ai_gain_14,
281                 ai_speed:       10000,
282                 n_aochan:       0,
283                 aobits:         0,
284                 ao_fifo_depth:  0,
285                 ao_unipolar:    1,
286                 caldac:         {dac8800,dac8043,ad8522},
287                 has_8255:       0,
288         },
289         {       device_id:      0x1350,
290                 name:           "pci-6071e",
291                 n_adchan:       64,
292                 adbits:         12,
293                 ai_fifo_depth:  512,
294                 alwaysdither:   1,
295                 gainlkup:       ai_gain_16,
296                 ai_speed:       800,
297                 n_aochan:       2,
298                 aobits:         12,
299                 ao_fifo_depth:  2048,
300                 ao_unipolar:    1,
301                 caldac:         {mb88341},
302                 has_8255:       0,
303         },
304         {       device_id:      0x2a60,
305                 name:           "pci-6023e",
306                 n_adchan:       16,
307                 adbits:         12,
308                 ai_fifo_depth:  512,
309                 alwaysdither:   0,
310                 gainlkup:       ai_gain_4,
311                 ai_speed:       5000,
312                 n_aochan:       0,
313                 aobits:         0,
314                 ao_unipolar:    0,
315                 caldac:         {mb88341},
316                 has_8255:       0,
317         },
318         {       device_id:      0x2a70,
319                 name:           "pci-6024e",
320                 n_adchan:       16,
321                 adbits:         12,
322                 ai_fifo_depth:  512,
323                 alwaysdither:   0,
324                 gainlkup:       ai_gain_4,
325                 ai_speed:       5000,
326                 n_aochan:       2,
327                 aobits:         12,
328                 ao_fifo_depth:  0,
329                 ao_unipolar:    0,
330                 caldac:         {mb88341},
331                 has_8255:       0,
332         },
333         {       device_id:      0x2a80,
334                 name:           "pci-6025e",
335                 n_adchan:       16,
336                 adbits:         12,
337                 ai_fifo_depth:  512,
338                 alwaysdither:   0,
339                 gainlkup:       ai_gain_4,
340                 ai_speed:       5000,
341                 n_aochan:       2,
342                 aobits:         12,
343                 ao_fifo_depth:  0,
344                 ao_unipolar:    0,
345                 caldac:         {mb88341},
346                 has_8255:       1,
347         },
348         {       device_id:      0x2ab0,
349                 name:           "pxi-6025e",
350                 n_adchan:       16,
351                 adbits:         12,
352                 ai_fifo_depth:  512,
353                 alwaysdither:   0,
354                 gainlkup:       ai_gain_4,
355                 ai_speed:       5000,
356                 n_aochan:       2,
357                 aobits:         12,
358                 ao_fifo_depth:  0,
359                 ao_unipolar:    1,
360                 caldac:         {mb88341},
361                 has_8255:       1,
362         },
363
364         {       device_id:      0x2ca0,
365                 name:           "pci-6034e",
366                 n_adchan:       16,
367                 adbits:         16,
368                 ai_fifo_depth:  512,
369                 alwaysdither:   1,
370                 gainlkup:       ai_gain_4,
371                 ai_speed:       5000,
372                 n_aochan:       0,
373                 aobits:         0,
374                 ao_fifo_depth:  0,
375                 ao_unipolar:    0,
376                 caldac:         {mb88341},
377                 has_8255:       0,
378         },
379         {       device_id:      0x2c80,
380                 name:           "pci-6035e",
381                 n_adchan:       16,
382                 adbits:         16,
383                 ai_fifo_depth:  512,
384                 alwaysdither:   1,
385                 gainlkup:       ai_gain_4,
386                 ai_speed:       5000,
387                 n_aochan:       2,
388                 aobits:         12,
389                 ao_fifo_depth:  0,
390                 ao_unipolar:    0,
391                 caldac:         {mb88341},
392                 has_8255:       0,
393         },
394         {       device_id:      0x18b0,
395                 name:           "pci-6052e",
396                 n_adchan:       16,
397                 adbits:         16,
398                 ai_fifo_depth:  512,
399                 alwaysdither:   1,
400                 gainlkup:       ai_gain_16,
401                 ai_speed:       3000,
402                 n_aochan:       2,
403                 aobits:         16,
404                 ao_unipolar:    1,
405                 ao_fifo_depth:  2048,
406                 caldac:         {ad8804,mb88341,ad8522}, /* manual is wrong */
407         },
408 #if 0
409         {       device_id:      0x0000, /* unknown */
410                 name:           "pci-6053e",
411                 n_adchan:       64,
412                 adbits:         16,
413                 ai_fifo_depth:  512,
414                 alwaysdither:   1,
415                 gainlkup:       ai_gain_16,
416                 ai_speed:       3000,
417                 n_aochan:       2,
418                 aobits:         16,
419                 ao_unipolar:    1,
420                 ao_fifo_depth:  2048,
421                 caldac:         {ad8804,mb88341,ad8522}, /* manual is wrong */
422         },
423 #endif
424         {       device_id:      0x14e0,
425                 name:           "pci-6110e",
426                 n_adchan:       4, 
427                 adbits:         12,
428                 ai_fifo_depth:  8192,
429                 alwaysdither:   0,
430                 gainlkup:       ai_gain_611x,
431                 ai_speed:       200,
432                 aobits:         16,
433                 ao_671x:        1,
434                 ao_unipolar:    0,
435                 ao_fifo_depth:  2048,
436                 reg_611x:       1,
437                 caldac:         {ad8804_debug,ad8804_debug,ad8804_debug},/* XXX */
438         },
439         {       device_id:      0x14f0,
440                 name:           "pci-6111e",
441                 n_adchan:       2,
442                 adbits:         12,
443                 ai_fifo_depth:  8192,
444                 alwaysdither:   0,
445                 gainlkup:       ai_gain_611x,
446                 ai_speed:       200,
447                 n_aochan:       2,
448                 aobits:         16,
449                 ao_671x:        1,
450                 ao_unipolar:    0,
451                 ao_fifo_depth:  2048,
452                 reg_611x:       1,
453                 caldac:         {ad8804_debug,ad8804_debug,ad8804_debug},/* XXX */
454         },
455         {       device_id:      0x1880,
456                 name:           "pci-6711",
457                 n_adchan:       0, /* no analog input */
458                 n_aochan:       4,
459                 aobits:         12,
460                 ao_unipolar:    0,
461                 ao_fifo_depth:  8192,
462                 ao_671x:        1,
463                 caldac:         {mb88341,mb88341},/* XXX */
464         },
465         {       device_id:      0x1870,
466                 name:           "pci-6713",
467                 n_adchan:       0, /* no analog input */
468                 n_aochan:       8,
469                 aobits:         12,
470                 ao_unipolar:    0,
471                 ao_fifo_depth:  16384,
472                 ao_671x:        1,
473                 caldac:         {mb88341,mb88341},/* XXX */
474         },
475 #if 0
476         {       device_id:      0x1880,
477                 name:           "pci-6731",
478                 n_adchan:       0, /* no analog input */
479                 n_aochan:       4,
480                 aobits:         16,
481                 ao_unipolar:    0,
482                 ao_fifo_depth:  8192,
483                 ao_671x:        1,
484                 caldac:         {mb88341,mb88341},/* XXX */
485         },
486         {       device_id:      0x1870,
487                 name:           "pci-6733",
488                 n_adchan:       0, /* no analog input */
489                 n_aochan:       8,
490                 aobits:         16,
491                 ao_unipolar:    0,
492                 ao_fifo_depth:  16384,
493                 ao_671x:        1,
494                 caldac:         {mb88341,mb88341},/* XXX */
495         },
496 #endif
497         {       device_id:      0x15b0,
498                 name:           "pxi-6071e",
499                 n_adchan:       64,
500                 adbits:         12,
501                 ai_fifo_depth:  512,
502                 alwaysdither:   1,
503                 gainlkup:       ai_gain_16,
504                 ai_speed:       800,
505                 n_aochan:       2,
506                 aobits:         12,
507                 ao_fifo_depth:  2048,
508                 ao_unipolar:    1,
509                 caldac:         {mb88341},
510                 has_8255:       0,
511         },
512
513         {       device_id:      0x11b0,
514                 name:           "pxi-6070e",
515                 n_adchan:       16,
516                 adbits:         12,
517                 ai_fifo_depth:  512,
518                 alwaysdither:   1,
519                 gainlkup:       ai_gain_16,
520                 ai_speed:       800,
521                 n_aochan:       2,
522                 aobits:         12,
523                 ao_fifo_depth:  2048,
524                 ao_unipolar:    1,
525                 caldac:         {mb88341},
526                 has_8255:       0,
527         },
528         {       device_id:      0x18c0,
529                 name:           "pxi-6052e",
530                 n_adchan:       16,
531                 adbits:         16,
532                 ai_fifo_depth:  512,
533                 alwaysdither:   1,
534                 gainlkup:       ai_gain_16,
535                 ai_speed:       3000,
536                 n_aochan:       2,
537                 aobits:         16,
538                 ao_unipolar:    1,
539                 ao_fifo_depth:  2048,
540                 caldac:         {mb88341,mb88341,ad8522},
541         },
542         {       device_id:      0x1580,
543                 name:           "pxi-6031e",
544                 n_adchan:       64,
545                 adbits:         16,
546                 ai_fifo_depth:  512,
547                 alwaysdither:   1,
548                 gainlkup:       ai_gain_14,
549                 ai_speed:       10000,
550                 n_aochan:       2,
551                 aobits:         16,
552                 ao_fifo_depth:  2048,
553                 ao_unipolar:    1,
554                 caldac:         {dac8800,dac8043,ad8522},
555         },
556         {       device_id:      0x2890,
557                 name:           "pci-6036e",
558                 n_adchan:       16,
559                 adbits:         16,
560                 ai_fifo_depth:  512,
561                 alwaysdither:   1,
562                 gainlkup:       ai_gain_4,
563                 ai_speed:       5000,
564                 n_aochan:       2,
565                 aobits:         16,
566                 ao_fifo_depth:  0,
567                 ao_unipolar:    0,
568                 caldac:         {mb88341},
569                 has_8255:       0,
570         },
571 };
572 #define n_pcimio_boards ((sizeof(ni_boards)/sizeof(ni_boards[0])))
573
574 static int pcimio_attach(comedi_device *dev,comedi_devconfig *it);
575 static int pcimio_detach(comedi_device *dev);
576 static comedi_driver driver_pcimio={
577         driver_name:    "ni_pcimio",
578         module:         THIS_MODULE,
579         attach:         pcimio_attach,
580         detach:         pcimio_detach,
581 };
582 COMEDI_INITCLEANUP(driver_pcimio);
583
584
585 /* How we access registers */
586
587 #define ni_writew(a,b)          (writew((a),dev->iobase+(b)))
588 #define ni_readw(a)             (readw(dev->iobase+(a)))
589 #define ni_writeb(a,b)          (writeb((a),dev->iobase+(b)))
590 #define ni_readb(a)             (readb(dev->iobase+(a)))
591
592 /* How we access STC registers */
593
594 /* We automatically take advantage of STC registers that can be
595  * read/written directly in the I/O space of the board.  Most
596  * PCIMIO devices map the low 8 STC registers to iobase+addr*2.
597  * The 611x devices map the write registers to iobase+addr*2, and
598  * the read registers to iobase+(addr-1)*2. */
599
600 #define win_out(data,addr) do{ \
601         if((addr)<8){ \
602                 ni_writew((data),(addr)*2); \
603         }else{ \
604                 ni_writew((addr),Window_Address); \
605                 ni_writew((data),Window_Data); \
606         } \
607 }while(0)
608
609 #define win_out2(data,addr) do{ \
610         win_out((data)>>16, (addr)); \
611         win_out((data)&0xffff, (addr)+1); \
612 }while(0)
613
614 #define win_in(addr) ( \
615         ((addr)<7) \
616         ? (ni_readw(((addr) - boardtype.reg_611x)*2)) \
617         : (ni_writew((addr),Window_Address),ni_readw(Window_Data)))
618
619 #define win_save() (ni_readw(Window_Address))
620 #define win_restore(a) (ni_writew((a),Window_Address))
621
622 #define ao_win_out(a,b) do{ \
623         ni_writew((b),AO_Window_Address_671x); \
624         ni_writew((a),AO_Window_Data_671x); \
625 }while(0)
626
627
628
629 #define interrupt_pin(a)        0
630 #define IRQ_POLARITY 1
631
632 #define NI_E_IRQ_FLAGS          SA_SHIRQ
633
634
635 typedef struct{
636         struct mite_struct *mite;
637
638         NI_PRIVATE_COMMON
639         
640         dma_addr_t ai_dma_handle;
641 }ni_private;
642 #define devpriv ((ni_private *)dev->private)
643
644
645 #include "ni_mio_common.c"
646
647
648 static int pcimio_find_device(comedi_device *dev,int bus,int slot);
649 static int pcimio_ai_alloc(comedi_device *dev, comedi_subdevice *s,
650         unsigned long new_size);
651
652
653 /* cleans up allocated resources */
654 static int pcimio_detach(comedi_device *dev)
655 {
656         mio_common_detach(dev);
657
658         if(dev->private && devpriv->mite)
659                 mite_unsetup(devpriv->mite);
660         
661         if(dev->irq){
662                 comedi_free_irq(dev->irq,dev);
663         }
664
665         return 0;
666 }
667
668 static int pcimio_attach(comedi_device *dev,comedi_devconfig *it)
669 {
670         int             ret;
671         
672         printk("comedi%d: ni_pcimio:",dev->minor);
673         
674         ret=alloc_private(dev,sizeof(ni_private));
675         if(ret<0)return ret;
676
677         ret=pcimio_find_device(dev,it->options[0],it->options[1]);
678         if(ret<0)return ret;
679
680         printk(" %s",boardtype.name);
681         dev->board_name=boardtype.name;
682         
683         ret = mite_setup(devpriv->mite);
684         if(ret < 0)
685         {
686                 printk(" error setting up mite\n");
687                 return ret;
688         }
689         dev->iobase = mite_iobase(devpriv->mite);
690
691         dev->irq=mite_irq(devpriv->mite);
692
693         if(dev->irq==0){
694                 printk(" unknown irq (bad)\n");
695         }else{
696                 printk(" ( irq = %d )",dev->irq);
697                 if( (ret=comedi_request_irq(dev->irq,ni_E_interrupt,NI_E_IRQ_FLAGS,"ni_pcimio",dev))<0 ){
698                         printk(" irq not available\n");
699                         dev->irq=0;
700                 }
701         }
702
703         ret = ni_E_init(dev,it);
704         if(ret<0)return ret;
705
706         dev->subdevices[0].buf_alloc = pcimio_ai_alloc;
707
708         return ret;
709 }
710
711
712 static int pcimio_find_device(comedi_device *dev,int bus,int slot)
713 {
714         struct mite_struct *mite;
715         int i;
716
717         for(mite=mite_devices;mite;mite=mite->next){
718                 if(mite->used)continue;
719                 if(bus || slot){
720                         if(bus!=mite->pcidev->bus->number ||
721                            slot!=PCI_SLOT(mite->pcidev->devfn))
722                                 continue;
723                 }
724
725                 for(i=0;i<n_pcimio_boards;i++){
726                         if(mite_device_id(mite)==ni_boards[i].device_id){
727                                 dev->board_ptr=ni_boards+i;
728                                 devpriv->mite=mite;
729
730                                 return 0;
731                         }
732                 }
733         }
734         printk("no device found\n");
735         mite_list_devices();
736         return -EIO;
737 }
738
739 /* This needs to be fixed before it can be used for AO, since it
740  * uses devpriv->ai_dma_handle */
741 static int pcimio_ai_alloc(comedi_device *dev, comedi_subdevice *s,
742         unsigned long new_size)
743 {
744         int ret;
745
746         ret = mite_buf_alloc(devpriv->mite, s->async, new_size);
747         if(ret<0)return ret;
748
749         return 0;
750 #if 0
751         comedi_async *async = s->async;
752
753         if(async->prealloc_buf && async->prealloc_bufsz == new_size){
754                 return 0;
755         }
756
757         if(async->prealloc_bufsz){
758                 pci_free_consistent(devpriv->mite->pcidev,
759                         async->prealloc_bufsz, async->prealloc_buf,
760                         devpriv->ai_dma_handle);
761                 async->prealloc_buf = NULL;
762                 async->prealloc_bufsz = 0;
763         }
764
765         if(new_size){
766                 async->prealloc_buf = pci_alloc_consistent(devpriv->mite->pcidev,
767                         new_size, &devpriv->ai_dma_handle);
768                 if(async->prealloc_buf == NULL){
769                         async->prealloc_bufsz = 0;
770                         return -ENOMEM;
771                 }
772         }
773         async->prealloc_bufsz = new_size;
774
775         return 0;
776 #endif
777 }
778
779