]> Pileus Git - ~andy/linux/blob - drivers/staging/comedi/drivers/addi_apci_3xxx.c
67be74ed52ad0a16c7fb43dd8cb85000fb4fbcc6
[~andy/linux] / drivers / staging / comedi / drivers / addi_apci_3xxx.c
1 #include <linux/pci.h>
2
3 #include "../comedidev.h"
4 #include "comedi_fc.h"
5 #include "amcc_s5933.h"
6
7 #include "addi-data/addi_common.h"
8
9 #include "addi-data/addi_eeprom.c"
10 #include "addi-data/hwdrv_apci3xxx.c"
11
12 #ifndef COMEDI_SUBD_TTLIO
13 #define COMEDI_SUBD_TTLIO   11  /* Digital Input Output But TTL */
14 #endif
15
16 enum apci3xxx_boardid {
17         BOARD_APCI3000_16,
18         BOARD_APCI3000_8,
19         BOARD_APCI3000_4,
20         BOARD_APCI3006_16,
21         BOARD_APCI3006_8,
22         BOARD_APCI3006_4,
23         BOARD_APCI3010_16,
24         BOARD_APCI3010_8,
25         BOARD_APCI3010_4,
26         BOARD_APCI3016_16,
27         BOARD_APCI3016_8,
28         BOARD_APCI3016_4,
29         BOARD_APCI3100_16_4,
30         BOARD_APCI3100_8_4,
31         BOARD_APCI3106_16_4,
32         BOARD_APCI3106_8_4,
33         BOARD_APCI3110_16_4,
34         BOARD_APCI3110_8_4,
35         BOARD_APCI3116_16_4,
36         BOARD_APCI3116_8_4,
37         BOARD_APCI3003,
38         BOARD_APCI3002_16,
39         BOARD_APCI3002_8,
40         BOARD_APCI3002_4,
41         BOARD_APCI3500,
42 };
43
44 static const struct addi_board apci3xxx_boardtypes[] = {
45         [BOARD_APCI3000_16] = {
46                 .pc_DriverName          = "apci3000-16",
47                 .i_IorangeBase1         = 256,
48                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
49                 .pc_EepromChip          = ADDIDATA_9054,
50                 .i_NbrAiChannel         = 16,
51                 .i_NbrAiChannelDiff     = 8,
52                 .i_AiChannelList        = 16,
53                 .i_AiMaxdata            = 4095,
54                 .pr_AiRangelist         = &range_apci3XXX_ai,
55                 .i_NbrTTLChannel        = 24,
56                 .b_AvailableConvertUnit = 6,
57                 .ui_MinAcquisitiontimeNs = 10000,
58                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
59                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
60                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
61                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
62                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
63                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
64         },
65         [BOARD_APCI3000_8] = {
66                 .pc_DriverName          = "apci3000-8",
67                 .i_IorangeBase1         = 256,
68                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
69                 .pc_EepromChip          = ADDIDATA_9054,
70                 .i_NbrAiChannel         = 8,
71                 .i_NbrAiChannelDiff     = 4,
72                 .i_AiChannelList        = 8,
73                 .i_AiMaxdata            = 4095,
74                 .pr_AiRangelist         = &range_apci3XXX_ai,
75                 .i_NbrTTLChannel        = 24,
76                 .b_AvailableConvertUnit = 6,
77                 .ui_MinAcquisitiontimeNs = 10000,
78                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
79                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
80                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
81                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
82                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
83                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
84         },
85         [BOARD_APCI3000_4] = {
86                 .pc_DriverName          = "apci3000-4",
87                 .i_IorangeBase1         = 256,
88                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
89                 .pc_EepromChip          = ADDIDATA_9054,
90                 .i_NbrAiChannel         = 4,
91                 .i_NbrAiChannelDiff     = 2,
92                 .i_AiChannelList        = 4,
93                 .i_AiMaxdata            = 4095,
94                 .pr_AiRangelist         = &range_apci3XXX_ai,
95                 .i_NbrTTLChannel        = 24,
96                 .b_AvailableConvertUnit = 6,
97                 .ui_MinAcquisitiontimeNs = 10000,
98                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
99                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
100                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
101                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
102                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
103                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
104         },
105         [BOARD_APCI3006_16] = {
106                 .pc_DriverName          = "apci3006-16",
107                 .i_IorangeBase1         = 256,
108                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
109                 .pc_EepromChip          = ADDIDATA_9054,
110                 .i_NbrAiChannel         = 16,
111                 .i_NbrAiChannelDiff     = 8,
112                 .i_AiChannelList        = 16,
113                 .i_AiMaxdata            = 65535,
114                 .pr_AiRangelist         = &range_apci3XXX_ai,
115                 .i_NbrTTLChannel        = 24,
116                 .b_AvailableConvertUnit = 6,
117                 .ui_MinAcquisitiontimeNs = 10000,
118                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
119                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
120                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
121                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
122                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
123                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
124         },
125         [BOARD_APCI3006_8] = {
126                 .pc_DriverName          = "apci3006-8",
127                 .i_IorangeBase1         = 256,
128                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
129                 .pc_EepromChip          = ADDIDATA_9054,
130                 .i_NbrAiChannel         = 8,
131                 .i_NbrAiChannelDiff     = 4,
132                 .i_AiChannelList        = 8,
133                 .i_AiMaxdata            = 65535,
134                 .pr_AiRangelist         = &range_apci3XXX_ai,
135                 .i_NbrTTLChannel        = 24,
136                 .b_AvailableConvertUnit = 6,
137                 .ui_MinAcquisitiontimeNs = 10000,
138                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
139                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
140                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
141                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
142                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
143                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
144         },
145         [BOARD_APCI3006_4] = {
146                 .pc_DriverName          = "apci3006-4",
147                 .i_IorangeBase1         = 256,
148                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
149                 .pc_EepromChip          = ADDIDATA_9054,
150                 .i_NbrAiChannel         = 4,
151                 .i_NbrAiChannelDiff     = 2,
152                 .i_AiChannelList        = 4,
153                 .i_AiMaxdata            = 65535,
154                 .pr_AiRangelist         = &range_apci3XXX_ai,
155                 .i_NbrTTLChannel        = 24,
156                 .b_AvailableConvertUnit = 6,
157                 .ui_MinAcquisitiontimeNs = 10000,
158                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
159                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
160                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
161                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
162                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
163                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
164         },
165         [BOARD_APCI3010_16] = {
166                 .pc_DriverName          = "apci3010-16",
167                 .i_IorangeBase1         = 256,
168                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
169                 .pc_EepromChip          = ADDIDATA_9054,
170                 .i_NbrAiChannel         = 16,
171                 .i_NbrAiChannelDiff     = 8,
172                 .i_AiChannelList        = 16,
173                 .i_AiMaxdata            = 4095,
174                 .pr_AiRangelist         = &range_apci3XXX_ai,
175                 .i_NbrDiChannel         = 4,
176                 .i_NbrDoChannel         = 4,
177                 .i_DoMaxdata            = 1,
178                 .i_NbrTTLChannel        = 24,
179                 .b_AvailableConvertUnit = 6,
180                 .ui_MinAcquisitiontimeNs = 5000,
181                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
182                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
183                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
184                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
185                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
186                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
187         },
188         [BOARD_APCI3010_8] = {
189                 .pc_DriverName          = "apci3010-8",
190                 .i_IorangeBase1         = 256,
191                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
192                 .pc_EepromChip          = ADDIDATA_9054,
193                 .i_NbrAiChannel         = 8,
194                 .i_NbrAiChannelDiff     = 4,
195                 .i_AiChannelList        = 8,
196                 .i_AiMaxdata            = 4095,
197                 .pr_AiRangelist         = &range_apci3XXX_ai,
198                 .i_NbrDiChannel         = 4,
199                 .i_NbrDoChannel         = 4,
200                 .i_DoMaxdata            = 1,
201                 .i_NbrTTLChannel        = 24,
202                 .b_AvailableConvertUnit = 6,
203                 .ui_MinAcquisitiontimeNs = 5000,
204                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
205                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
206                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
207                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
208                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
209                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
210         },
211         [BOARD_APCI3010_4] = {
212                 .pc_DriverName          = "apci3010-4",
213                 .i_IorangeBase1         = 256,
214                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
215                 .pc_EepromChip          = ADDIDATA_9054,
216                 .i_NbrAiChannel         = 4,
217                 .i_NbrAiChannelDiff     = 2,
218                 .i_AiChannelList        = 4,
219                 .i_AiMaxdata            = 4095,
220                 .pr_AiRangelist         = &range_apci3XXX_ai,
221                 .i_NbrDiChannel         = 4,
222                 .i_NbrDoChannel         = 4,
223                 .i_DoMaxdata            = 1,
224                 .i_NbrTTLChannel        = 24,
225                 .b_AvailableConvertUnit = 6,
226                 .ui_MinAcquisitiontimeNs = 5000,
227                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
228                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
229                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
230                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
231                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
232                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
233         },
234         [BOARD_APCI3016_16] = {
235                 .pc_DriverName          = "apci3016-16",
236                 .i_IorangeBase1         = 256,
237                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
238                 .pc_EepromChip          = ADDIDATA_9054,
239                 .i_NbrAiChannel         = 16,
240                 .i_NbrAiChannelDiff     = 8,
241                 .i_AiChannelList        = 16,
242                 .i_AiMaxdata            = 65535,
243                 .pr_AiRangelist         = &range_apci3XXX_ai,
244                 .i_NbrDiChannel         = 4,
245                 .i_NbrDoChannel         = 4,
246                 .i_DoMaxdata            = 1,
247                 .i_NbrTTLChannel        = 24,
248                 .b_AvailableConvertUnit = 6,
249                 .ui_MinAcquisitiontimeNs = 5000,
250                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
251                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
252                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
253                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
254                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
255                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
256         },
257         [BOARD_APCI3016_8] = {
258                 .pc_DriverName          = "apci3016-8",
259                 .i_IorangeBase1         = 256,
260                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
261                 .pc_EepromChip          = ADDIDATA_9054,
262                 .i_NbrAiChannel         = 8,
263                 .i_NbrAiChannelDiff     = 4,
264                 .i_AiChannelList        = 8,
265                 .i_AiMaxdata            = 65535,
266                 .pr_AiRangelist         = &range_apci3XXX_ai,
267                 .i_NbrDiChannel         = 4,
268                 .i_NbrDoChannel         = 4,
269                 .i_DoMaxdata            = 1,
270                 .i_NbrTTLChannel        = 24,
271                 .b_AvailableConvertUnit = 6,
272                 .ui_MinAcquisitiontimeNs = 5000,
273                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
274                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
275                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
276                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
277                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
278                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
279         },
280         [BOARD_APCI3016_4] = {
281                 .pc_DriverName          = "apci3016-4",
282                 .i_IorangeBase1         = 256,
283                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
284                 .pc_EepromChip          = ADDIDATA_9054,
285                 .i_NbrAiChannel         = 4,
286                 .i_NbrAiChannelDiff     = 2,
287                 .i_AiChannelList        = 4,
288                 .i_AiMaxdata            = 65535,
289                 .pr_AiRangelist         = &range_apci3XXX_ai,
290                 .i_NbrDiChannel         = 4,
291                 .i_NbrDoChannel         = 4,
292                 .i_DoMaxdata            = 1,
293                 .i_NbrTTLChannel        = 24,
294                 .b_AvailableConvertUnit = 6,
295                 .ui_MinAcquisitiontimeNs = 5000,
296                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
297                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
298                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
299                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
300                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
301                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
302         },
303         [BOARD_APCI3100_16_4] = {
304                 .pc_DriverName          = "apci3100-16-4",
305                 .i_IorangeBase1         = 256,
306                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
307                 .pc_EepromChip          = ADDIDATA_9054,
308                 .i_NbrAiChannel         = 16,
309                 .i_NbrAiChannelDiff     = 8,
310                 .i_AiChannelList        = 16,
311                 .i_NbrAoChannel         = 4,
312                 .i_AiMaxdata            = 4095,
313                 .i_AoMaxdata            = 4095,
314                 .pr_AiRangelist         = &range_apci3XXX_ai,
315                 .pr_AoRangelist         = &range_apci3XXX_ao,
316                 .i_NbrTTLChannel        = 24,
317                 .b_AvailableConvertUnit = 6,
318                 .ui_MinAcquisitiontimeNs = 10000,
319                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
320                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
321                 .ao_write               = i_APCI3XXX_InsnWriteAnalogOutput,
322                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
323                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
324                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
325                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
326         },
327         [BOARD_APCI3100_8_4] = {
328                 .pc_DriverName          = "apci3100-8-4",
329                 .i_IorangeBase1         = 256,
330                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
331                 .pc_EepromChip          = ADDIDATA_9054,
332                 .i_NbrAiChannel         = 8,
333                 .i_NbrAiChannelDiff     = 4,
334                 .i_AiChannelList        = 8,
335                 .i_NbrAoChannel         = 4,
336                 .i_AiMaxdata            = 4095,
337                 .i_AoMaxdata            = 4095,
338                 .pr_AiRangelist         = &range_apci3XXX_ai,
339                 .pr_AoRangelist         = &range_apci3XXX_ao,
340                 .i_NbrTTLChannel        = 24,
341                 .b_AvailableConvertUnit = 6,
342                 .ui_MinAcquisitiontimeNs = 10000,
343                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
344                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
345                 .ao_write               = i_APCI3XXX_InsnWriteAnalogOutput,
346                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
347                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
348                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
349                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
350         },
351         [BOARD_APCI3106_16_4] = {
352                 .pc_DriverName          = "apci3106-16-4",
353                 .i_IorangeBase1         = 256,
354                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
355                 .pc_EepromChip          = ADDIDATA_9054,
356                 .i_NbrAiChannel         = 16,
357                 .i_NbrAiChannelDiff     = 8,
358                 .i_AiChannelList        = 16,
359                 .i_NbrAoChannel         = 4,
360                 .i_AiMaxdata            = 65535,
361                 .i_AoMaxdata            = 4095,
362                 .pr_AiRangelist         = &range_apci3XXX_ai,
363                 .pr_AoRangelist         = &range_apci3XXX_ao,
364                 .i_NbrTTLChannel        = 24,
365                 .b_AvailableConvertUnit = 6,
366                 .ui_MinAcquisitiontimeNs = 10000,
367                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
368                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
369                 .ao_write               = i_APCI3XXX_InsnWriteAnalogOutput,
370                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
371                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
372                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
373                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
374         },
375         [BOARD_APCI3106_8_4] = {
376                 .pc_DriverName          = "apci3106-8-4",
377                 .i_IorangeBase1         = 256,
378                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
379                 .pc_EepromChip          = ADDIDATA_9054,
380                 .i_NbrAiChannel         = 8,
381                 .i_NbrAiChannelDiff     = 4,
382                 .i_AiChannelList        = 8,
383                 .i_NbrAoChannel         = 4,
384                 .i_AiMaxdata            = 65535,
385                 .i_AoMaxdata            = 4095,
386                 .pr_AiRangelist         = &range_apci3XXX_ai,
387                 .pr_AoRangelist         = &range_apci3XXX_ao,
388                 .i_NbrTTLChannel        = 24,
389                 .b_AvailableConvertUnit = 6,
390                 .ui_MinAcquisitiontimeNs = 10000,
391                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
392                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
393                 .ao_write               = i_APCI3XXX_InsnWriteAnalogOutput,
394                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
395                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
396                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
397                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
398         },
399         [BOARD_APCI3110_16_4] = {
400                 .pc_DriverName          = "apci3110-16-4",
401                 .i_IorangeBase1         = 256,
402                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
403                 .pc_EepromChip          = ADDIDATA_9054,
404                 .i_NbrAiChannel         = 16,
405                 .i_NbrAiChannelDiff     = 8,
406                 .i_AiChannelList        = 16,
407                 .i_NbrAoChannel         = 4,
408                 .i_AiMaxdata            = 4095,
409                 .i_AoMaxdata            = 4095,
410                 .pr_AiRangelist         = &range_apci3XXX_ai,
411                 .pr_AoRangelist         = &range_apci3XXX_ao,
412                 .i_NbrDiChannel         = 4,
413                 .i_NbrDoChannel         = 4,
414                 .i_DoMaxdata            = 1,
415                 .i_NbrTTLChannel        = 24,
416                 .b_AvailableConvertUnit = 6,
417                 .ui_MinAcquisitiontimeNs = 5000,
418                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
419                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
420                 .ao_write               = i_APCI3XXX_InsnWriteAnalogOutput,
421                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
422                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
423                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
424                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
425         },
426         [BOARD_APCI3110_8_4] = {
427                 .pc_DriverName          = "apci3110-8-4",
428                 .i_IorangeBase1         = 256,
429                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
430                 .pc_EepromChip          = ADDIDATA_9054,
431                 .i_NbrAiChannel         = 8,
432                 .i_NbrAiChannelDiff     = 4,
433                 .i_AiChannelList        = 8,
434                 .i_NbrAoChannel         = 4,
435                 .i_AiMaxdata            = 4095,
436                 .i_AoMaxdata            = 4095,
437                 .pr_AiRangelist         = &range_apci3XXX_ai,
438                 .pr_AoRangelist         = &range_apci3XXX_ao,
439                 .i_NbrDiChannel         = 4,
440                 .i_NbrDoChannel         = 4,
441                 .i_DoMaxdata            = 1,
442                 .i_NbrTTLChannel        = 24,
443                 .b_AvailableConvertUnit = 6,
444                 .ui_MinAcquisitiontimeNs = 5000,
445                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
446                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
447                 .ao_write               = i_APCI3XXX_InsnWriteAnalogOutput,
448                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
449                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
450                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
451                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
452         },
453         [BOARD_APCI3116_16_4] = {
454                 .pc_DriverName          = "apci3116-16-4",
455                 .i_IorangeBase1         = 256,
456                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
457                 .pc_EepromChip          = ADDIDATA_9054,
458                 .i_NbrAiChannel         = 16,
459                 .i_NbrAiChannelDiff     = 8,
460                 .i_AiChannelList        = 16,
461                 .i_NbrAoChannel         = 4,
462                 .i_AiMaxdata            = 65535,
463                 .i_AoMaxdata            = 4095,
464                 .pr_AiRangelist         = &range_apci3XXX_ai,
465                 .pr_AoRangelist         = &range_apci3XXX_ao,
466                 .i_NbrDiChannel         = 4,
467                 .i_NbrDoChannel         = 4,
468                 .i_DoMaxdata            = 1,
469                 .i_NbrTTLChannel        = 24,
470                 .b_AvailableConvertUnit = 6,
471                 .ui_MinAcquisitiontimeNs = 5000,
472                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
473                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
474                 .ao_write               = i_APCI3XXX_InsnWriteAnalogOutput,
475                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
476                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
477                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
478                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
479         },
480         [BOARD_APCI3116_8_4] = {
481                 .pc_DriverName          = "apci3116-8-4",
482                 .i_IorangeBase1         = 256,
483                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
484                 .pc_EepromChip          = ADDIDATA_9054,
485                 .i_NbrAiChannel         = 8,
486                 .i_NbrAiChannelDiff     = 4,
487                 .i_AiChannelList        = 8,
488                 .i_NbrAoChannel         = 4,
489                 .i_AiMaxdata            = 65535,
490                 .i_AoMaxdata            = 4095,
491                 .pr_AiRangelist         = &range_apci3XXX_ai,
492                 .pr_AoRangelist         = &range_apci3XXX_ao,
493                 .i_NbrDiChannel         = 4,
494                 .i_NbrDoChannel         = 4,
495                 .i_DoMaxdata            = 1,
496                 .i_NbrTTLChannel        = 24,
497                 .b_AvailableConvertUnit = 6,
498                 .ui_MinAcquisitiontimeNs = 5000,
499                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
500                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
501                 .ao_write               = i_APCI3XXX_InsnWriteAnalogOutput,
502                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
503                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
504                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
505                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
506         },
507         [BOARD_APCI3003] = {
508                 .pc_DriverName          = "apci3003",
509                 .i_IorangeBase1         = 256,
510                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
511                 .pc_EepromChip          = ADDIDATA_9054,
512                 .i_NbrAiChannelDiff     = 4,
513                 .i_AiChannelList        = 4,
514                 .i_AiMaxdata            = 65535,
515                 .pr_AiRangelist         = &range_apci3XXX_ai,
516                 .i_NbrDiChannel         = 4,
517                 .i_NbrDoChannel         = 4,
518                 .i_DoMaxdata            = 1,
519                 .b_AvailableConvertUnit = 7,
520                 .ui_MinAcquisitiontimeNs = 2500,
521                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
522                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
523         },
524         [BOARD_APCI3002_16] = {
525                 .pc_DriverName          = "apci3002-16",
526                 .i_IorangeBase1         = 256,
527                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
528                 .pc_EepromChip          = ADDIDATA_9054,
529                 .i_NbrAiChannelDiff     = 16,
530                 .i_AiChannelList        = 16,
531                 .i_AiMaxdata            = 65535,
532                 .pr_AiRangelist         = &range_apci3XXX_ai,
533                 .i_NbrDiChannel         = 4,
534                 .i_NbrDoChannel         = 4,
535                 .i_DoMaxdata            = 1,
536                 .b_AvailableConvertUnit = 6,
537                 .ui_MinAcquisitiontimeNs = 5000,
538                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
539                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
540         },
541         [BOARD_APCI3002_8] = {
542                 .pc_DriverName          = "apci3002-8",
543                 .i_IorangeBase1         = 256,
544                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
545                 .pc_EepromChip          = ADDIDATA_9054,
546                 .i_NbrAiChannelDiff     = 8,
547                 .i_AiChannelList        = 8,
548                 .i_AiMaxdata            = 65535,
549                 .pr_AiRangelist         = &range_apci3XXX_ai,
550                 .i_NbrDiChannel         = 4,
551                 .i_NbrDoChannel         = 4,
552                 .i_DoMaxdata            = 1,
553                 .b_AvailableConvertUnit = 6,
554                 .ui_MinAcquisitiontimeNs = 5000,
555                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
556                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
557         },
558         [BOARD_APCI3002_4] = {
559                 .pc_DriverName          = "apci3002-4",
560                 .i_IorangeBase1         = 256,
561                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
562                 .pc_EepromChip          = ADDIDATA_9054,
563                 .i_NbrAiChannelDiff     = 4,
564                 .i_AiChannelList        = 4,
565                 .i_AiMaxdata            = 65535,
566                 .pr_AiRangelist         = &range_apci3XXX_ai,
567                 .i_NbrDiChannel         = 4,
568                 .i_NbrDoChannel         = 4,
569                 .i_DoMaxdata            = 1,
570                 .b_AvailableConvertUnit = 6,
571                 .ui_MinAcquisitiontimeNs = 5000,
572                 .ai_config              = i_APCI3XXX_InsnConfigAnalogInput,
573                 .ai_read                = i_APCI3XXX_InsnReadAnalogInput,
574         },
575         [BOARD_APCI3500] = {
576                 .pc_DriverName          = "apci3500",
577                 .i_IorangeBase1         = 256,
578                 .i_PCIEeprom            = ADDIDATA_NO_EEPROM,
579                 .pc_EepromChip          = ADDIDATA_9054,
580                 .i_NbrAoChannel         = 4,
581                 .i_AoMaxdata            = 4095,
582                 .pr_AoRangelist         = &range_apci3XXX_ao,
583                 .i_NbrTTLChannel        = 24,
584                 .ao_write               = i_APCI3XXX_InsnWriteAnalogOutput,
585                 .ttl_config             = i_APCI3XXX_InsnConfigInitTTLIO,
586                 .ttl_bits               = i_APCI3XXX_InsnBitsTTLIO,
587                 .ttl_read               = i_APCI3XXX_InsnReadTTLIO,
588                 .ttl_write              = i_APCI3XXX_InsnWriteTTLIO,
589         },
590 };
591
592 static irqreturn_t apci3xxx_irq_handler(int irq, void *d)
593 {
594         struct comedi_device *dev = d;
595         struct addi_private *devpriv = dev->private;
596         unsigned int status;
597         int i;
598
599         /* Test if interrupt occur */
600         status = readl(devpriv->dw_AiBase + 16);
601         if ((status & 0x2) == 0x2) {
602                 /* Reset the interrupt */
603                 writel(status, devpriv->dw_AiBase + 16);
604
605                 /* Test if interrupt enabled */
606                 if (devpriv->b_EocEosInterrupt == 1) {
607                         /* Read all analog inputs value */
608                         for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) {
609                                 unsigned int val;
610
611                                 val = readl(devpriv->dw_AiBase + 28);
612                                 devpriv->ui_AiReadData[i] = val;
613                         }
614
615                         /* Set the interrupt flag */
616                         devpriv->b_EocEosInterrupt = 2;
617
618                         /* Send a signal to from kernel to user space */
619                         send_sig(SIGIO, devpriv->tsk_Current, 0);
620                 }
621         }
622         return IRQ_RETVAL(1);
623 }
624
625 static int apci3xxx_di_insn_bits(struct comedi_device *dev,
626                                  struct comedi_subdevice *s,
627                                  struct comedi_insn *insn,
628                                  unsigned int *data)
629 {
630         struct addi_private *devpriv = dev->private;
631
632         data[1] = inl(devpriv->iobase + 32) & 0xf;
633
634         return insn->n;
635 }
636
637 static int apci3xxx_do_insn_bits(struct comedi_device *dev,
638                                  struct comedi_subdevice *s,
639                                  struct comedi_insn *insn,
640                                  unsigned int *data)
641 {
642         struct addi_private *devpriv = dev->private;
643         unsigned int mask = data[0];
644         unsigned int bits = data[1];
645
646         s->state = inl(devpriv->iobase + 48) & 0xf;
647         if (mask) {
648                 s->state &= ~mask;
649                 s->state |= (bits & mask);
650
651                 outl(s->state, devpriv->iobase + 48);
652         }
653
654         data[1] = s->state;
655
656         return insn->n;
657 }
658
659 static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,
660                                      struct comedi_subdevice *s,
661                                      struct comedi_insn *insn,
662                                      unsigned int *data)
663 {
664         const struct addi_board *this_board = comedi_board(dev);
665         struct addi_private *devpriv = dev->private;
666         unsigned short w_Address = CR_CHAN(insn->chanspec);
667         unsigned short w_Data;
668
669         w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc,
670                 this_board->pc_EepromChip, 2 * w_Address);
671         data[0] = w_Data;
672
673         return insn->n;
674 }
675
676 static int apci3xxx_reset(struct comedi_device *dev)
677 {
678         struct addi_private *devpriv = dev->private;
679         unsigned int val;
680         int i;
681
682         /* Disable the interrupt */
683         disable_irq(dev->irq);
684
685         /* Reset the interrupt flag */
686         devpriv->b_EocEosInterrupt = 0;
687
688         /* Clear the start command */
689         writel(0, devpriv->dw_AiBase + 8);
690
691         /* Reset the interrupt flags */
692         val = readl(devpriv->dw_AiBase + 16);
693         writel(val, devpriv->dw_AiBase + 16);
694
695         /* clear the EOS */
696         readl(devpriv->dw_AiBase + 20);
697
698         /* Clear the FIFO */
699         for (i = 0; i < 16; i++)
700                 val = readl(devpriv->dw_AiBase + 28);
701
702         /* Enable the interrupt */
703         enable_irq(dev->irq);
704
705         return 0;
706 }
707
708 static int apci3xxx_auto_attach(struct comedi_device *dev,
709                                 unsigned long context)
710 {
711         struct pci_dev *pcidev = comedi_to_pci_dev(dev);
712         const struct addi_board *board = NULL;
713         struct addi_private *devpriv;
714         struct comedi_subdevice *s;
715         int ret, n_subdevices;
716         unsigned int dw_Dummy;
717
718         if (context < ARRAY_SIZE(apci3xxx_boardtypes))
719                 board = &apci3xxx_boardtypes[context];
720         if (!board)
721                 return -ENODEV;
722         dev->board_ptr = board;
723         dev->board_name = board->pc_DriverName;
724
725         devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
726         if (!devpriv)
727                 return -ENOMEM;
728         dev->private = devpriv;
729
730         ret = comedi_pci_enable(dev);
731         if (ret)
732                 return ret;
733
734         if (!board->pc_EepromChip ||
735             strcmp(board->pc_EepromChip, ADDIDATA_9054)) {
736                 /* board does not have an eeprom or is not ADDIDATA_9054 */
737                 if (board->i_IorangeBase1)
738                         dev->iobase = pci_resource_start(pcidev, 1);
739                 else
740                         dev->iobase = pci_resource_start(pcidev, 0);
741
742                 devpriv->iobase = dev->iobase;
743                 devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
744                 devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
745         } else {
746                 /* board has an ADDIDATA_9054 eeprom */
747                 dev->iobase = pci_resource_start(pcidev, 2);
748                 devpriv->iobase = pci_resource_start(pcidev, 2);
749                 devpriv->dw_AiBase = pci_ioremap_bar(pcidev, 3);
750         }
751         devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
752
753         /* Initialize parameters that can be overridden in EEPROM */
754         devpriv->s_EeParameters.i_NbrAiChannel = board->i_NbrAiChannel;
755         devpriv->s_EeParameters.i_NbrAoChannel = board->i_NbrAoChannel;
756         devpriv->s_EeParameters.i_AiMaxdata = board->i_AiMaxdata;
757         devpriv->s_EeParameters.i_AoMaxdata = board->i_AoMaxdata;
758         devpriv->s_EeParameters.i_NbrDiChannel = board->i_NbrDiChannel;
759         devpriv->s_EeParameters.i_NbrDoChannel = board->i_NbrDoChannel;
760         devpriv->s_EeParameters.i_DoMaxdata = board->i_DoMaxdata;
761         devpriv->s_EeParameters.i_Dma = board->i_Dma;
762         devpriv->s_EeParameters.i_Timer = board->i_Timer;
763         devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
764                                                 board->ui_MinAcquisitiontimeNs;
765         devpriv->s_EeParameters.ui_MinDelaytimeNs = board->ui_MinDelaytimeNs;
766
767         /* ## */
768
769         if (pcidev->irq > 0) {
770                 ret = request_irq(pcidev->irq, apci3xxx_irq_handler,
771                                   IRQF_SHARED, dev->board_name, dev);
772                 if (ret == 0)
773                         dev->irq = pcidev->irq;
774         }
775
776         /*  Read eepeom and fill addi_board Structure */
777
778         if (board->i_PCIEeprom) {
779                 if (!(strcmp(board->pc_EepromChip, "S5920"))) {
780                         /*  Set 3 wait stait */
781                         if (!(strcmp(dev->board_name, "apci035")))
782                                 outl(0x80808082, devpriv->i_IobaseAmcc + 0x60);
783                         else
784                                 outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
785
786                         /*  Enable the interrupt for the controller */
787                         dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
788                         outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
789                 }
790                 addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0));
791         }
792
793         n_subdevices = 7;
794         ret = comedi_alloc_subdevices(dev, n_subdevices);
795         if (ret)
796                 return ret;
797
798         /*  Allocate and Initialise AI Subdevice Structures */
799         s = &dev->subdevices[0];
800         if (devpriv->s_EeParameters.i_NbrAiChannel ||
801             board->i_NbrAiChannelDiff) {
802                 dev->read_subdev = s;
803                 s->type = COMEDI_SUBD_AI;
804                 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND |
805                                   SDF_DIFF;
806                 if (devpriv->s_EeParameters.i_NbrAiChannel) {
807                         s->n_chan = devpriv->s_EeParameters.i_NbrAiChannel;
808                         devpriv->b_SingelDiff = 0;
809                 } else {
810                         s->n_chan = board->i_NbrAiChannelDiff;
811                         devpriv->b_SingelDiff = 1;
812                 }
813                 s->maxdata = devpriv->s_EeParameters.i_AiMaxdata;
814                 s->len_chanlist = board->i_AiChannelList;
815                 s->range_table = board->pr_AiRangelist;
816
817                 /* Set the initialisation flag */
818                 devpriv->b_AiInitialisation = 1;
819
820                 s->insn_config = board->ai_config;
821                 s->insn_read = board->ai_read;
822                 s->insn_write = board->ai_write;
823                 s->insn_bits = board->ai_bits;
824                 s->do_cmdtest = board->ai_cmdtest;
825                 s->do_cmd = board->ai_cmd;
826                 s->cancel = board->ai_cancel;
827
828         } else {
829                 s->type = COMEDI_SUBD_UNUSED;
830         }
831
832         /*  Allocate and Initialise AO Subdevice Structures */
833         s = &dev->subdevices[1];
834         if (devpriv->s_EeParameters.i_NbrAoChannel) {
835                 s->type = COMEDI_SUBD_AO;
836                 s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
837                 s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel;
838                 s->maxdata = devpriv->s_EeParameters.i_AoMaxdata;
839                 s->len_chanlist = devpriv->s_EeParameters.i_NbrAoChannel;
840                 s->range_table = board->pr_AoRangelist;
841                 s->insn_config = board->ao_config;
842                 s->insn_write = board->ao_write;
843         } else {
844                 s->type = COMEDI_SUBD_UNUSED;
845         }
846         /*  Allocate and Initialise DI Subdevice Structures */
847         s = &dev->subdevices[2];
848         if (devpriv->s_EeParameters.i_NbrDiChannel) {
849                 s->type = COMEDI_SUBD_DI;
850                 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
851                 s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel;
852                 s->maxdata = 1;
853                 s->len_chanlist = devpriv->s_EeParameters.i_NbrDiChannel;
854                 s->range_table = &range_digital;
855                 s->io_bits = 0; /* all bits input */
856                 s->insn_bits = apci3xxx_di_insn_bits;
857         } else {
858                 s->type = COMEDI_SUBD_UNUSED;
859         }
860         /*  Allocate and Initialise DO Subdevice Structures */
861         s = &dev->subdevices[3];
862         if (devpriv->s_EeParameters.i_NbrDoChannel) {
863                 s->type = COMEDI_SUBD_DO;
864                 s->subdev_flags =
865                         SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
866                 s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel;
867                 s->maxdata = devpriv->s_EeParameters.i_DoMaxdata;
868                 s->len_chanlist = devpriv->s_EeParameters.i_NbrDoChannel;
869                 s->range_table = &range_digital;
870                 s->io_bits = 0xf;       /* all bits output */
871                 s->insn_bits = apci3xxx_do_insn_bits;
872         } else {
873                 s->type = COMEDI_SUBD_UNUSED;
874         }
875
876         /*  Allocate and Initialise Timer Subdevice Structures */
877         s = &dev->subdevices[4];
878         if (devpriv->s_EeParameters.i_Timer) {
879                 s->type = COMEDI_SUBD_TIMER;
880                 s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
881                 s->n_chan = 1;
882                 s->maxdata = 0;
883                 s->len_chanlist = 1;
884                 s->range_table = &range_digital;
885
886                 s->insn_write = board->timer_write;
887                 s->insn_read = board->timer_read;
888                 s->insn_config = board->timer_config;
889                 s->insn_bits = board->timer_bits;
890         } else {
891                 s->type = COMEDI_SUBD_UNUSED;
892         }
893
894         /*  Allocate and Initialise TTL */
895         s = &dev->subdevices[5];
896         if (board->i_NbrTTLChannel) {
897                 s->type = COMEDI_SUBD_TTLIO;
898                 s->subdev_flags =
899                         SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
900                 s->n_chan = board->i_NbrTTLChannel;
901                 s->maxdata = 1;
902                 s->io_bits = 0; /* all bits input */
903                 s->len_chanlist = board->i_NbrTTLChannel;
904                 s->range_table = &range_digital;
905                 s->insn_config = board->ttl_config;
906                 s->insn_bits = board->ttl_bits;
907                 s->insn_read = board->ttl_read;
908                 s->insn_write = board->ttl_write;
909         } else {
910                 s->type = COMEDI_SUBD_UNUSED;
911         }
912
913         /* EEPROM */
914         s = &dev->subdevices[6];
915         if (board->i_PCIEeprom) {
916                 s->type = COMEDI_SUBD_MEMORY;
917                 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
918                 s->n_chan = 256;
919                 s->maxdata = 0xffff;
920                 s->insn_read = i_ADDIDATA_InsnReadEeprom;
921         } else {
922                 s->type = COMEDI_SUBD_UNUSED;
923         }
924
925         apci3xxx_reset(dev);
926         return 0;
927 }
928
929 static void apci3xxx_detach(struct comedi_device *dev)
930 {
931         struct addi_private *devpriv = dev->private;
932
933         if (devpriv) {
934                 if (dev->iobase)
935                         apci3xxx_reset(dev);
936                 if (dev->irq)
937                         free_irq(dev->irq, dev);
938                 if (devpriv->dw_AiBase)
939                         iounmap(devpriv->dw_AiBase);
940         }
941         comedi_pci_disable(dev);
942 }
943
944 static struct comedi_driver apci3xxx_driver = {
945         .driver_name    = "addi_apci_3xxx",
946         .module         = THIS_MODULE,
947         .auto_attach    = apci3xxx_auto_attach,
948         .detach         = apci3xxx_detach,
949 };
950
951 static int apci3xxx_pci_probe(struct pci_dev *dev,
952                               const struct pci_device_id *id)
953 {
954         return comedi_pci_auto_config(dev, &apci3xxx_driver, id->driver_data);
955 }
956
957 static DEFINE_PCI_DEVICE_TABLE(apci3xxx_pci_table) = {
958         { PCI_VDEVICE(ADDIDATA, 0x3010), BOARD_APCI3000_16 },
959         { PCI_VDEVICE(ADDIDATA, 0x300f), BOARD_APCI3000_8 },
960         { PCI_VDEVICE(ADDIDATA, 0x300e), BOARD_APCI3000_4 },
961         { PCI_VDEVICE(ADDIDATA, 0x3013), BOARD_APCI3006_16 },
962         { PCI_VDEVICE(ADDIDATA, 0x3014), BOARD_APCI3006_8 },
963         { PCI_VDEVICE(ADDIDATA, 0x3015), BOARD_APCI3006_4 },
964         { PCI_VDEVICE(ADDIDATA, 0x3016), BOARD_APCI3010_16 },
965         { PCI_VDEVICE(ADDIDATA, 0x3017), BOARD_APCI3010_8 },
966         { PCI_VDEVICE(ADDIDATA, 0x3018), BOARD_APCI3010_4 },
967         { PCI_VDEVICE(ADDIDATA, 0x3019), BOARD_APCI3016_16 },
968         { PCI_VDEVICE(ADDIDATA, 0x301a), BOARD_APCI3016_8 },
969         { PCI_VDEVICE(ADDIDATA, 0x301b), BOARD_APCI3016_4 },
970         { PCI_VDEVICE(ADDIDATA, 0x301c), BOARD_APCI3100_16_4 },
971         { PCI_VDEVICE(ADDIDATA, 0x301d), BOARD_APCI3100_8_4 },
972         { PCI_VDEVICE(ADDIDATA, 0x301e), BOARD_APCI3106_16_4 },
973         { PCI_VDEVICE(ADDIDATA, 0x301f), BOARD_APCI3106_8_4 },
974         { PCI_VDEVICE(ADDIDATA, 0x3020), BOARD_APCI3110_16_4 },
975         { PCI_VDEVICE(ADDIDATA, 0x3021), BOARD_APCI3110_8_4 },
976         { PCI_VDEVICE(ADDIDATA, 0x3022), BOARD_APCI3116_16_4 },
977         { PCI_VDEVICE(ADDIDATA, 0x3023), BOARD_APCI3116_8_4 },
978         { PCI_VDEVICE(ADDIDATA, 0x300B), BOARD_APCI3003 },
979         { PCI_VDEVICE(ADDIDATA, 0x3002), BOARD_APCI3002_16 },
980         { PCI_VDEVICE(ADDIDATA, 0x3003), BOARD_APCI3002_8 },
981         { PCI_VDEVICE(ADDIDATA, 0x3004), BOARD_APCI3002_4 },
982         { PCI_VDEVICE(ADDIDATA, 0x3024), BOARD_APCI3500 },
983         { 0 }
984 };
985 MODULE_DEVICE_TABLE(pci, apci3xxx_pci_table);
986
987 static struct pci_driver apci3xxx_pci_driver = {
988         .name           = "addi_apci_3xxx",
989         .id_table       = apci3xxx_pci_table,
990         .probe          = apci3xxx_pci_probe,
991         .remove         = comedi_pci_auto_unconfig,
992 };
993 module_comedi_pci_driver(apci3xxx_driver, apci3xxx_pci_driver);
994
995 MODULE_AUTHOR("Comedi http://www.comedi.org");
996 MODULE_DESCRIPTION("Comedi low-level driver");
997 MODULE_LICENSE("GPL");