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