1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * me4000.c 4 * Source code for the Meilhaus ME-4000 board family. 5 * 6 * COMEDI - Linux Control and Measurement Device Interface 7 * Copyright (C) 2000 David A. Schleef <ds@schleef.org> 8 */ 9 10 /* 11 * Driver: me4000 12 * Description: Meilhaus ME-4000 series boards 13 * Devices: [Meilhaus] ME-4650 (me4000), ME-4670i, ME-4680, ME-4680i, 14 * ME-4680is 15 * Author: gg (Guenter Gebhardt <g.gebhardt@meilhaus.com>) 16 * Updated: Mon, 18 Mar 2002 15:34:01 -0800 17 * Status: untested 18 * 19 * Supports: 20 * - Analog Input 21 * - Analog Output 22 * - Digital I/O 23 * - Counter 24 * 25 * Configuration Options: not applicable, uses PCI auto config 26 * 27 * The firmware required by these boards is available in the 28 * comedi_nonfree_firmware tarball available from 29 * https://www.comedi.org. 30 */ 31 32 #include <linux/module.h> 33 #include <linux/delay.h> 34 #include <linux/interrupt.h> 35 #include <linux/comedi/comedi_pci.h> 36 #include <linux/comedi/comedi_8254.h> 37 38 #include "plx9052.h" 39 40 #define ME4000_FIRMWARE "me4000_firmware.bin" 41 42 /* 43 * ME4000 Register map and bit defines 44 */ 45 #define ME4000_AO_CHAN(x) ((x) * 0x18) 46 47 #define ME4000_AO_CTRL_REG(x) (0x00 + ME4000_AO_CHAN(x)) 48 #define ME4000_AO_CTRL_MODE_0 BIT(0) 49 #define ME4000_AO_CTRL_MODE_1 BIT(1) 50 #define ME4000_AO_CTRL_STOP BIT(2) 51 #define ME4000_AO_CTRL_ENABLE_FIFO BIT(3) 52 #define ME4000_AO_CTRL_ENABLE_EX_TRIG BIT(4) 53 #define ME4000_AO_CTRL_EX_TRIG_EDGE BIT(5) 54 #define ME4000_AO_CTRL_IMMEDIATE_STOP BIT(7) 55 #define ME4000_AO_CTRL_ENABLE_DO BIT(8) 56 #define ME4000_AO_CTRL_ENABLE_IRQ BIT(9) 57 #define ME4000_AO_CTRL_RESET_IRQ BIT(10) 58 #define ME4000_AO_STATUS_REG(x) (0x04 + ME4000_AO_CHAN(x)) 59 #define ME4000_AO_STATUS_FSM BIT(0) 60 #define ME4000_AO_STATUS_FF BIT(1) 61 #define ME4000_AO_STATUS_HF BIT(2) 62 #define ME4000_AO_STATUS_EF BIT(3) 63 #define ME4000_AO_FIFO_REG(x) (0x08 + ME4000_AO_CHAN(x)) 64 #define ME4000_AO_SINGLE_REG(x) (0x0c + ME4000_AO_CHAN(x)) 65 #define ME4000_AO_TIMER_REG(x) (0x10 + ME4000_AO_CHAN(x)) 66 #define ME4000_AI_CTRL_REG 0x74 67 #define ME4000_AI_STATUS_REG 0x74 68 #define ME4000_AI_CTRL_MODE_0 BIT(0) 69 #define ME4000_AI_CTRL_MODE_1 BIT(1) 70 #define ME4000_AI_CTRL_MODE_2 BIT(2) 71 #define ME4000_AI_CTRL_SAMPLE_HOLD BIT(3) 72 #define ME4000_AI_CTRL_IMMEDIATE_STOP BIT(4) 73 #define ME4000_AI_CTRL_STOP BIT(5) 74 #define ME4000_AI_CTRL_CHANNEL_FIFO BIT(6) 75 #define ME4000_AI_CTRL_DATA_FIFO BIT(7) 76 #define ME4000_AI_CTRL_FULLSCALE BIT(8) 77 #define ME4000_AI_CTRL_OFFSET BIT(9) 78 #define ME4000_AI_CTRL_EX_TRIG_ANALOG BIT(10) 79 #define ME4000_AI_CTRL_EX_TRIG BIT(11) 80 #define ME4000_AI_CTRL_EX_TRIG_FALLING BIT(12) 81 #define ME4000_AI_CTRL_EX_IRQ BIT(13) 82 #define ME4000_AI_CTRL_EX_IRQ_RESET BIT(14) 83 #define ME4000_AI_CTRL_LE_IRQ BIT(15) 84 #define ME4000_AI_CTRL_LE_IRQ_RESET BIT(16) 85 #define ME4000_AI_CTRL_HF_IRQ BIT(17) 86 #define ME4000_AI_CTRL_HF_IRQ_RESET BIT(18) 87 #define ME4000_AI_CTRL_SC_IRQ BIT(19) 88 #define ME4000_AI_CTRL_SC_IRQ_RESET BIT(20) 89 #define ME4000_AI_CTRL_SC_RELOAD BIT(21) 90 #define ME4000_AI_STATUS_EF_CHANNEL BIT(22) 91 #define ME4000_AI_STATUS_HF_CHANNEL BIT(23) 92 #define ME4000_AI_STATUS_FF_CHANNEL BIT(24) 93 #define ME4000_AI_STATUS_EF_DATA BIT(25) 94 #define ME4000_AI_STATUS_HF_DATA BIT(26) 95 #define ME4000_AI_STATUS_FF_DATA BIT(27) 96 #define ME4000_AI_STATUS_LE BIT(28) 97 #define ME4000_AI_STATUS_FSM BIT(29) 98 #define ME4000_AI_CTRL_EX_TRIG_BOTH BIT(31) 99 #define ME4000_AI_CHANNEL_LIST_REG 0x78 100 #define ME4000_AI_LIST_INPUT_DIFFERENTIAL BIT(5) 101 #define ME4000_AI_LIST_RANGE(x) ((3 - ((x) & 3)) << 6) 102 #define ME4000_AI_LIST_LAST_ENTRY BIT(8) 103 #define ME4000_AI_DATA_REG 0x7c 104 #define ME4000_AI_CHAN_TIMER_REG 0x80 105 #define ME4000_AI_CHAN_PRE_TIMER_REG 0x84 106 #define ME4000_AI_SCAN_TIMER_LOW_REG 0x88 107 #define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8c 108 #define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90 109 #define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94 110 #define ME4000_AI_START_REG 0x98 111 #define ME4000_IRQ_STATUS_REG 0x9c 112 #define ME4000_IRQ_STATUS_EX BIT(0) 113 #define ME4000_IRQ_STATUS_LE BIT(1) 114 #define ME4000_IRQ_STATUS_AI_HF BIT(2) 115 #define ME4000_IRQ_STATUS_AO_0_HF BIT(3) 116 #define ME4000_IRQ_STATUS_AO_1_HF BIT(4) 117 #define ME4000_IRQ_STATUS_AO_2_HF BIT(5) 118 #define ME4000_IRQ_STATUS_AO_3_HF BIT(6) 119 #define ME4000_IRQ_STATUS_SC BIT(7) 120 #define ME4000_DIO_PORT_0_REG 0xa0 121 #define ME4000_DIO_PORT_1_REG 0xa4 122 #define ME4000_DIO_PORT_2_REG 0xa8 123 #define ME4000_DIO_PORT_3_REG 0xac 124 #define ME4000_DIO_DIR_REG 0xb0 125 #define ME4000_AO_LOADSETREG_XX 0xb4 126 #define ME4000_DIO_CTRL_REG 0xb8 127 #define ME4000_DIO_CTRL_MODE_0 BIT(0) 128 #define ME4000_DIO_CTRL_MODE_1 BIT(1) 129 #define ME4000_DIO_CTRL_MODE_2 BIT(2) 130 #define ME4000_DIO_CTRL_MODE_3 BIT(3) 131 #define ME4000_DIO_CTRL_MODE_4 BIT(4) 132 #define ME4000_DIO_CTRL_MODE_5 BIT(5) 133 #define ME4000_DIO_CTRL_MODE_6 BIT(6) 134 #define ME4000_DIO_CTRL_MODE_7 BIT(7) 135 #define ME4000_DIO_CTRL_FUNCTION_0 BIT(8) 136 #define ME4000_DIO_CTRL_FUNCTION_1 BIT(9) 137 #define ME4000_DIO_CTRL_FIFO_HIGH_0 BIT(10) 138 #define ME4000_DIO_CTRL_FIFO_HIGH_1 BIT(11) 139 #define ME4000_DIO_CTRL_FIFO_HIGH_2 BIT(12) 140 #define ME4000_DIO_CTRL_FIFO_HIGH_3 BIT(13) 141 #define ME4000_AO_DEMUX_ADJUST_REG 0xbc 142 #define ME4000_AO_DEMUX_ADJUST_VALUE 0x4c 143 #define ME4000_AI_SAMPLE_COUNTER_REG 0xc0 144 145 #define ME4000_AI_FIFO_COUNT 2048 146 147 #define ME4000_AI_MIN_TICKS 66 148 #define ME4000_AI_MIN_SAMPLE_TIME 2000 149 150 #define ME4000_AI_CHANNEL_LIST_COUNT 1024 151 152 struct me4000_private { 153 unsigned long plx_regbase; 154 unsigned int ai_ctrl_mode; 155 unsigned int ai_init_ticks; 156 unsigned int ai_scan_ticks; 157 unsigned int ai_chan_ticks; 158 }; 159 160 enum me4000_boardid { 161 BOARD_ME4650, 162 BOARD_ME4660, 163 BOARD_ME4660I, 164 BOARD_ME4660S, 165 BOARD_ME4660IS, 166 BOARD_ME4670, 167 BOARD_ME4670I, 168 BOARD_ME4670S, 169 BOARD_ME4670IS, 170 BOARD_ME4680, 171 BOARD_ME4680I, 172 BOARD_ME4680S, 173 BOARD_ME4680IS, 174 }; 175 176 struct me4000_board { 177 const char *name; 178 int ai_nchan; 179 unsigned int can_do_diff_ai:1; 180 unsigned int can_do_sh_ai:1; /* sample & hold (8 channels) */ 181 unsigned int ex_trig_analog:1; 182 unsigned int has_ao:1; 183 unsigned int has_ao_fifo:1; 184 unsigned int has_counter:1; 185 }; 186 187 static const struct me4000_board me4000_boards[] = { 188 [BOARD_ME4650] = { 189 .name = "ME-4650", 190 .ai_nchan = 16, 191 }, 192 [BOARD_ME4660] = { 193 .name = "ME-4660", 194 .ai_nchan = 32, 195 .can_do_diff_ai = 1, 196 .has_counter = 1, 197 }, 198 [BOARD_ME4660I] = { 199 .name = "ME-4660i", 200 .ai_nchan = 32, 201 .can_do_diff_ai = 1, 202 .has_counter = 1, 203 }, 204 [BOARD_ME4660S] = { 205 .name = "ME-4660s", 206 .ai_nchan = 32, 207 .can_do_diff_ai = 1, 208 .can_do_sh_ai = 1, 209 .has_counter = 1, 210 }, 211 [BOARD_ME4660IS] = { 212 .name = "ME-4660is", 213 .ai_nchan = 32, 214 .can_do_diff_ai = 1, 215 .can_do_sh_ai = 1, 216 .has_counter = 1, 217 }, 218 [BOARD_ME4670] = { 219 .name = "ME-4670", 220 .ai_nchan = 32, 221 .can_do_diff_ai = 1, 222 .ex_trig_analog = 1, 223 .has_ao = 1, 224 .has_counter = 1, 225 }, 226 [BOARD_ME4670I] = { 227 .name = "ME-4670i", 228 .ai_nchan = 32, 229 .can_do_diff_ai = 1, 230 .ex_trig_analog = 1, 231 .has_ao = 1, 232 .has_counter = 1, 233 }, 234 [BOARD_ME4670S] = { 235 .name = "ME-4670s", 236 .ai_nchan = 32, 237 .can_do_diff_ai = 1, 238 .can_do_sh_ai = 1, 239 .ex_trig_analog = 1, 240 .has_ao = 1, 241 .has_counter = 1, 242 }, 243 [BOARD_ME4670IS] = { 244 .name = "ME-4670is", 245 .ai_nchan = 32, 246 .can_do_diff_ai = 1, 247 .can_do_sh_ai = 1, 248 .ex_trig_analog = 1, 249 .has_ao = 1, 250 .has_counter = 1, 251 }, 252 [BOARD_ME4680] = { 253 .name = "ME-4680", 254 .ai_nchan = 32, 255 .can_do_diff_ai = 1, 256 .ex_trig_analog = 1, 257 .has_ao = 1, 258 .has_ao_fifo = 1, 259 .has_counter = 1, 260 }, 261 [BOARD_ME4680I] = { 262 .name = "ME-4680i", 263 .ai_nchan = 32, 264 .can_do_diff_ai = 1, 265 .ex_trig_analog = 1, 266 .has_ao = 1, 267 .has_ao_fifo = 1, 268 .has_counter = 1, 269 }, 270 [BOARD_ME4680S] = { 271 .name = "ME-4680s", 272 .ai_nchan = 32, 273 .can_do_diff_ai = 1, 274 .can_do_sh_ai = 1, 275 .ex_trig_analog = 1, 276 .has_ao = 1, 277 .has_ao_fifo = 1, 278 .has_counter = 1, 279 }, 280 [BOARD_ME4680IS] = { 281 .name = "ME-4680is", 282 .ai_nchan = 32, 283 .can_do_diff_ai = 1, 284 .can_do_sh_ai = 1, 285 .ex_trig_analog = 1, 286 .has_ao = 1, 287 .has_ao_fifo = 1, 288 .has_counter = 1, 289 }, 290 }; 291 292 /* 293 * NOTE: the ranges here are inverted compared to the values 294 * written to the ME4000_AI_CHANNEL_LIST_REG, 295 * 296 * The ME4000_AI_LIST_RANGE() macro handles the inversion. 297 */ 298 static const struct comedi_lrange me4000_ai_range = { 299 4, { 300 UNI_RANGE(2.5), 301 UNI_RANGE(10), 302 BIP_RANGE(2.5), 303 BIP_RANGE(10) 304 } 305 }; 306 307 static int me4000_xilinx_download(struct comedi_device *dev, 308 const u8 *data, size_t size, 309 unsigned long context) 310 { 311 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 312 struct me4000_private *devpriv = dev->private; 313 unsigned long xilinx_iobase = pci_resource_start(pcidev, 5); 314 unsigned int file_length; 315 unsigned int val; 316 unsigned int i; 317 318 if (!xilinx_iobase) 319 return -ENODEV; 320 321 /* 322 * Set PLX local interrupt 2 polarity to high. 323 * Interrupt is thrown by init pin of xilinx. 324 */ 325 outl(PLX9052_INTCSR_LI2POL, devpriv->plx_regbase + PLX9052_INTCSR); 326 327 /* Set /CS and /WRITE of the Xilinx */ 328 val = inl(devpriv->plx_regbase + PLX9052_CNTRL); 329 val |= PLX9052_CNTRL_UIO2_DATA; 330 outl(val, devpriv->plx_regbase + PLX9052_CNTRL); 331 332 /* Init Xilinx with CS1 */ 333 inb(xilinx_iobase + 0xC8); 334 335 /* Wait until /INIT pin is set */ 336 usleep_range(20, 1000); 337 val = inl(devpriv->plx_regbase + PLX9052_INTCSR); 338 if (!(val & PLX9052_INTCSR_LI2STAT)) { 339 dev_err(dev->class_dev, "Can't init Xilinx\n"); 340 return -EIO; 341 } 342 343 /* Reset /CS and /WRITE of the Xilinx */ 344 val = inl(devpriv->plx_regbase + PLX9052_CNTRL); 345 val &= ~PLX9052_CNTRL_UIO2_DATA; 346 outl(val, devpriv->plx_regbase + PLX9052_CNTRL); 347 348 /* Download Xilinx firmware */ 349 file_length = (((unsigned int)data[0] & 0xff) << 24) + 350 (((unsigned int)data[1] & 0xff) << 16) + 351 (((unsigned int)data[2] & 0xff) << 8) + 352 ((unsigned int)data[3] & 0xff); 353 usleep_range(10, 1000); 354 355 for (i = 0; i < file_length; i++) { 356 outb(data[16 + i], xilinx_iobase); 357 usleep_range(10, 1000); 358 359 /* Check if BUSY flag is low */ 360 val = inl(devpriv->plx_regbase + PLX9052_CNTRL); 361 if (val & PLX9052_CNTRL_UIO1_DATA) { 362 dev_err(dev->class_dev, 363 "Xilinx is still busy (i = %d)\n", i); 364 return -EIO; 365 } 366 } 367 368 /* If done flag is high download was successful */ 369 val = inl(devpriv->plx_regbase + PLX9052_CNTRL); 370 if (!(val & PLX9052_CNTRL_UIO0_DATA)) { 371 dev_err(dev->class_dev, "DONE flag is not set\n"); 372 dev_err(dev->class_dev, "Download not successful\n"); 373 return -EIO; 374 } 375 376 /* Set /CS and /WRITE */ 377 val = inl(devpriv->plx_regbase + PLX9052_CNTRL); 378 val |= PLX9052_CNTRL_UIO2_DATA; 379 outl(val, devpriv->plx_regbase + PLX9052_CNTRL); 380 381 return 0; 382 } 383 384 static void me4000_ai_reset(struct comedi_device *dev) 385 { 386 unsigned int ctrl; 387 388 /* Stop any running conversion */ 389 ctrl = inl(dev->iobase + ME4000_AI_CTRL_REG); 390 ctrl |= ME4000_AI_CTRL_STOP | ME4000_AI_CTRL_IMMEDIATE_STOP; 391 outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG); 392 393 /* Clear the control register */ 394 outl(0x0, dev->iobase + ME4000_AI_CTRL_REG); 395 } 396 397 static void me4000_reset(struct comedi_device *dev) 398 { 399 struct me4000_private *devpriv = dev->private; 400 unsigned int val; 401 int chan; 402 403 /* Disable interrupts on the PLX */ 404 outl(0, devpriv->plx_regbase + PLX9052_INTCSR); 405 406 /* Software reset the PLX */ 407 val = inl(devpriv->plx_regbase + PLX9052_CNTRL); 408 val |= PLX9052_CNTRL_PCI_RESET; 409 outl(val, devpriv->plx_regbase + PLX9052_CNTRL); 410 val &= ~PLX9052_CNTRL_PCI_RESET; 411 outl(val, devpriv->plx_regbase + PLX9052_CNTRL); 412 413 /* 0x8000 to the DACs means an output voltage of 0V */ 414 for (chan = 0; chan < 4; chan++) 415 outl(0x8000, dev->iobase + ME4000_AO_SINGLE_REG(chan)); 416 417 me4000_ai_reset(dev); 418 419 /* Set both stop bits in the analog output control register */ 420 val = ME4000_AO_CTRL_IMMEDIATE_STOP | ME4000_AO_CTRL_STOP; 421 for (chan = 0; chan < 4; chan++) 422 outl(val, dev->iobase + ME4000_AO_CTRL_REG(chan)); 423 424 /* Set the adustment register for AO demux */ 425 outl(ME4000_AO_DEMUX_ADJUST_VALUE, 426 dev->iobase + ME4000_AO_DEMUX_ADJUST_REG); 427 428 /* 429 * Set digital I/O direction for port 0 430 * to output on isolated versions 431 */ 432 if (!(inl(dev->iobase + ME4000_DIO_DIR_REG) & 0x1)) 433 outl(0x1, dev->iobase + ME4000_DIO_CTRL_REG); 434 } 435 436 static unsigned int me4000_ai_get_sample(struct comedi_device *dev, 437 struct comedi_subdevice *s) 438 { 439 unsigned int val; 440 441 /* read two's complement value and munge to offset binary */ 442 val = inl(dev->iobase + ME4000_AI_DATA_REG); 443 return comedi_offset_munge(s, val); 444 } 445 446 static int me4000_ai_eoc(struct comedi_device *dev, 447 struct comedi_subdevice *s, 448 struct comedi_insn *insn, 449 unsigned long context) 450 { 451 unsigned int status; 452 453 status = inl(dev->iobase + ME4000_AI_STATUS_REG); 454 if (status & ME4000_AI_STATUS_EF_DATA) 455 return 0; 456 return -EBUSY; 457 } 458 459 static int me4000_ai_insn_read(struct comedi_device *dev, 460 struct comedi_subdevice *s, 461 struct comedi_insn *insn, 462 unsigned int *data) 463 { 464 unsigned int chan = CR_CHAN(insn->chanspec); 465 unsigned int range = CR_RANGE(insn->chanspec); 466 unsigned int aref = CR_AREF(insn->chanspec); 467 unsigned int entry; 468 int ret = 0; 469 int i; 470 471 entry = chan | ME4000_AI_LIST_RANGE(range); 472 if (aref == AREF_DIFF) { 473 if (!(s->subdev_flags & SDF_DIFF)) { 474 dev_err(dev->class_dev, 475 "Differential inputs are not available\n"); 476 return -EINVAL; 477 } 478 479 if (!comedi_range_is_bipolar(s, range)) { 480 dev_err(dev->class_dev, 481 "Range must be bipolar when aref = diff\n"); 482 return -EINVAL; 483 } 484 485 if (chan >= (s->n_chan / 2)) { 486 dev_err(dev->class_dev, 487 "Analog input is not available\n"); 488 return -EINVAL; 489 } 490 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL; 491 } 492 493 entry |= ME4000_AI_LIST_LAST_ENTRY; 494 495 /* Enable channel list and data fifo for single acquisition mode */ 496 outl(ME4000_AI_CTRL_CHANNEL_FIFO | ME4000_AI_CTRL_DATA_FIFO, 497 dev->iobase + ME4000_AI_CTRL_REG); 498 499 /* Generate channel list entry */ 500 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG); 501 502 /* Set the timer to maximum sample rate */ 503 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_TIMER_REG); 504 outl(ME4000_AI_MIN_TICKS, dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG); 505 506 for (i = 0; i < insn->n; i++) { 507 unsigned int val; 508 509 /* start conversion by dummy read */ 510 inl(dev->iobase + ME4000_AI_START_REG); 511 512 ret = comedi_timeout(dev, s, insn, me4000_ai_eoc, 0); 513 if (ret) 514 break; 515 516 val = me4000_ai_get_sample(dev, s); 517 data[i] = comedi_offset_munge(s, val); 518 } 519 520 me4000_ai_reset(dev); 521 522 return ret ? ret : insn->n; 523 } 524 525 static int me4000_ai_cancel(struct comedi_device *dev, 526 struct comedi_subdevice *s) 527 { 528 me4000_ai_reset(dev); 529 530 return 0; 531 } 532 533 static int me4000_ai_check_chanlist(struct comedi_device *dev, 534 struct comedi_subdevice *s, 535 struct comedi_cmd *cmd) 536 { 537 unsigned int aref0 = CR_AREF(cmd->chanlist[0]); 538 int i; 539 540 for (i = 0; i < cmd->chanlist_len; i++) { 541 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 542 unsigned int range = CR_RANGE(cmd->chanlist[i]); 543 unsigned int aref = CR_AREF(cmd->chanlist[i]); 544 545 if (aref != aref0) { 546 dev_dbg(dev->class_dev, 547 "Mode is not equal for all entries\n"); 548 return -EINVAL; 549 } 550 551 if (aref == AREF_DIFF) { 552 if (!(s->subdev_flags & SDF_DIFF)) { 553 dev_err(dev->class_dev, 554 "Differential inputs are not available\n"); 555 return -EINVAL; 556 } 557 558 if (chan >= (s->n_chan / 2)) { 559 dev_dbg(dev->class_dev, 560 "Channel number to high\n"); 561 return -EINVAL; 562 } 563 564 if (!comedi_range_is_bipolar(s, range)) { 565 dev_dbg(dev->class_dev, 566 "Bipolar is not selected in differential mode\n"); 567 return -EINVAL; 568 } 569 } 570 } 571 572 return 0; 573 } 574 575 static void me4000_ai_round_cmd_args(struct comedi_device *dev, 576 struct comedi_subdevice *s, 577 struct comedi_cmd *cmd) 578 { 579 struct me4000_private *devpriv = dev->private; 580 int rest; 581 582 devpriv->ai_init_ticks = 0; 583 devpriv->ai_scan_ticks = 0; 584 devpriv->ai_chan_ticks = 0; 585 586 if (cmd->start_arg) { 587 devpriv->ai_init_ticks = (cmd->start_arg * 33) / 1000; 588 rest = (cmd->start_arg * 33) % 1000; 589 590 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) { 591 if (rest > 33) 592 devpriv->ai_init_ticks++; 593 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) { 594 if (rest) 595 devpriv->ai_init_ticks++; 596 } 597 } 598 599 if (cmd->scan_begin_arg) { 600 devpriv->ai_scan_ticks = (cmd->scan_begin_arg * 33) / 1000; 601 rest = (cmd->scan_begin_arg * 33) % 1000; 602 603 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) { 604 if (rest > 33) 605 devpriv->ai_scan_ticks++; 606 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) { 607 if (rest) 608 devpriv->ai_scan_ticks++; 609 } 610 } 611 612 if (cmd->convert_arg) { 613 devpriv->ai_chan_ticks = (cmd->convert_arg * 33) / 1000; 614 rest = (cmd->convert_arg * 33) % 1000; 615 616 if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_NEAREST) { 617 if (rest > 33) 618 devpriv->ai_chan_ticks++; 619 } else if ((cmd->flags & CMDF_ROUND_MASK) == CMDF_ROUND_UP) { 620 if (rest) 621 devpriv->ai_chan_ticks++; 622 } 623 } 624 } 625 626 static void me4000_ai_write_chanlist(struct comedi_device *dev, 627 struct comedi_subdevice *s, 628 struct comedi_cmd *cmd) 629 { 630 int i; 631 632 for (i = 0; i < cmd->chanlist_len; i++) { 633 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 634 unsigned int range = CR_RANGE(cmd->chanlist[i]); 635 unsigned int aref = CR_AREF(cmd->chanlist[i]); 636 unsigned int entry; 637 638 entry = chan | ME4000_AI_LIST_RANGE(range); 639 640 if (aref == AREF_DIFF) 641 entry |= ME4000_AI_LIST_INPUT_DIFFERENTIAL; 642 643 if (i == (cmd->chanlist_len - 1)) 644 entry |= ME4000_AI_LIST_LAST_ENTRY; 645 646 outl(entry, dev->iobase + ME4000_AI_CHANNEL_LIST_REG); 647 } 648 } 649 650 static int me4000_ai_do_cmd(struct comedi_device *dev, 651 struct comedi_subdevice *s) 652 { 653 struct me4000_private *devpriv = dev->private; 654 struct comedi_cmd *cmd = &s->async->cmd; 655 unsigned int ctrl; 656 657 /* Write timer arguments */ 658 outl(devpriv->ai_init_ticks - 1, 659 dev->iobase + ME4000_AI_SCAN_PRE_TIMER_LOW_REG); 660 outl(0x0, dev->iobase + ME4000_AI_SCAN_PRE_TIMER_HIGH_REG); 661 662 if (devpriv->ai_scan_ticks) { 663 outl(devpriv->ai_scan_ticks - 1, 664 dev->iobase + ME4000_AI_SCAN_TIMER_LOW_REG); 665 outl(0x0, dev->iobase + ME4000_AI_SCAN_TIMER_HIGH_REG); 666 } 667 668 outl(devpriv->ai_chan_ticks - 1, 669 dev->iobase + ME4000_AI_CHAN_PRE_TIMER_REG); 670 outl(devpriv->ai_chan_ticks - 1, 671 dev->iobase + ME4000_AI_CHAN_TIMER_REG); 672 673 /* Start sources */ 674 ctrl = devpriv->ai_ctrl_mode | 675 ME4000_AI_CTRL_CHANNEL_FIFO | 676 ME4000_AI_CTRL_DATA_FIFO; 677 678 /* Stop triggers */ 679 if (cmd->stop_src == TRIG_COUNT) { 680 outl(cmd->chanlist_len * cmd->stop_arg, 681 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG); 682 ctrl |= ME4000_AI_CTRL_SC_IRQ; 683 } else if (cmd->stop_src == TRIG_NONE && 684 cmd->scan_end_src == TRIG_COUNT) { 685 outl(cmd->scan_end_arg, 686 dev->iobase + ME4000_AI_SAMPLE_COUNTER_REG); 687 ctrl |= ME4000_AI_CTRL_SC_IRQ; 688 } 689 ctrl |= ME4000_AI_CTRL_HF_IRQ; 690 691 /* Write the setup to the control register */ 692 outl(ctrl, dev->iobase + ME4000_AI_CTRL_REG); 693 694 /* Write the channel list */ 695 me4000_ai_write_chanlist(dev, s, cmd); 696 697 /* Start acquistion by dummy read */ 698 inl(dev->iobase + ME4000_AI_START_REG); 699 700 return 0; 701 } 702 703 static int me4000_ai_do_cmd_test(struct comedi_device *dev, 704 struct comedi_subdevice *s, 705 struct comedi_cmd *cmd) 706 { 707 struct me4000_private *devpriv = dev->private; 708 int err = 0; 709 710 /* Step 1 : check if triggers are trivially valid */ 711 712 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); 713 err |= comedi_check_trigger_src(&cmd->scan_begin_src, 714 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT); 715 err |= comedi_check_trigger_src(&cmd->convert_src, 716 TRIG_TIMER | TRIG_EXT); 717 err |= comedi_check_trigger_src(&cmd->scan_end_src, 718 TRIG_NONE | TRIG_COUNT); 719 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE | TRIG_COUNT); 720 721 if (err) 722 return 1; 723 724 /* Step 2a : make sure trigger sources are unique */ 725 726 err |= comedi_check_trigger_is_unique(cmd->start_src); 727 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); 728 err |= comedi_check_trigger_is_unique(cmd->convert_src); 729 err |= comedi_check_trigger_is_unique(cmd->scan_end_src); 730 err |= comedi_check_trigger_is_unique(cmd->stop_src); 731 732 /* Step 2b : and mutually compatible */ 733 734 if (cmd->start_src == TRIG_NOW && 735 cmd->scan_begin_src == TRIG_TIMER && 736 cmd->convert_src == TRIG_TIMER) { 737 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0; 738 } else if (cmd->start_src == TRIG_NOW && 739 cmd->scan_begin_src == TRIG_FOLLOW && 740 cmd->convert_src == TRIG_TIMER) { 741 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0; 742 } else if (cmd->start_src == TRIG_EXT && 743 cmd->scan_begin_src == TRIG_TIMER && 744 cmd->convert_src == TRIG_TIMER) { 745 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1; 746 } else if (cmd->start_src == TRIG_EXT && 747 cmd->scan_begin_src == TRIG_FOLLOW && 748 cmd->convert_src == TRIG_TIMER) { 749 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_1; 750 } else if (cmd->start_src == TRIG_EXT && 751 cmd->scan_begin_src == TRIG_EXT && 752 cmd->convert_src == TRIG_TIMER) { 753 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_2; 754 } else if (cmd->start_src == TRIG_EXT && 755 cmd->scan_begin_src == TRIG_EXT && 756 cmd->convert_src == TRIG_EXT) { 757 devpriv->ai_ctrl_mode = ME4000_AI_CTRL_MODE_0 | 758 ME4000_AI_CTRL_MODE_1; 759 } else { 760 err |= -EINVAL; 761 } 762 763 if (err) 764 return 2; 765 766 /* Step 3: check if arguments are trivially valid */ 767 768 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); 769 770 if (cmd->chanlist_len < 1) { 771 cmd->chanlist_len = 1; 772 err |= -EINVAL; 773 } 774 775 /* Round the timer arguments */ 776 me4000_ai_round_cmd_args(dev, s, cmd); 777 778 if (devpriv->ai_init_ticks < 66) { 779 cmd->start_arg = 2000; 780 err |= -EINVAL; 781 } 782 if (devpriv->ai_scan_ticks && devpriv->ai_scan_ticks < 67) { 783 cmd->scan_begin_arg = 2031; 784 err |= -EINVAL; 785 } 786 if (devpriv->ai_chan_ticks < 66) { 787 cmd->convert_arg = 2000; 788 err |= -EINVAL; 789 } 790 791 if (cmd->stop_src == TRIG_COUNT) 792 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); 793 else /* TRIG_NONE */ 794 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); 795 796 if (err) 797 return 3; 798 799 /* 800 * Stage 4. Check for argument conflicts. 801 */ 802 if (cmd->start_src == TRIG_NOW && 803 cmd->scan_begin_src == TRIG_TIMER && 804 cmd->convert_src == TRIG_TIMER) { 805 /* Check timer arguments */ 806 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) { 807 dev_err(dev->class_dev, "Invalid start arg\n"); 808 cmd->start_arg = 2000; /* 66 ticks at least */ 809 err++; 810 } 811 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) { 812 dev_err(dev->class_dev, "Invalid convert arg\n"); 813 cmd->convert_arg = 2000; /* 66 ticks at least */ 814 err++; 815 } 816 if (devpriv->ai_scan_ticks <= 817 cmd->chanlist_len * devpriv->ai_chan_ticks) { 818 dev_err(dev->class_dev, "Invalid scan end arg\n"); 819 820 /* At least one tick more */ 821 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; 822 err++; 823 } 824 } else if (cmd->start_src == TRIG_NOW && 825 cmd->scan_begin_src == TRIG_FOLLOW && 826 cmd->convert_src == TRIG_TIMER) { 827 /* Check timer arguments */ 828 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) { 829 dev_err(dev->class_dev, "Invalid start arg\n"); 830 cmd->start_arg = 2000; /* 66 ticks at least */ 831 err++; 832 } 833 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) { 834 dev_err(dev->class_dev, "Invalid convert arg\n"); 835 cmd->convert_arg = 2000; /* 66 ticks at least */ 836 err++; 837 } 838 } else if (cmd->start_src == TRIG_EXT && 839 cmd->scan_begin_src == TRIG_TIMER && 840 cmd->convert_src == TRIG_TIMER) { 841 /* Check timer arguments */ 842 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) { 843 dev_err(dev->class_dev, "Invalid start arg\n"); 844 cmd->start_arg = 2000; /* 66 ticks at least */ 845 err++; 846 } 847 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) { 848 dev_err(dev->class_dev, "Invalid convert arg\n"); 849 cmd->convert_arg = 2000; /* 66 ticks at least */ 850 err++; 851 } 852 if (devpriv->ai_scan_ticks <= 853 cmd->chanlist_len * devpriv->ai_chan_ticks) { 854 dev_err(dev->class_dev, "Invalid scan end arg\n"); 855 856 /* At least one tick more */ 857 cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; 858 err++; 859 } 860 } else if (cmd->start_src == TRIG_EXT && 861 cmd->scan_begin_src == TRIG_FOLLOW && 862 cmd->convert_src == TRIG_TIMER) { 863 /* Check timer arguments */ 864 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) { 865 dev_err(dev->class_dev, "Invalid start arg\n"); 866 cmd->start_arg = 2000; /* 66 ticks at least */ 867 err++; 868 } 869 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) { 870 dev_err(dev->class_dev, "Invalid convert arg\n"); 871 cmd->convert_arg = 2000; /* 66 ticks at least */ 872 err++; 873 } 874 } else if (cmd->start_src == TRIG_EXT && 875 cmd->scan_begin_src == TRIG_EXT && 876 cmd->convert_src == TRIG_TIMER) { 877 /* Check timer arguments */ 878 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) { 879 dev_err(dev->class_dev, "Invalid start arg\n"); 880 cmd->start_arg = 2000; /* 66 ticks at least */ 881 err++; 882 } 883 if (devpriv->ai_chan_ticks < ME4000_AI_MIN_TICKS) { 884 dev_err(dev->class_dev, "Invalid convert arg\n"); 885 cmd->convert_arg = 2000; /* 66 ticks at least */ 886 err++; 887 } 888 } else if (cmd->start_src == TRIG_EXT && 889 cmd->scan_begin_src == TRIG_EXT && 890 cmd->convert_src == TRIG_EXT) { 891 /* Check timer arguments */ 892 if (devpriv->ai_init_ticks < ME4000_AI_MIN_TICKS) { 893 dev_err(dev->class_dev, "Invalid start arg\n"); 894 cmd->start_arg = 2000; /* 66 ticks at least */ 895 err++; 896 } 897 } 898 if (cmd->scan_end_src == TRIG_COUNT) { 899 if (cmd->scan_end_arg == 0) { 900 dev_err(dev->class_dev, "Invalid scan end arg\n"); 901 cmd->scan_end_arg = 1; 902 err++; 903 } 904 } 905 906 if (err) 907 return 4; 908 909 /* Step 5: check channel list if it exists */ 910 if (cmd->chanlist && cmd->chanlist_len > 0) 911 err |= me4000_ai_check_chanlist(dev, s, cmd); 912 913 if (err) 914 return 5; 915 916 return 0; 917 } 918 919 static irqreturn_t me4000_ai_isr(int irq, void *dev_id) 920 { 921 unsigned int tmp; 922 struct comedi_device *dev = dev_id; 923 struct comedi_subdevice *s = dev->read_subdev; 924 int i; 925 int c = 0; 926 unsigned short lval; 927 928 if (!dev->attached) 929 return IRQ_NONE; 930 931 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) & 932 ME4000_IRQ_STATUS_AI_HF) { 933 /* Read status register to find out what happened */ 934 tmp = inl(dev->iobase + ME4000_AI_STATUS_REG); 935 936 if (!(tmp & ME4000_AI_STATUS_FF_DATA) && 937 !(tmp & ME4000_AI_STATUS_HF_DATA) && 938 (tmp & ME4000_AI_STATUS_EF_DATA)) { 939 dev_err(dev->class_dev, "FIFO overflow\n"); 940 s->async->events |= COMEDI_CB_ERROR; 941 c = ME4000_AI_FIFO_COUNT; 942 } else if ((tmp & ME4000_AI_STATUS_FF_DATA) && 943 !(tmp & ME4000_AI_STATUS_HF_DATA) && 944 (tmp & ME4000_AI_STATUS_EF_DATA)) { 945 c = ME4000_AI_FIFO_COUNT / 2; 946 } else { 947 dev_err(dev->class_dev, "Undefined FIFO state\n"); 948 s->async->events |= COMEDI_CB_ERROR; 949 c = 0; 950 } 951 952 for (i = 0; i < c; i++) { 953 lval = me4000_ai_get_sample(dev, s); 954 if (!comedi_buf_write_samples(s, &lval, 1)) 955 break; 956 } 957 958 /* Work is done, so reset the interrupt */ 959 tmp |= ME4000_AI_CTRL_HF_IRQ_RESET; 960 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); 961 tmp &= ~ME4000_AI_CTRL_HF_IRQ_RESET; 962 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); 963 } 964 965 if (inl(dev->iobase + ME4000_IRQ_STATUS_REG) & 966 ME4000_IRQ_STATUS_SC) { 967 /* Acquisition is complete */ 968 s->async->events |= COMEDI_CB_EOA; 969 970 /* Poll data until fifo empty */ 971 while (inl(dev->iobase + ME4000_AI_STATUS_REG) & 972 ME4000_AI_STATUS_EF_DATA) { 973 lval = me4000_ai_get_sample(dev, s); 974 if (!comedi_buf_write_samples(s, &lval, 1)) 975 break; 976 } 977 978 /* Work is done, so reset the interrupt */ 979 tmp = inl(dev->iobase + ME4000_AI_CTRL_REG); 980 tmp |= ME4000_AI_CTRL_SC_IRQ_RESET; 981 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); 982 tmp &= ~ME4000_AI_CTRL_SC_IRQ_RESET; 983 outl(tmp, dev->iobase + ME4000_AI_CTRL_REG); 984 } 985 986 comedi_handle_events(dev, s); 987 988 return IRQ_HANDLED; 989 } 990 991 static int me4000_ao_insn_write(struct comedi_device *dev, 992 struct comedi_subdevice *s, 993 struct comedi_insn *insn, 994 unsigned int *data) 995 { 996 unsigned int chan = CR_CHAN(insn->chanspec); 997 unsigned int tmp; 998 999 /* Stop any running conversion */ 1000 tmp = inl(dev->iobase + ME4000_AO_CTRL_REG(chan)); 1001 tmp |= ME4000_AO_CTRL_IMMEDIATE_STOP; 1002 outl(tmp, dev->iobase + ME4000_AO_CTRL_REG(chan)); 1003 1004 /* Clear control register and set to single mode */ 1005 outl(0x0, dev->iobase + ME4000_AO_CTRL_REG(chan)); 1006 1007 /* Write data value */ 1008 outl(data[0], dev->iobase + ME4000_AO_SINGLE_REG(chan)); 1009 1010 /* Store in the mirror */ 1011 s->readback[chan] = data[0]; 1012 1013 return 1; 1014 } 1015 1016 static int me4000_dio_insn_bits(struct comedi_device *dev, 1017 struct comedi_subdevice *s, 1018 struct comedi_insn *insn, 1019 unsigned int *data) 1020 { 1021 if (comedi_dio_update_state(s, data)) { 1022 outl((s->state >> 0) & 0xFF, 1023 dev->iobase + ME4000_DIO_PORT_0_REG); 1024 outl((s->state >> 8) & 0xFF, 1025 dev->iobase + ME4000_DIO_PORT_1_REG); 1026 outl((s->state >> 16) & 0xFF, 1027 dev->iobase + ME4000_DIO_PORT_2_REG); 1028 outl((s->state >> 24) & 0xFF, 1029 dev->iobase + ME4000_DIO_PORT_3_REG); 1030 } 1031 1032 data[1] = ((inl(dev->iobase + ME4000_DIO_PORT_0_REG) & 0xFF) << 0) | 1033 ((inl(dev->iobase + ME4000_DIO_PORT_1_REG) & 0xFF) << 8) | 1034 ((inl(dev->iobase + ME4000_DIO_PORT_2_REG) & 0xFF) << 16) | 1035 ((inl(dev->iobase + ME4000_DIO_PORT_3_REG) & 0xFF) << 24); 1036 1037 return insn->n; 1038 } 1039 1040 static int me4000_dio_insn_config(struct comedi_device *dev, 1041 struct comedi_subdevice *s, 1042 struct comedi_insn *insn, 1043 unsigned int *data) 1044 { 1045 unsigned int chan = CR_CHAN(insn->chanspec); 1046 unsigned int mask; 1047 unsigned int tmp; 1048 int ret; 1049 1050 if (chan < 8) 1051 mask = 0x000000ff; 1052 else if (chan < 16) 1053 mask = 0x0000ff00; 1054 else if (chan < 24) 1055 mask = 0x00ff0000; 1056 else 1057 mask = 0xff000000; 1058 1059 ret = comedi_dio_insn_config(dev, s, insn, data, mask); 1060 if (ret) 1061 return ret; 1062 1063 tmp = inl(dev->iobase + ME4000_DIO_CTRL_REG); 1064 tmp &= ~(ME4000_DIO_CTRL_MODE_0 | ME4000_DIO_CTRL_MODE_1 | 1065 ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3 | 1066 ME4000_DIO_CTRL_MODE_4 | ME4000_DIO_CTRL_MODE_5 | 1067 ME4000_DIO_CTRL_MODE_6 | ME4000_DIO_CTRL_MODE_7); 1068 if (s->io_bits & 0x000000ff) 1069 tmp |= ME4000_DIO_CTRL_MODE_0; 1070 if (s->io_bits & 0x0000ff00) 1071 tmp |= ME4000_DIO_CTRL_MODE_2; 1072 if (s->io_bits & 0x00ff0000) 1073 tmp |= ME4000_DIO_CTRL_MODE_4; 1074 if (s->io_bits & 0xff000000) 1075 tmp |= ME4000_DIO_CTRL_MODE_6; 1076 1077 /* 1078 * Check for optoisolated ME-4000 version. 1079 * If one the first port is a fixed output 1080 * port and the second is a fixed input port. 1081 */ 1082 if (inl(dev->iobase + ME4000_DIO_DIR_REG)) { 1083 s->io_bits |= 0x000000ff; 1084 s->io_bits &= ~0x0000ff00; 1085 tmp |= ME4000_DIO_CTRL_MODE_0; 1086 tmp &= ~(ME4000_DIO_CTRL_MODE_2 | ME4000_DIO_CTRL_MODE_3); 1087 } 1088 1089 outl(tmp, dev->iobase + ME4000_DIO_CTRL_REG); 1090 1091 return insn->n; 1092 } 1093 1094 static int me4000_auto_attach(struct comedi_device *dev, 1095 unsigned long context) 1096 { 1097 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 1098 const struct me4000_board *board = NULL; 1099 struct me4000_private *devpriv; 1100 struct comedi_subdevice *s; 1101 int result; 1102 1103 if (context < ARRAY_SIZE(me4000_boards)) 1104 board = &me4000_boards[context]; 1105 if (!board) 1106 return -ENODEV; 1107 dev->board_ptr = board; 1108 dev->board_name = board->name; 1109 1110 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1111 if (!devpriv) 1112 return -ENOMEM; 1113 1114 result = comedi_pci_enable(dev); 1115 if (result) 1116 return result; 1117 1118 devpriv->plx_regbase = pci_resource_start(pcidev, 1); 1119 dev->iobase = pci_resource_start(pcidev, 2); 1120 if (!devpriv->plx_regbase || !dev->iobase) 1121 return -ENODEV; 1122 1123 result = comedi_load_firmware(dev, &pcidev->dev, ME4000_FIRMWARE, 1124 me4000_xilinx_download, 0); 1125 if (result < 0) 1126 return result; 1127 1128 me4000_reset(dev); 1129 1130 if (pcidev->irq > 0) { 1131 result = request_irq(pcidev->irq, me4000_ai_isr, IRQF_SHARED, 1132 dev->board_name, dev); 1133 if (result == 0) { 1134 dev->irq = pcidev->irq; 1135 1136 /* Enable interrupts on the PLX */ 1137 outl(PLX9052_INTCSR_LI1ENAB | PLX9052_INTCSR_LI1POL | 1138 PLX9052_INTCSR_PCIENAB, 1139 devpriv->plx_regbase + PLX9052_INTCSR); 1140 } 1141 } 1142 1143 result = comedi_alloc_subdevices(dev, 4); 1144 if (result) 1145 return result; 1146 1147 /* Analog Input subdevice */ 1148 s = &dev->subdevices[0]; 1149 s->type = COMEDI_SUBD_AI; 1150 s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND; 1151 if (board->can_do_diff_ai) 1152 s->subdev_flags |= SDF_DIFF; 1153 s->n_chan = board->ai_nchan; 1154 s->maxdata = 0xffff; 1155 s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT; 1156 s->range_table = &me4000_ai_range; 1157 s->insn_read = me4000_ai_insn_read; 1158 1159 if (dev->irq) { 1160 dev->read_subdev = s; 1161 s->subdev_flags |= SDF_CMD_READ; 1162 s->cancel = me4000_ai_cancel; 1163 s->do_cmdtest = me4000_ai_do_cmd_test; 1164 s->do_cmd = me4000_ai_do_cmd; 1165 } 1166 1167 /* Analog Output subdevice */ 1168 s = &dev->subdevices[1]; 1169 if (board->has_ao) { 1170 s->type = COMEDI_SUBD_AO; 1171 s->subdev_flags = SDF_WRITABLE | SDF_COMMON | SDF_GROUND; 1172 s->n_chan = 4; 1173 s->maxdata = 0xffff; 1174 s->range_table = &range_bipolar10; 1175 s->insn_write = me4000_ao_insn_write; 1176 1177 result = comedi_alloc_subdev_readback(s); 1178 if (result) 1179 return result; 1180 } else { 1181 s->type = COMEDI_SUBD_UNUSED; 1182 } 1183 1184 /* Digital I/O subdevice */ 1185 s = &dev->subdevices[2]; 1186 s->type = COMEDI_SUBD_DIO; 1187 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 1188 s->n_chan = 32; 1189 s->maxdata = 1; 1190 s->range_table = &range_digital; 1191 s->insn_bits = me4000_dio_insn_bits; 1192 s->insn_config = me4000_dio_insn_config; 1193 1194 /* 1195 * Check for optoisolated ME-4000 version. If one the first 1196 * port is a fixed output port and the second is a fixed input port. 1197 */ 1198 if (!inl(dev->iobase + ME4000_DIO_DIR_REG)) { 1199 s->io_bits |= 0xFF; 1200 outl(ME4000_DIO_CTRL_MODE_0, 1201 dev->iobase + ME4000_DIO_DIR_REG); 1202 } 1203 1204 /* Counter subdevice (8254) */ 1205 s = &dev->subdevices[3]; 1206 if (board->has_counter) { 1207 unsigned long timer_base = pci_resource_start(pcidev, 3); 1208 1209 if (!timer_base) 1210 return -ENODEV; 1211 1212 dev->pacer = comedi_8254_init(timer_base, 0, I8254_IO8, 0); 1213 if (!dev->pacer) 1214 return -ENOMEM; 1215 1216 comedi_8254_subdevice_init(s, dev->pacer); 1217 } else { 1218 s->type = COMEDI_SUBD_UNUSED; 1219 } 1220 1221 return 0; 1222 } 1223 1224 static void me4000_detach(struct comedi_device *dev) 1225 { 1226 if (dev->irq) { 1227 struct me4000_private *devpriv = dev->private; 1228 1229 /* Disable interrupts on the PLX */ 1230 outl(0, devpriv->plx_regbase + PLX9052_INTCSR); 1231 } 1232 comedi_pci_detach(dev); 1233 } 1234 1235 static struct comedi_driver me4000_driver = { 1236 .driver_name = "me4000", 1237 .module = THIS_MODULE, 1238 .auto_attach = me4000_auto_attach, 1239 .detach = me4000_detach, 1240 }; 1241 1242 static int me4000_pci_probe(struct pci_dev *dev, 1243 const struct pci_device_id *id) 1244 { 1245 return comedi_pci_auto_config(dev, &me4000_driver, id->driver_data); 1246 } 1247 1248 static const struct pci_device_id me4000_pci_table[] = { 1249 { PCI_VDEVICE(MEILHAUS, 0x4650), BOARD_ME4650 }, 1250 { PCI_VDEVICE(MEILHAUS, 0x4660), BOARD_ME4660 }, 1251 { PCI_VDEVICE(MEILHAUS, 0x4661), BOARD_ME4660I }, 1252 { PCI_VDEVICE(MEILHAUS, 0x4662), BOARD_ME4660S }, 1253 { PCI_VDEVICE(MEILHAUS, 0x4663), BOARD_ME4660IS }, 1254 { PCI_VDEVICE(MEILHAUS, 0x4670), BOARD_ME4670 }, 1255 { PCI_VDEVICE(MEILHAUS, 0x4671), BOARD_ME4670I }, 1256 { PCI_VDEVICE(MEILHAUS, 0x4672), BOARD_ME4670S }, 1257 { PCI_VDEVICE(MEILHAUS, 0x4673), BOARD_ME4670IS }, 1258 { PCI_VDEVICE(MEILHAUS, 0x4680), BOARD_ME4680 }, 1259 { PCI_VDEVICE(MEILHAUS, 0x4681), BOARD_ME4680I }, 1260 { PCI_VDEVICE(MEILHAUS, 0x4682), BOARD_ME4680S }, 1261 { PCI_VDEVICE(MEILHAUS, 0x4683), BOARD_ME4680IS }, 1262 { 0 } 1263 }; 1264 MODULE_DEVICE_TABLE(pci, me4000_pci_table); 1265 1266 static struct pci_driver me4000_pci_driver = { 1267 .name = "me4000", 1268 .id_table = me4000_pci_table, 1269 .probe = me4000_pci_probe, 1270 .remove = comedi_pci_auto_unconfig, 1271 }; 1272 module_comedi_pci_driver(me4000_driver, me4000_pci_driver); 1273 1274 MODULE_AUTHOR("Comedi https://www.comedi.org"); 1275 MODULE_DESCRIPTION("Comedi driver for Meilhaus ME-4000 series boards"); 1276 MODULE_LICENSE("GPL"); 1277 MODULE_FIRMWARE(ME4000_FIRMWARE); 1278