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