Lines Matching +full:board +full:- +full:control

1 // SPDX-License-Identifier: GPL-2.0
13 * Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
14 * PCI-1734, PCI-1735U, PCI-1736UP, PCI-1739U, PCI-1750,
15 * PCI-1751, PCI-1752, PCI-1753, PCI-1753+PCI-1753E,
16 * PCI-1754, PCI-1756, PCI-1761, PCI-1762
34 /* PCI-1730, PCI-1733, PCI-1736 interrupt control registers */
45 /* PCI-1739U, PCI-1750, PCI1751 interrupt control registers */
46 #define PCI1750_INT_REG 0x20 /* R/W: status/control */
48 /* PCI-1753, PCI-1753E interrupt control registers */
49 #define PCI1753_INT_REG(x) (0x10 + (x)) /* R/W: control group 0 to 3 */
50 #define PCI1753E_INT_REG(x) (0x30 + (x)) /* R/W: control group 0 to 3 */
52 /* PCI-1754, PCI-1756 interrupt control registers */
53 #define PCI1754_INT_REG(x) (0x08 + (x) * 2) /* R/W: control group 0 to 3 */
55 /* PCI-1752, PCI-1756 special registers */
58 /* PCI-1761 interrupt control registers */
63 /* PCI-1762 interrupt control registers */
64 #define PCI1762_INT_REG 0x06 /* R/W: status/control */
101 const char *name; /* board name */
117 .sdi[0] = { 16, 0x02, }, /* DI 0-15 */
118 .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */
119 .sdo[0] = { 16, 0x02, }, /* DO 0-15 */
120 .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
130 .sdi[1] = { 32, 0x00, }, /* ISO DI 0-31 */
136 .sdo[1] = { 32, 0x00, }, /* ISO DO 0-31 */
142 .sdi[0] = { 32, 0x00, }, /* DI 0-31 */
143 .sdo[0] = { 32, 0x00, }, /* DO 0-31 */
150 .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */
151 .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
163 .sdi[1] = { 16, 0x00, }, /* ISO DI 0-15 */
164 .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
175 .sdo[0] = { 32, 0x00, }, /* DO 0-31 */
176 .sdo[1] = { 32, 0x04, }, /* DO 32-63 */
194 .sdi[0] = { 32, 0x00, }, /* DI 0-31 */
195 .sdi[1] = { 32, 0x04, }, /* DI 32-63 */
202 .sdi[1] = { 32, 0x00, }, /* DI 0-31 */
203 .sdo[1] = { 32, 0x04, }, /* DO 0-31 */
210 .sdi[1] = { 8, 0x01 }, /* ISO DI 0-7 */
211 .sdo[1] = { 8, 0x00 }, /* RELAY DO 0-7 */
217 .sdi[1] = { 16, 0x02, }, /* ISO DI 0-15 */
218 .sdo[1] = { 16, 0x00, }, /* ISO DO 0-15 */
232 spinlock_t subd_slock; /* spin-lock for cmd_running */
240 struct comedi_subdevice *s = &dev->subdevices[subdev]; in process_irq()
241 struct pci_dio_sd_private_data *sd_priv = s->private; in process_irq()
242 unsigned long reg = sd_priv->port_offset; in process_irq()
243 struct comedi_async *async_p = s->async; in process_irq()
246 unsigned short val = inw(dev->iobase + reg); in process_irq()
248 spin_lock(&sd_priv->subd_slock); in process_irq()
249 if (sd_priv->cmd_running) in process_irq()
251 spin_unlock(&sd_priv->subd_slock); in process_irq()
259 struct pci_dio_dev_private_data *dev_private = dev->private; in pci_dio_interrupt()
260 const struct dio_boardtype *board = dev->board_ptr; in pci_dio_interrupt() local
265 if (!dev->attached) { in pci_dio_interrupt()
272 spin_lock_irqsave(&dev->spinlock, cpu_flags); in pci_dio_interrupt()
273 irqflags = inb(dev->iobase + PCI173X_INT_FLAG_REG); in pci_dio_interrupt()
275 spin_unlock_irqrestore(&dev->spinlock, cpu_flags); in pci_dio_interrupt()
280 outb(irqflags, dev->iobase + PCI173X_INT_CLR_REG); in pci_dio_interrupt()
281 spin_unlock_irqrestore(&dev->spinlock, cpu_flags); in pci_dio_interrupt()
285 if (irqflags & board->sdirq[i].int_en) in pci_dio_interrupt()
286 process_irq(dev, dev_private->irq_subd + i, irqflags); in pci_dio_interrupt()
300 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW); in pci_dio_asy_cmdtest()
301 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); in pci_dio_asy_cmdtest()
302 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); in pci_dio_asy_cmdtest()
303 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in pci_dio_asy_cmdtest()
304 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE); in pci_dio_asy_cmdtest()
314 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in pci_dio_asy_cmdtest()
320 if (cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) { in pci_dio_asy_cmdtest()
321 cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT); in pci_dio_asy_cmdtest()
322 err |= -EINVAL; in pci_dio_asy_cmdtest()
324 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); in pci_dio_asy_cmdtest()
325 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in pci_dio_asy_cmdtest()
326 cmd->chanlist_len); in pci_dio_asy_cmdtest()
327 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in pci_dio_asy_cmdtest()
342 struct pci_dio_dev_private_data *dev_private = dev->private; in pci_dio_asy_cmd()
343 struct pci_dio_sd_private_data *sd_priv = s->private; in pci_dio_asy_cmd()
344 const struct dio_boardtype *board = dev->board_ptr; in pci_dio_asy_cmd() local
345 struct comedi_cmd *cmd = &s->async->cmd; in pci_dio_asy_cmd()
349 int_en = board->sdirq[s->index - dev_private->irq_subd].int_en; in pci_dio_asy_cmd()
351 spin_lock_irqsave(&dev->spinlock, cpu_flags); in pci_dio_asy_cmd()
352 if (cmd->scan_begin_arg & CR_INVERT) in pci_dio_asy_cmd()
353 dev_private->int_rf |= int_en; /* falling edge */ in pci_dio_asy_cmd()
355 dev_private->int_rf &= ~int_en; /* rising edge */ in pci_dio_asy_cmd()
356 outb(dev_private->int_rf, dev->iobase + PCI173X_INT_RF_REG); in pci_dio_asy_cmd()
357 dev_private->int_ctrl |= int_en; /* enable interrupt source */ in pci_dio_asy_cmd()
358 outb(dev_private->int_ctrl, dev->iobase + PCI173X_INT_EN_REG); in pci_dio_asy_cmd()
359 spin_unlock_irqrestore(&dev->spinlock, cpu_flags); in pci_dio_asy_cmd()
361 spin_lock_irqsave(&sd_priv->subd_slock, cpu_flags); in pci_dio_asy_cmd()
362 sd_priv->cmd_running = 1; in pci_dio_asy_cmd()
363 spin_unlock_irqrestore(&sd_priv->subd_slock, cpu_flags); in pci_dio_asy_cmd()
371 struct pci_dio_dev_private_data *dev_private = dev->private; in pci_dio_asy_cancel()
372 struct pci_dio_sd_private_data *sd_priv = s->private; in pci_dio_asy_cancel()
373 const struct dio_boardtype *board = dev->board_ptr; in pci_dio_asy_cancel() local
377 spin_lock_irqsave(&sd_priv->subd_slock, cpu_flags); in pci_dio_asy_cancel()
378 sd_priv->cmd_running = 0; in pci_dio_asy_cancel()
379 spin_unlock_irqrestore(&sd_priv->subd_slock, cpu_flags); in pci_dio_asy_cancel()
381 int_en = board->sdirq[s->index - dev_private->irq_subd].int_en; in pci_dio_asy_cancel()
383 spin_lock_irqsave(&dev->spinlock, cpu_flags); in pci_dio_asy_cancel()
384 dev_private->int_ctrl &= ~int_en; in pci_dio_asy_cancel()
385 outb(dev_private->int_ctrl, dev->iobase + PCI173X_INT_EN_REG); in pci_dio_asy_cancel()
386 spin_unlock_irqrestore(&dev->spinlock, cpu_flags); in pci_dio_asy_cancel()
391 /* same as _insn_bits_di_ because the IRQ-pins are the DI-ports */
397 struct pci_dio_sd_private_data *sd_priv = s->private; in pci_dio_insn_bits_dirq_b()
398 unsigned long reg = (unsigned long)sd_priv->port_offset; in pci_dio_insn_bits_dirq_b()
399 unsigned long iobase = dev->iobase + reg; in pci_dio_insn_bits_dirq_b()
403 return insn->n; in pci_dio_insn_bits_dirq_b()
411 unsigned long reg = (unsigned long)s->private; in pci_dio_insn_bits_di_b()
412 unsigned long iobase = dev->iobase + reg; in pci_dio_insn_bits_di_b()
415 if (s->n_chan > 8) in pci_dio_insn_bits_di_b()
417 if (s->n_chan > 16) in pci_dio_insn_bits_di_b()
419 if (s->n_chan > 24) in pci_dio_insn_bits_di_b()
422 return insn->n; in pci_dio_insn_bits_di_b()
430 unsigned long reg = (unsigned long)s->private; in pci_dio_insn_bits_di_w()
431 unsigned long iobase = dev->iobase + reg; in pci_dio_insn_bits_di_w()
434 if (s->n_chan > 16) in pci_dio_insn_bits_di_w()
437 return insn->n; in pci_dio_insn_bits_di_w()
445 unsigned long reg = (unsigned long)s->private; in pci_dio_insn_bits_do_b()
446 unsigned long iobase = dev->iobase + reg; in pci_dio_insn_bits_do_b()
449 outb(s->state & 0xff, iobase); in pci_dio_insn_bits_do_b()
450 if (s->n_chan > 8) in pci_dio_insn_bits_do_b()
451 outb((s->state >> 8) & 0xff, iobase + 1); in pci_dio_insn_bits_do_b()
452 if (s->n_chan > 16) in pci_dio_insn_bits_do_b()
453 outb((s->state >> 16) & 0xff, iobase + 2); in pci_dio_insn_bits_do_b()
454 if (s->n_chan > 24) in pci_dio_insn_bits_do_b()
455 outb((s->state >> 24) & 0xff, iobase + 3); in pci_dio_insn_bits_do_b()
458 data[1] = s->state; in pci_dio_insn_bits_do_b()
460 return insn->n; in pci_dio_insn_bits_do_b()
468 unsigned long reg = (unsigned long)s->private; in pci_dio_insn_bits_do_w()
469 unsigned long iobase = dev->iobase + reg; in pci_dio_insn_bits_do_w()
472 outw(s->state & 0xffff, iobase); in pci_dio_insn_bits_do_w()
473 if (s->n_chan > 16) in pci_dio_insn_bits_do_w()
474 outw((s->state >> 16) & 0xffff, iobase + 2); in pci_dio_insn_bits_do_w()
477 data[1] = s->state; in pci_dio_insn_bits_do_w()
479 return insn->n; in pci_dio_insn_bits_do_w()
484 struct pci_dio_dev_private_data *dev_private = dev->private; in pci_dio_reset()
485 /* disable channel freeze function on the PCI-1752/1756 boards */ in pci_dio_reset()
487 outw(0, dev->iobase + PCI1752_CFC_REG); in pci_dio_reset()
494 dev_private->int_ctrl = 0x00; in pci_dio_reset()
495 outb(dev_private->int_ctrl, dev->iobase + PCI173X_INT_EN_REG); in pci_dio_reset()
497 outb(0x0f, dev->iobase + PCI173X_INT_CLR_REG); in pci_dio_reset()
499 dev_private->int_rf = 0x00; in pci_dio_reset()
500 outb(dev_private->int_rf, dev->iobase + PCI173X_INT_RF_REG); in pci_dio_reset()
505 outb(0x88, dev->iobase + PCI1750_INT_REG); in pci_dio_reset()
509 outb(0x88, dev->iobase + PCI1753_INT_REG(0)); in pci_dio_reset()
510 outb(0x80, dev->iobase + PCI1753_INT_REG(1)); in pci_dio_reset()
511 outb(0x80, dev->iobase + PCI1753_INT_REG(2)); in pci_dio_reset()
512 outb(0x80, dev->iobase + PCI1753_INT_REG(3)); in pci_dio_reset()
514 outb(0x88, dev->iobase + PCI1753E_INT_REG(0)); in pci_dio_reset()
515 outb(0x80, dev->iobase + PCI1753E_INT_REG(1)); in pci_dio_reset()
516 outb(0x80, dev->iobase + PCI1753E_INT_REG(2)); in pci_dio_reset()
517 outb(0x80, dev->iobase + PCI1753E_INT_REG(3)); in pci_dio_reset()
522 outw(0x08, dev->iobase + PCI1754_INT_REG(0)); in pci_dio_reset()
523 outw(0x08, dev->iobase + PCI1754_INT_REG(1)); in pci_dio_reset()
525 outw(0x08, dev->iobase + PCI1754_INT_REG(2)); in pci_dio_reset()
526 outw(0x08, dev->iobase + PCI1754_INT_REG(3)); in pci_dio_reset()
531 outb(0, dev->iobase + PCI1761_INT_EN_REG); in pci_dio_reset()
533 outb(0xff, dev->iobase + PCI1761_INT_CLR_REG); in pci_dio_reset()
535 outb(0, dev->iobase + PCI1761_INT_RF_REG); in pci_dio_reset()
538 outw(0x0101, dev->iobase + PCI1762_INT_REG); in pci_dio_reset()
551 const struct dio_boardtype *board = NULL; in pci_dio_auto_attach() local
557 board = &boardtypes[context]; in pci_dio_auto_attach()
558 if (!board) in pci_dio_auto_attach()
559 return -ENODEV; in pci_dio_auto_attach()
560 dev->board_ptr = board; in pci_dio_auto_attach()
561 dev->board_name = board->name; in pci_dio_auto_attach()
565 return -ENOMEM; in pci_dio_auto_attach()
571 dev->iobase = pci_resource_start(pcidev, 0); in pci_dio_auto_attach()
573 dev->iobase = pci_resource_start(pcidev, 2); in pci_dio_auto_attach()
575 dev_private->boardtype = context; in pci_dio_auto_attach()
579 if (board->sdirq[0].int_en && pcidev->irq) { in pci_dio_auto_attach()
580 ret = request_irq(pcidev->irq, pci_dio_interrupt, IRQF_SHARED, in pci_dio_auto_attach()
581 dev->board_name, dev); in pci_dio_auto_attach()
583 dev->irq = pcidev->irq; in pci_dio_auto_attach()
586 ret = comedi_alloc_subdevices(dev, board->nsubdevs); in pci_dio_auto_attach()
592 const struct diosubd_data *d = &board->sdi[i]; in pci_dio_auto_attach()
594 if (d->chans) { in pci_dio_auto_attach()
595 s = &dev->subdevices[subdev++]; in pci_dio_auto_attach()
596 s->type = COMEDI_SUBD_DI; in pci_dio_auto_attach()
597 s->subdev_flags = SDF_READABLE; in pci_dio_auto_attach()
598 s->n_chan = d->chans; in pci_dio_auto_attach()
599 s->maxdata = 1; in pci_dio_auto_attach()
600 s->range_table = &range_digital; in pci_dio_auto_attach()
601 s->insn_bits = board->is_16bit in pci_dio_auto_attach()
604 s->private = (void *)d->addr; in pci_dio_auto_attach()
609 const struct diosubd_data *d = &board->sdo[i]; in pci_dio_auto_attach()
611 if (d->chans) { in pci_dio_auto_attach()
612 s = &dev->subdevices[subdev++]; in pci_dio_auto_attach()
613 s->type = COMEDI_SUBD_DO; in pci_dio_auto_attach()
614 s->subdev_flags = SDF_WRITABLE; in pci_dio_auto_attach()
615 s->n_chan = d->chans; in pci_dio_auto_attach()
616 s->maxdata = 1; in pci_dio_auto_attach()
617 s->range_table = &range_digital; in pci_dio_auto_attach()
618 s->insn_bits = board->is_16bit in pci_dio_auto_attach()
621 s->private = (void *)d->addr; in pci_dio_auto_attach()
624 if (board->is_16bit) { in pci_dio_auto_attach()
625 outw(0, dev->iobase + d->addr); in pci_dio_auto_attach()
626 if (s->n_chan > 16) in pci_dio_auto_attach()
627 outw(0, dev->iobase + d->addr + 2); in pci_dio_auto_attach()
629 outb(0, dev->iobase + d->addr); in pci_dio_auto_attach()
630 if (s->n_chan > 8) in pci_dio_auto_attach()
631 outb(0, dev->iobase + d->addr + 1); in pci_dio_auto_attach()
632 if (s->n_chan > 16) in pci_dio_auto_attach()
633 outb(0, dev->iobase + d->addr + 2); in pci_dio_auto_attach()
634 if (s->n_chan > 24) in pci_dio_auto_attach()
635 outb(0, dev->iobase + d->addr + 3); in pci_dio_auto_attach()
641 const struct diosubd_data *d = &board->sdio[i]; in pci_dio_auto_attach()
643 for (j = 0; j < d->chans; j++) { in pci_dio_auto_attach()
644 s = &dev->subdevices[subdev++]; in pci_dio_auto_attach()
646 d->addr + j * I8255_SIZE); in pci_dio_auto_attach()
652 if (board->id_reg) { in pci_dio_auto_attach()
653 s = &dev->subdevices[subdev++]; in pci_dio_auto_attach()
654 s->type = COMEDI_SUBD_DI; in pci_dio_auto_attach()
655 s->subdev_flags = SDF_READABLE | SDF_INTERNAL; in pci_dio_auto_attach()
656 s->n_chan = 4; in pci_dio_auto_attach()
657 s->maxdata = 1; in pci_dio_auto_attach()
658 s->range_table = &range_digital; in pci_dio_auto_attach()
659 s->insn_bits = board->is_16bit ? pci_dio_insn_bits_di_w in pci_dio_auto_attach()
661 s->private = (void *)board->id_reg; in pci_dio_auto_attach()
664 if (board->timer_regbase) { in pci_dio_auto_attach()
665 s = &dev->subdevices[subdev++]; in pci_dio_auto_attach()
667 dev->pacer = in pci_dio_auto_attach()
668 comedi_8254_io_alloc(dev->iobase + board->timer_regbase, in pci_dio_auto_attach()
670 if (IS_ERR(dev->pacer)) in pci_dio_auto_attach()
671 return PTR_ERR(dev->pacer); in pci_dio_auto_attach()
673 comedi_8254_subdevice_init(s, dev->pacer); in pci_dio_auto_attach()
676 dev_private->irq_subd = subdev; /* first interrupt subdevice index */ in pci_dio_auto_attach()
679 const struct dio_irq_subd_data *d = &board->sdirq[i]; in pci_dio_auto_attach()
681 if (d->int_en) { in pci_dio_auto_attach()
682 s = &dev->subdevices[subdev++]; in pci_dio_auto_attach()
683 s->type = COMEDI_SUBD_DI; in pci_dio_auto_attach()
684 s->subdev_flags = SDF_READABLE; in pci_dio_auto_attach()
685 s->n_chan = 1; in pci_dio_auto_attach()
686 s->maxdata = 1; in pci_dio_auto_attach()
687 s->range_table = &range_digital; in pci_dio_auto_attach()
688 s->insn_bits = pci_dio_insn_bits_dirq_b; in pci_dio_auto_attach()
691 return -ENOMEM; in pci_dio_auto_attach()
693 spin_lock_init(&sd_priv->subd_slock); in pci_dio_auto_attach()
694 sd_priv->port_offset = d->addr; in pci_dio_auto_attach()
695 sd_priv->cmd_running = 0; in pci_dio_auto_attach()
697 if (dev->irq) { in pci_dio_auto_attach()
698 dev->read_subdev = s; in pci_dio_auto_attach()
699 s->type = COMEDI_SUBD_DI; in pci_dio_auto_attach()
700 s->subdev_flags = SDF_READABLE | SDF_CMD_READ; in pci_dio_auto_attach()
701 s->len_chanlist = 1; in pci_dio_auto_attach()
702 s->do_cmdtest = pci_dio_asy_cmdtest; in pci_dio_auto_attach()
703 s->do_cmd = pci_dio_asy_cmd; in pci_dio_auto_attach()
704 s->cancel = pci_dio_asy_cancel; in pci_dio_auto_attach()
714 struct pci_dio_dev_private_data *dev_private = dev->private; in pci_dio_detach()
715 int boardtype = dev_private->boardtype; in pci_dio_detach()
717 if (dev->iobase) in pci_dio_detach()
734 * board available. Need to enable PCI device and request the main in pci_dio_override_cardtype()
766 cardtype = pci_dio_override_cardtype(dev, id->driver_data); in adv_pci_dio_pci_probe()