1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * addi_apci_1500.c 4 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. 5 * 6 * ADDI-DATA GmbH 7 * Dieselstrasse 3 8 * D-77833 Ottersweier 9 * Tel: +19(0)7223/9493-0 10 * Fax: +49(0)7223/9493-92 11 * http://www.addi-data.com 12 * info@addi-data.com 13 */ 14 15 #include <linux/module.h> 16 #include <linux/interrupt.h> 17 #include <linux/comedi/comedi_pci.h> 18 19 #include "amcc_s5933.h" 20 #include "z8536.h" 21 22 /* 23 * PCI Bar 0 Register map (devpriv->amcc) 24 * see amcc_s5933.h for register and bit defines 25 */ 26 27 /* 28 * PCI Bar 1 Register map (dev->iobase) 29 * see z8536.h for Z8536 internal registers and bit defines 30 */ 31 #define APCI1500_Z8536_PORTC_REG 0x00 32 #define APCI1500_Z8536_PORTB_REG 0x01 33 #define APCI1500_Z8536_PORTA_REG 0x02 34 #define APCI1500_Z8536_CTRL_REG 0x03 35 36 /* 37 * PCI Bar 2 Register map (devpriv->addon) 38 */ 39 #define APCI1500_CLK_SEL_REG 0x00 40 #define APCI1500_DI_REG 0x00 41 #define APCI1500_DO_REG 0x02 42 43 struct apci1500_private { 44 unsigned long amcc; 45 unsigned long addon; 46 47 unsigned int clk_src; 48 49 /* Digital trigger configuration [0]=AND [1]=OR */ 50 unsigned int pm[2]; /* Pattern Mask */ 51 unsigned int pt[2]; /* Pattern Transition */ 52 unsigned int pp[2]; /* Pattern Polarity */ 53 }; 54 55 static unsigned int z8536_read(struct comedi_device *dev, unsigned int reg) 56 { 57 unsigned long flags; 58 unsigned int val; 59 60 spin_lock_irqsave(&dev->spinlock, flags); 61 outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG); 62 val = inb(dev->iobase + APCI1500_Z8536_CTRL_REG); 63 spin_unlock_irqrestore(&dev->spinlock, flags); 64 65 return val; 66 } 67 68 static void z8536_write(struct comedi_device *dev, 69 unsigned int val, unsigned int reg) 70 { 71 unsigned long flags; 72 73 spin_lock_irqsave(&dev->spinlock, flags); 74 outb(reg, dev->iobase + APCI1500_Z8536_CTRL_REG); 75 outb(val, dev->iobase + APCI1500_Z8536_CTRL_REG); 76 spin_unlock_irqrestore(&dev->spinlock, flags); 77 } 78 79 static void z8536_reset(struct comedi_device *dev) 80 { 81 unsigned long flags; 82 83 /* 84 * Even if the state of the Z8536 is not known, the following 85 * sequence will reset it and put it in State 0. 86 */ 87 spin_lock_irqsave(&dev->spinlock, flags); 88 inb(dev->iobase + APCI1500_Z8536_CTRL_REG); 89 outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG); 90 inb(dev->iobase + APCI1500_Z8536_CTRL_REG); 91 outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG); 92 outb(1, dev->iobase + APCI1500_Z8536_CTRL_REG); 93 outb(0, dev->iobase + APCI1500_Z8536_CTRL_REG); 94 spin_unlock_irqrestore(&dev->spinlock, flags); 95 96 /* Disable all Ports and Counter/Timers */ 97 z8536_write(dev, 0x00, Z8536_CFG_CTRL_REG); 98 99 /* 100 * Port A is connected to Ditial Input channels 0-7. 101 * Configure the port to allow interrupt detection. 102 */ 103 z8536_write(dev, Z8536_PAB_MODE_PTS_BIT | 104 Z8536_PAB_MODE_SB | 105 Z8536_PAB_MODE_PMS_DISABLE, 106 Z8536_PA_MODE_REG); 107 z8536_write(dev, 0xff, Z8536_PB_DPP_REG); 108 z8536_write(dev, 0xff, Z8536_PA_DD_REG); 109 110 /* 111 * Port B is connected to Ditial Input channels 8-13. 112 * Configure the port to allow interrupt detection. 113 * 114 * NOTE: Bits 7 and 6 of Port B are connected to internal 115 * diagnostic signals and bit 7 is inverted. 116 */ 117 z8536_write(dev, Z8536_PAB_MODE_PTS_BIT | 118 Z8536_PAB_MODE_SB | 119 Z8536_PAB_MODE_PMS_DISABLE, 120 Z8536_PB_MODE_REG); 121 z8536_write(dev, 0x7f, Z8536_PB_DPP_REG); 122 z8536_write(dev, 0xff, Z8536_PB_DD_REG); 123 124 /* 125 * Not sure what Port C is connected to... 126 */ 127 z8536_write(dev, 0x09, Z8536_PC_DPP_REG); 128 z8536_write(dev, 0x0e, Z8536_PC_DD_REG); 129 130 /* 131 * Clear and disable all interrupt sources. 132 * 133 * Just in case, the reset of the Z8536 should have already 134 * done this. 135 */ 136 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PA_CMDSTAT_REG); 137 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG); 138 139 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_PB_CMDSTAT_REG); 140 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG); 141 142 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(0)); 143 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(0)); 144 145 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(1)); 146 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(1)); 147 148 z8536_write(dev, Z8536_CMD_CLR_IP_IUS, Z8536_CT_CMDSTAT_REG(2)); 149 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_CT_CMDSTAT_REG(2)); 150 151 /* Disable all interrupts */ 152 z8536_write(dev, 0x00, Z8536_INT_CTRL_REG); 153 } 154 155 static void apci1500_port_enable(struct comedi_device *dev, bool enable) 156 { 157 unsigned int cfg; 158 159 cfg = z8536_read(dev, Z8536_CFG_CTRL_REG); 160 if (enable) 161 cfg |= (Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE); 162 else 163 cfg &= ~(Z8536_CFG_CTRL_PAE | Z8536_CFG_CTRL_PBE); 164 z8536_write(dev, cfg, Z8536_CFG_CTRL_REG); 165 } 166 167 static void apci1500_timer_enable(struct comedi_device *dev, 168 unsigned int chan, bool enable) 169 { 170 unsigned int bit; 171 unsigned int cfg; 172 173 if (chan == 0) 174 bit = Z8536_CFG_CTRL_CT1E; 175 else if (chan == 1) 176 bit = Z8536_CFG_CTRL_CT2E; 177 else 178 bit = Z8536_CFG_CTRL_PCE_CT3E; 179 180 cfg = z8536_read(dev, Z8536_CFG_CTRL_REG); 181 if (enable) { 182 cfg |= bit; 183 } else { 184 cfg &= ~bit; 185 z8536_write(dev, 0x00, Z8536_CT_CMDSTAT_REG(chan)); 186 } 187 z8536_write(dev, cfg, Z8536_CFG_CTRL_REG); 188 } 189 190 static bool apci1500_ack_irq(struct comedi_device *dev, 191 unsigned int reg) 192 { 193 unsigned int val; 194 195 val = z8536_read(dev, reg); 196 if ((val & Z8536_STAT_IE_IP) == Z8536_STAT_IE_IP) { 197 val &= 0x0f; /* preserve any write bits */ 198 val |= Z8536_CMD_CLR_IP_IUS; 199 z8536_write(dev, val, reg); 200 201 return true; 202 } 203 return false; 204 } 205 206 static irqreturn_t apci1500_interrupt(int irq, void *d) 207 { 208 struct comedi_device *dev = d; 209 struct apci1500_private *devpriv = dev->private; 210 struct comedi_subdevice *s = dev->read_subdev; 211 unsigned short status = 0; 212 unsigned int val; 213 214 val = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); 215 if (!(val & INTCSR_INTR_ASSERTED)) 216 return IRQ_NONE; 217 218 if (apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG)) 219 status |= 0x01; /* port a event (inputs 0-7) */ 220 221 if (apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG)) { 222 /* Tests if this is an external error */ 223 val = inb(dev->iobase + APCI1500_Z8536_PORTB_REG); 224 val &= 0xc0; 225 if (val) { 226 if (val & 0x80) /* voltage error */ 227 status |= 0x40; 228 if (val & 0x40) /* short circuit error */ 229 status |= 0x80; 230 } else { 231 status |= 0x02; /* port b event (inputs 8-13) */ 232 } 233 } 234 235 /* 236 * NOTE: The 'status' returned by the sample matches the 237 * interrupt mask information from the APCI-1500 Users Manual. 238 * 239 * Mask Meaning 240 * ---------- ------------------------------------------ 241 * 0b00000001 Event 1 has occurred 242 * 0b00000010 Event 2 has occurred 243 * 0b00000100 Counter/timer 1 has run down (not implemented) 244 * 0b00001000 Counter/timer 2 has run down (not implemented) 245 * 0b00010000 Counter 3 has run down (not implemented) 246 * 0b00100000 Watchdog has run down (not implemented) 247 * 0b01000000 Voltage error 248 * 0b10000000 Short-circuit error 249 */ 250 comedi_buf_write_samples(s, &status, 1); 251 comedi_handle_events(dev, s); 252 253 return IRQ_HANDLED; 254 } 255 256 static int apci1500_di_cancel(struct comedi_device *dev, 257 struct comedi_subdevice *s) 258 { 259 /* Disables the main interrupt on the board */ 260 z8536_write(dev, 0x00, Z8536_INT_CTRL_REG); 261 262 /* Disable Ports A & B */ 263 apci1500_port_enable(dev, false); 264 265 /* Ack any pending interrupts */ 266 apci1500_ack_irq(dev, Z8536_PA_CMDSTAT_REG); 267 apci1500_ack_irq(dev, Z8536_PB_CMDSTAT_REG); 268 269 /* Disable pattern interrupts */ 270 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PA_CMDSTAT_REG); 271 z8536_write(dev, Z8536_CMD_CLR_IE, Z8536_PB_CMDSTAT_REG); 272 273 /* Enable Ports A & B */ 274 apci1500_port_enable(dev, true); 275 276 return 0; 277 } 278 279 static int apci1500_di_inttrig_start(struct comedi_device *dev, 280 struct comedi_subdevice *s, 281 unsigned int trig_num) 282 { 283 struct apci1500_private *devpriv = dev->private; 284 struct comedi_cmd *cmd = &s->async->cmd; 285 unsigned int pa_mode = Z8536_PAB_MODE_PMS_DISABLE; 286 unsigned int pb_mode = Z8536_PAB_MODE_PMS_DISABLE; 287 unsigned int pa_trig = trig_num & 0x01; 288 unsigned int pb_trig = (trig_num >> 1) & 0x01; 289 bool valid_trig = false; 290 unsigned int val; 291 292 if (trig_num != cmd->start_arg) 293 return -EINVAL; 294 295 /* Disable Ports A & B */ 296 apci1500_port_enable(dev, false); 297 298 /* Set Port A for selected trigger pattern */ 299 z8536_write(dev, devpriv->pm[pa_trig] & 0xff, Z8536_PA_PM_REG); 300 z8536_write(dev, devpriv->pt[pa_trig] & 0xff, Z8536_PA_PT_REG); 301 z8536_write(dev, devpriv->pp[pa_trig] & 0xff, Z8536_PA_PP_REG); 302 303 /* Set Port B for selected trigger pattern */ 304 z8536_write(dev, (devpriv->pm[pb_trig] >> 8) & 0xff, Z8536_PB_PM_REG); 305 z8536_write(dev, (devpriv->pt[pb_trig] >> 8) & 0xff, Z8536_PB_PT_REG); 306 z8536_write(dev, (devpriv->pp[pb_trig] >> 8) & 0xff, Z8536_PB_PP_REG); 307 308 /* Set Port A trigger mode (if enabled) and enable interrupt */ 309 if (devpriv->pm[pa_trig] & 0xff) { 310 pa_mode = pa_trig ? Z8536_PAB_MODE_PMS_AND 311 : Z8536_PAB_MODE_PMS_OR; 312 313 val = z8536_read(dev, Z8536_PA_MODE_REG); 314 val &= ~Z8536_PAB_MODE_PMS_MASK; 315 val |= (pa_mode | Z8536_PAB_MODE_IMO); 316 z8536_write(dev, val, Z8536_PA_MODE_REG); 317 318 z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PA_CMDSTAT_REG); 319 320 valid_trig = true; 321 322 dev_dbg(dev->class_dev, 323 "Port A configured for %s mode pattern detection\n", 324 pa_trig ? "AND" : "OR"); 325 } 326 327 /* Set Port B trigger mode (if enabled) and enable interrupt */ 328 if (devpriv->pm[pb_trig] & 0xff00) { 329 pb_mode = pb_trig ? Z8536_PAB_MODE_PMS_AND 330 : Z8536_PAB_MODE_PMS_OR; 331 332 val = z8536_read(dev, Z8536_PB_MODE_REG); 333 val &= ~Z8536_PAB_MODE_PMS_MASK; 334 val |= (pb_mode | Z8536_PAB_MODE_IMO); 335 z8536_write(dev, val, Z8536_PB_MODE_REG); 336 337 z8536_write(dev, Z8536_CMD_SET_IE, Z8536_PB_CMDSTAT_REG); 338 339 valid_trig = true; 340 341 dev_dbg(dev->class_dev, 342 "Port B configured for %s mode pattern detection\n", 343 pb_trig ? "AND" : "OR"); 344 } 345 346 /* Enable Ports A & B */ 347 apci1500_port_enable(dev, true); 348 349 if (!valid_trig) { 350 dev_dbg(dev->class_dev, 351 "digital trigger %d is not configured\n", trig_num); 352 return -EINVAL; 353 } 354 355 /* Authorizes the main interrupt on the board */ 356 z8536_write(dev, Z8536_INT_CTRL_MIE | Z8536_INT_CTRL_DLC, 357 Z8536_INT_CTRL_REG); 358 359 return 0; 360 } 361 362 static int apci1500_di_cmd(struct comedi_device *dev, 363 struct comedi_subdevice *s) 364 { 365 s->async->inttrig = apci1500_di_inttrig_start; 366 367 return 0; 368 } 369 370 static int apci1500_di_cmdtest(struct comedi_device *dev, 371 struct comedi_subdevice *s, 372 struct comedi_cmd *cmd) 373 { 374 int err = 0; 375 376 /* Step 1 : check if triggers are trivially valid */ 377 378 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT); 379 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); 380 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); 381 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 382 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE); 383 384 if (err) 385 return 1; 386 387 /* Step 2a : make sure trigger sources are unique */ 388 /* Step 2b : and mutually compatible */ 389 390 /* Step 3: check if arguments are trivially valid */ 391 392 /* 393 * Internal start source triggers: 394 * 395 * 0 AND mode for Port A (digital inputs 0-7) 396 * AND mode for Port B (digital inputs 8-13 and internal signals) 397 * 398 * 1 OR mode for Port A (digital inputs 0-7) 399 * AND mode for Port B (digital inputs 8-13 and internal signals) 400 * 401 * 2 AND mode for Port A (digital inputs 0-7) 402 * OR mode for Port B (digital inputs 8-13 and internal signals) 403 * 404 * 3 OR mode for Port A (digital inputs 0-7) 405 * OR mode for Port B (digital inputs 8-13 and internal signals) 406 */ 407 err |= comedi_check_trigger_arg_max(&cmd->start_arg, 3); 408 409 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 410 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); 411 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, 412 cmd->chanlist_len); 413 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); 414 415 if (err) 416 return 3; 417 418 /* Step 4: fix up any arguments */ 419 420 /* Step 5: check channel list if it exists */ 421 422 return 0; 423 } 424 425 /* 426 * The pattern-recognition logic must be configured before the digital 427 * input async command is started. 428 * 429 * Digital input channels 0 to 13 can generate interrupts. Channels 14 430 * and 15 are connected to internal board status/diagnostic signals. 431 * 432 * Channel 14 - Voltage error (the external supply is < 5V) 433 * Channel 15 - Short-circuit/overtemperature error 434 * 435 * data[0] : INSN_CONFIG_DIGITAL_TRIG 436 * data[1] : trigger number 437 * 0 = AND mode 438 * 1 = OR mode 439 * data[2] : configuration operation: 440 * COMEDI_DIGITAL_TRIG_DISABLE = no interrupts 441 * COMEDI_DIGITAL_TRIG_ENABLE_EDGES = edge interrupts 442 * COMEDI_DIGITAL_TRIG_ENABLE_LEVELS = level interrupts 443 * data[3] : left-shift for data[4] and data[5] 444 * data[4] : rising-edge/high level channels 445 * data[5] : falling-edge/low level channels 446 */ 447 static int apci1500_di_cfg_trig(struct comedi_device *dev, 448 struct comedi_subdevice *s, 449 struct comedi_insn *insn, 450 unsigned int *data) 451 { 452 struct apci1500_private *devpriv = dev->private; 453 unsigned int trig = data[1]; 454 unsigned int shift = data[3]; 455 unsigned int hi_mask; 456 unsigned int lo_mask; 457 unsigned int chan_mask; 458 unsigned int old_mask; 459 unsigned int pm; 460 unsigned int pt; 461 unsigned int pp; 462 unsigned int invalid_chan; 463 464 if (trig > 1) { 465 dev_dbg(dev->class_dev, 466 "invalid digital trigger number (0=AND, 1=OR)\n"); 467 return -EINVAL; 468 } 469 470 if (shift <= 16) { 471 hi_mask = data[4] << shift; 472 lo_mask = data[5] << shift; 473 old_mask = (1U << shift) - 1; 474 invalid_chan = (data[4] | data[5]) >> (16 - shift); 475 } else { 476 hi_mask = 0; 477 lo_mask = 0; 478 old_mask = 0xffff; 479 invalid_chan = data[4] | data[5]; 480 } 481 chan_mask = hi_mask | lo_mask; 482 483 if (invalid_chan) { 484 dev_dbg(dev->class_dev, "invalid digital trigger channel\n"); 485 return -EINVAL; 486 } 487 488 pm = devpriv->pm[trig] & old_mask; 489 pt = devpriv->pt[trig] & old_mask; 490 pp = devpriv->pp[trig] & old_mask; 491 492 switch (data[2]) { 493 case COMEDI_DIGITAL_TRIG_DISABLE: 494 /* clear trigger configuration */ 495 pm = 0; 496 pt = 0; 497 pp = 0; 498 break; 499 case COMEDI_DIGITAL_TRIG_ENABLE_EDGES: 500 pm |= chan_mask; /* enable channels */ 501 pt |= chan_mask; /* enable edge detection */ 502 pp |= hi_mask; /* rising-edge channels */ 503 pp &= ~lo_mask; /* falling-edge channels */ 504 break; 505 case COMEDI_DIGITAL_TRIG_ENABLE_LEVELS: 506 pm |= chan_mask; /* enable channels */ 507 pt &= ~chan_mask; /* enable level detection */ 508 pp |= hi_mask; /* high level channels */ 509 pp &= ~lo_mask; /* low level channels */ 510 break; 511 default: 512 return -EINVAL; 513 } 514 515 /* 516 * The AND mode trigger can only have one channel (max) enabled 517 * for edge detection. 518 */ 519 if (trig == 0) { 520 int ret = 0; 521 unsigned int src; 522 523 src = pt & 0xff; 524 if (src) 525 ret |= comedi_check_trigger_is_unique(src); 526 527 src = (pt >> 8) & 0xff; 528 if (src) 529 ret |= comedi_check_trigger_is_unique(src); 530 531 if (ret) { 532 dev_dbg(dev->class_dev, 533 "invalid AND trigger configuration\n"); 534 return ret; 535 } 536 } 537 538 /* save the trigger configuration */ 539 devpriv->pm[trig] = pm; 540 devpriv->pt[trig] = pt; 541 devpriv->pp[trig] = pp; 542 543 return insn->n; 544 } 545 546 static int apci1500_di_insn_config(struct comedi_device *dev, 547 struct comedi_subdevice *s, 548 struct comedi_insn *insn, 549 unsigned int *data) 550 { 551 switch (data[0]) { 552 case INSN_CONFIG_DIGITAL_TRIG: 553 return apci1500_di_cfg_trig(dev, s, insn, data); 554 default: 555 return -EINVAL; 556 } 557 } 558 559 static int apci1500_di_insn_bits(struct comedi_device *dev, 560 struct comedi_subdevice *s, 561 struct comedi_insn *insn, 562 unsigned int *data) 563 { 564 struct apci1500_private *devpriv = dev->private; 565 566 data[1] = inw(devpriv->addon + APCI1500_DI_REG); 567 568 return insn->n; 569 } 570 571 static int apci1500_do_insn_bits(struct comedi_device *dev, 572 struct comedi_subdevice *s, 573 struct comedi_insn *insn, 574 unsigned int *data) 575 { 576 struct apci1500_private *devpriv = dev->private; 577 578 if (comedi_dio_update_state(s, data)) 579 outw(s->state, devpriv->addon + APCI1500_DO_REG); 580 581 data[1] = s->state; 582 583 return insn->n; 584 } 585 586 static int apci1500_timer_insn_config(struct comedi_device *dev, 587 struct comedi_subdevice *s, 588 struct comedi_insn *insn, 589 unsigned int *data) 590 { 591 struct apci1500_private *devpriv = dev->private; 592 unsigned int chan = CR_CHAN(insn->chanspec); 593 unsigned int val; 594 595 switch (data[0]) { 596 case INSN_CONFIG_ARM: 597 val = data[1] & s->maxdata; 598 z8536_write(dev, val & 0xff, Z8536_CT_RELOAD_LSB_REG(chan)); 599 z8536_write(dev, (val >> 8) & 0xff, 600 Z8536_CT_RELOAD_MSB_REG(chan)); 601 602 apci1500_timer_enable(dev, chan, true); 603 z8536_write(dev, Z8536_CT_CMDSTAT_GCB, 604 Z8536_CT_CMDSTAT_REG(chan)); 605 break; 606 case INSN_CONFIG_DISARM: 607 apci1500_timer_enable(dev, chan, false); 608 break; 609 610 case INSN_CONFIG_GET_COUNTER_STATUS: 611 data[1] = 0; 612 val = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan)); 613 if (val & Z8536_CT_STAT_CIP) 614 data[1] |= COMEDI_COUNTER_COUNTING; 615 if (val & Z8536_CT_CMDSTAT_GCB) 616 data[1] |= COMEDI_COUNTER_ARMED; 617 if (val & Z8536_STAT_IP) { 618 data[1] |= COMEDI_COUNTER_TERMINAL_COUNT; 619 apci1500_ack_irq(dev, Z8536_CT_CMDSTAT_REG(chan)); 620 } 621 data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING | 622 COMEDI_COUNTER_TERMINAL_COUNT; 623 break; 624 625 case INSN_CONFIG_SET_COUNTER_MODE: 626 /* Simulate the 8254 timer modes */ 627 switch (data[1]) { 628 case I8254_MODE0: 629 /* Interrupt on Terminal Count */ 630 val = Z8536_CT_MODE_ECE | 631 Z8536_CT_MODE_DCS_ONESHOT; 632 break; 633 case I8254_MODE1: 634 /* Hardware Retriggerable One-Shot */ 635 val = Z8536_CT_MODE_ETE | 636 Z8536_CT_MODE_DCS_ONESHOT; 637 break; 638 case I8254_MODE2: 639 /* Rate Generator */ 640 val = Z8536_CT_MODE_CSC | 641 Z8536_CT_MODE_DCS_PULSE; 642 break; 643 case I8254_MODE3: 644 /* Square Wave Mode */ 645 val = Z8536_CT_MODE_CSC | 646 Z8536_CT_MODE_DCS_SQRWAVE; 647 break; 648 case I8254_MODE4: 649 /* Software Triggered Strobe */ 650 val = Z8536_CT_MODE_REB | 651 Z8536_CT_MODE_DCS_PULSE; 652 break; 653 case I8254_MODE5: 654 /* Hardware Triggered Strobe (watchdog) */ 655 val = Z8536_CT_MODE_EOE | 656 Z8536_CT_MODE_ETE | 657 Z8536_CT_MODE_REB | 658 Z8536_CT_MODE_DCS_PULSE; 659 break; 660 default: 661 return -EINVAL; 662 } 663 apci1500_timer_enable(dev, chan, false); 664 z8536_write(dev, val, Z8536_CT_MODE_REG(chan)); 665 break; 666 667 case INSN_CONFIG_SET_CLOCK_SRC: 668 if (data[1] > 2) 669 return -EINVAL; 670 devpriv->clk_src = data[1]; 671 if (devpriv->clk_src == 2) 672 devpriv->clk_src = 3; 673 outw(devpriv->clk_src, devpriv->addon + APCI1500_CLK_SEL_REG); 674 break; 675 case INSN_CONFIG_GET_CLOCK_SRC: 676 switch (devpriv->clk_src) { 677 case 0: 678 data[1] = 0; /* 111.86 kHz / 2 */ 679 data[2] = 17879; /* 17879 ns (approx) */ 680 break; 681 case 1: 682 data[1] = 1; /* 3.49 kHz / 2 */ 683 data[2] = 573066; /* 573066 ns (approx) */ 684 break; 685 case 3: 686 data[1] = 2; /* 1.747 kHz / 2 */ 687 data[2] = 1164822; /* 1164822 ns (approx) */ 688 break; 689 default: 690 return -EINVAL; 691 } 692 break; 693 694 case INSN_CONFIG_SET_GATE_SRC: 695 if (chan == 0) 696 return -EINVAL; 697 698 val = z8536_read(dev, Z8536_CT_MODE_REG(chan)); 699 val &= Z8536_CT_MODE_EGE; 700 if (data[1] == 1) 701 val |= Z8536_CT_MODE_EGE; 702 else if (data[1] > 1) 703 return -EINVAL; 704 z8536_write(dev, val, Z8536_CT_MODE_REG(chan)); 705 break; 706 case INSN_CONFIG_GET_GATE_SRC: 707 if (chan == 0) 708 return -EINVAL; 709 break; 710 711 default: 712 return -EINVAL; 713 } 714 return insn->n; 715 } 716 717 static int apci1500_timer_insn_write(struct comedi_device *dev, 718 struct comedi_subdevice *s, 719 struct comedi_insn *insn, 720 unsigned int *data) 721 { 722 unsigned int chan = CR_CHAN(insn->chanspec); 723 unsigned int cmd; 724 725 cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan)); 726 cmd &= Z8536_CT_CMDSTAT_GCB; /* preserve gate */ 727 cmd |= Z8536_CT_CMD_TCB; /* set trigger */ 728 729 /* software trigger a timer, it only makes sense to do one write */ 730 if (insn->n) 731 z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan)); 732 733 return insn->n; 734 } 735 736 static int apci1500_timer_insn_read(struct comedi_device *dev, 737 struct comedi_subdevice *s, 738 struct comedi_insn *insn, 739 unsigned int *data) 740 { 741 unsigned int chan = CR_CHAN(insn->chanspec); 742 unsigned int cmd; 743 unsigned int val; 744 int i; 745 746 cmd = z8536_read(dev, Z8536_CT_CMDSTAT_REG(chan)); 747 cmd &= Z8536_CT_CMDSTAT_GCB; /* preserve gate */ 748 cmd |= Z8536_CT_CMD_RCC; /* set RCC */ 749 750 for (i = 0; i < insn->n; i++) { 751 z8536_write(dev, cmd, Z8536_CT_CMDSTAT_REG(chan)); 752 753 val = z8536_read(dev, Z8536_CT_VAL_MSB_REG(chan)) << 8; 754 val |= z8536_read(dev, Z8536_CT_VAL_LSB_REG(chan)); 755 756 data[i] = val; 757 } 758 759 return insn->n; 760 } 761 762 static int apci1500_auto_attach(struct comedi_device *dev, 763 unsigned long context) 764 { 765 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 766 struct apci1500_private *devpriv; 767 struct comedi_subdevice *s; 768 int ret; 769 770 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 771 if (!devpriv) 772 return -ENOMEM; 773 774 ret = comedi_pci_enable(dev); 775 if (ret) 776 return ret; 777 778 dev->iobase = pci_resource_start(pcidev, 1); 779 devpriv->amcc = pci_resource_start(pcidev, 0); 780 devpriv->addon = pci_resource_start(pcidev, 2); 781 782 z8536_reset(dev); 783 784 if (pcidev->irq > 0) { 785 ret = request_irq(pcidev->irq, apci1500_interrupt, IRQF_SHARED, 786 dev->board_name, dev); 787 if (ret == 0) 788 dev->irq = pcidev->irq; 789 } 790 791 ret = comedi_alloc_subdevices(dev, 3); 792 if (ret) 793 return ret; 794 795 /* Digital Input subdevice */ 796 s = &dev->subdevices[0]; 797 s->type = COMEDI_SUBD_DI; 798 s->subdev_flags = SDF_READABLE; 799 s->n_chan = 16; 800 s->maxdata = 1; 801 s->range_table = &range_digital; 802 s->insn_bits = apci1500_di_insn_bits; 803 if (dev->irq) { 804 dev->read_subdev = s; 805 s->subdev_flags |= SDF_CMD_READ; 806 s->len_chanlist = 1; 807 s->insn_config = apci1500_di_insn_config; 808 s->do_cmdtest = apci1500_di_cmdtest; 809 s->do_cmd = apci1500_di_cmd; 810 s->cancel = apci1500_di_cancel; 811 } 812 813 /* Digital Output subdevice */ 814 s = &dev->subdevices[1]; 815 s->type = COMEDI_SUBD_DO; 816 s->subdev_flags = SDF_WRITABLE; 817 s->n_chan = 16; 818 s->maxdata = 1; 819 s->range_table = &range_digital; 820 s->insn_bits = apci1500_do_insn_bits; 821 822 /* reset all the digital outputs */ 823 outw(0x0, devpriv->addon + APCI1500_DO_REG); 824 825 /* Counter/Timer(Watchdog) subdevice */ 826 s = &dev->subdevices[2]; 827 s->type = COMEDI_SUBD_TIMER; 828 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 829 s->n_chan = 3; 830 s->maxdata = 0xffff; 831 s->range_table = &range_unknown; 832 s->insn_config = apci1500_timer_insn_config; 833 s->insn_write = apci1500_timer_insn_write; 834 s->insn_read = apci1500_timer_insn_read; 835 836 /* Enable the PCI interrupt */ 837 if (dev->irq) { 838 outl(0x2000 | INTCSR_INBOX_FULL_INT, 839 devpriv->amcc + AMCC_OP_REG_INTCSR); 840 inl(devpriv->amcc + AMCC_OP_REG_IMB1); 841 inl(devpriv->amcc + AMCC_OP_REG_INTCSR); 842 outl(INTCSR_INBOX_INTR_STATUS | 0x2000 | INTCSR_INBOX_FULL_INT, 843 devpriv->amcc + AMCC_OP_REG_INTCSR); 844 } 845 846 return 0; 847 } 848 849 static void apci1500_detach(struct comedi_device *dev) 850 { 851 struct apci1500_private *devpriv = dev->private; 852 853 if (devpriv->amcc) 854 outl(0x0, devpriv->amcc + AMCC_OP_REG_INTCSR); 855 comedi_pci_detach(dev); 856 } 857 858 static struct comedi_driver apci1500_driver = { 859 .driver_name = "addi_apci_1500", 860 .module = THIS_MODULE, 861 .auto_attach = apci1500_auto_attach, 862 .detach = apci1500_detach, 863 }; 864 865 static int apci1500_pci_probe(struct pci_dev *dev, 866 const struct pci_device_id *id) 867 { 868 return comedi_pci_auto_config(dev, &apci1500_driver, id->driver_data); 869 } 870 871 static const struct pci_device_id apci1500_pci_table[] = { 872 { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80fc) }, 873 { 0 } 874 }; 875 MODULE_DEVICE_TABLE(pci, apci1500_pci_table); 876 877 static struct pci_driver apci1500_pci_driver = { 878 .name = "addi_apci_1500", 879 .id_table = apci1500_pci_table, 880 .probe = apci1500_pci_probe, 881 .remove = comedi_pci_auto_unconfig, 882 }; 883 module_comedi_pci_driver(apci1500_driver, apci1500_pci_driver); 884 885 MODULE_AUTHOR("Comedi https://www.comedi.org"); 886 MODULE_DESCRIPTION("ADDI-DATA APCI-1500, 16 channel DI / 16 channel DO boards"); 887 MODULE_LICENSE("GPL"); 888