Lines Matching +full:sdi +full:- +full:enabled

1 // SPDX-License-Identifier: GPL-2.0+
3 * COMEDI driver for the ADLINK PCI-723x/743x series boards.
11 * COMEDI - Linux Control and Measurement Device Interface
17 * Description: 32/64-Channel Isolated Digital I/O Boards
18 * Devices: [ADLink] PCI-7230 (adl_pci7230), PCI-7233 (adl_pci7233),
19 * PCI-7234 (adl_pci7234), PCI-7432 (adl_pci7432), PCI-7433 (adl_pci7433),
20 * PCI-7434 (adl_pci7434)
23 * Status: works (tested on PCI-7230)
29 * PCI-7230 - 4 subdevices: 0 - 16 input, 1 - 16 output,
30 * 2 - IRQ_IDI0, 3 - IRQ_IDI1
31 * PCI-7233 - 1 subdevice: 0 - 32 input
32 * PCI-7234 - 1 subdevice: 0 - 32 output
33 * PCI-7432 - 2 subdevices: 0 - 32 input, 1 - 32 output
34 * PCI-7433 - 2 subdevices: 0 - 32 input, 1 - 32 input
35 * PCI-7434 - 2 subdevices: 0 - 32 output, 1 - 32 output
37 * The PCI-7230, PCI-7432 and PCI-7433 boards also support external
38 * interrupt signals on digital input channels 0 and 1. The PCI-7233
39 * has dual-interrupt sources for change-of-state (COS) on any 16
43 * Currently, this driver only supports interrupts for PCI-7230.
54 * Register I/O map (32-bit access only)
125 spinlock_t subd_slock; /* spin-lock for cmd_running */
133 struct comedi_subdevice *s = &dev->subdevices[subdev]; in process_irq()
134 struct adl_pci7x3x_sd_private_data *sd_priv = s->private; in process_irq()
135 unsigned long reg = sd_priv->port_offset; in process_irq()
136 struct comedi_async *async_p = s->async; in process_irq()
139 unsigned short val = inw(dev->iobase + reg); in process_irq()
141 spin_lock(&sd_priv->subd_slock); in process_irq()
142 if (sd_priv->cmd_running) in process_irq()
144 spin_unlock(&sd_priv->subd_slock); in process_irq()
152 struct adl_pci7x3x_dev_private_data *dev_private = dev->private; in adl_pci7x3x_interrupt()
157 if (!dev->attached) { in adl_pci7x3x_interrupt()
164 spin_lock_irqsave(&dev->spinlock, cpu_flags); in adl_pci7x3x_interrupt()
165 intcsr = inl(dev_private->lcr_io_base + PLX9052_INTCSR); in adl_pci7x3x_interrupt()
171 outb(0x00, dev->iobase + ADL_PT_CLRIRQ); in adl_pci7x3x_interrupt()
173 spin_unlock_irqrestore(&dev->spinlock, cpu_flags); in adl_pci7x3x_interrupt()
177 if (li1stat) /* 0x0005 LINTi1 is Enabled && IDI0 is 1 */ in adl_pci7x3x_interrupt()
180 if (li2stat) /* 0x0028 LINTi2 is Enabled && IDI1 is 1 */ in adl_pci7x3x_interrupt()
194 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW); in adl_pci7x3x_asy_cmdtest()
195 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT); in adl_pci7x3x_asy_cmdtest()
196 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_FOLLOW); in adl_pci7x3x_asy_cmdtest()
197 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in adl_pci7x3x_asy_cmdtest()
198 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_NONE); in adl_pci7x3x_asy_cmdtest()
208 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in adl_pci7x3x_asy_cmdtest()
209 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); in adl_pci7x3x_asy_cmdtest()
210 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0); in adl_pci7x3x_asy_cmdtest()
211 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in adl_pci7x3x_asy_cmdtest()
212 cmd->chanlist_len); in adl_pci7x3x_asy_cmdtest()
213 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in adl_pci7x3x_asy_cmdtest()
228 struct adl_pci7x3x_dev_private_data *dev_private = dev->private; in adl_pci7x3x_asy_cmd()
229 struct adl_pci7x3x_sd_private_data *sd_priv = s->private; in adl_pci7x3x_asy_cmd()
233 if (s->index == 2) { in adl_pci7x3x_asy_cmd()
234 /* enable LINTi1 == IDI sdi[0] Ch 0 IRQ ActHigh */ in adl_pci7x3x_asy_cmd()
237 /* enable LINTi2 == IDI sdi[0] Ch 1 IRQ ActHigh */ in adl_pci7x3x_asy_cmd()
241 spin_lock_irqsave(&dev->spinlock, cpu_flags); in adl_pci7x3x_asy_cmd()
242 dev_private->int_ctrl |= int_enab; in adl_pci7x3x_asy_cmd()
243 outl(dev_private->int_ctrl, dev_private->lcr_io_base + PLX9052_INTCSR); in adl_pci7x3x_asy_cmd()
244 spin_unlock_irqrestore(&dev->spinlock, cpu_flags); in adl_pci7x3x_asy_cmd()
246 spin_lock_irqsave(&sd_priv->subd_slock, cpu_flags); in adl_pci7x3x_asy_cmd()
247 sd_priv->cmd_running = 1; in adl_pci7x3x_asy_cmd()
248 spin_unlock_irqrestore(&sd_priv->subd_slock, cpu_flags); in adl_pci7x3x_asy_cmd()
256 struct adl_pci7x3x_dev_private_data *dev_private = dev->private; in adl_pci7x3x_asy_cancel()
257 struct adl_pci7x3x_sd_private_data *sd_priv = s->private; in adl_pci7x3x_asy_cancel()
261 spin_lock_irqsave(&sd_priv->subd_slock, cpu_flags); in adl_pci7x3x_asy_cancel()
262 sd_priv->cmd_running = 0; in adl_pci7x3x_asy_cancel()
263 spin_unlock_irqrestore(&sd_priv->subd_slock, cpu_flags); in adl_pci7x3x_asy_cancel()
265 if (s->index == 2) in adl_pci7x3x_asy_cancel()
269 spin_lock_irqsave(&dev->spinlock, cpu_flags); in adl_pci7x3x_asy_cancel()
270 dev_private->int_ctrl &= ~int_enab; in adl_pci7x3x_asy_cancel()
271 outl(dev_private->int_ctrl, dev_private->lcr_io_base + PLX9052_INTCSR); in adl_pci7x3x_asy_cancel()
272 spin_unlock_irqrestore(&dev->spinlock, cpu_flags); in adl_pci7x3x_asy_cancel()
277 /* same as _di_insn_bits because the IRQ-pins are the DI-ports */
283 struct adl_pci7x3x_sd_private_data *sd_priv = s->private; in adl_pci7x3x_dirq_insn_bits()
284 unsigned long reg = (unsigned long)sd_priv->port_offset; in adl_pci7x3x_dirq_insn_bits()
286 data[1] = inl(dev->iobase + reg); in adl_pci7x3x_dirq_insn_bits()
288 return insn->n; in adl_pci7x3x_dirq_insn_bits()
296 unsigned long reg = (unsigned long)s->private; in adl_pci7x3x_do_insn_bits()
299 unsigned int val = s->state; in adl_pci7x3x_do_insn_bits()
301 if (s->n_chan == 16) { in adl_pci7x3x_do_insn_bits()
303 * It seems the PCI-7230 needs the 16-bit DO state in adl_pci7x3x_do_insn_bits()
305 * to the 32-bit register. Set the value in both in adl_pci7x3x_do_insn_bits()
310 outl(val, dev->iobase + reg); in adl_pci7x3x_do_insn_bits()
313 data[1] = s->state; in adl_pci7x3x_do_insn_bits()
315 return insn->n; in adl_pci7x3x_do_insn_bits()
323 unsigned long reg = (unsigned long)s->private; in adl_pci7x3x_di_insn_bits()
325 data[1] = inl(dev->iobase + reg); in adl_pci7x3x_di_insn_bits()
327 return insn->n; in adl_pci7x3x_di_insn_bits()
332 struct adl_pci7x3x_dev_private_data *dev_private = dev->private; in adl_pci7x3x_reset()
335 dev_private->int_ctrl = 0x00; /* Disable PCI + LINTi2 + LINTi1 */ in adl_pci7x3x_reset()
336 outl(dev_private->int_ctrl, dev_private->lcr_io_base + PLX9052_INTCSR); in adl_pci7x3x_reset()
356 return -ENODEV; in adl_pci7x3x_auto_attach()
357 dev->board_ptr = board; in adl_pci7x3x_auto_attach()
358 dev->board_name = board->name; in adl_pci7x3x_auto_attach()
362 return -ENOMEM; in adl_pci7x3x_auto_attach()
367 dev->iobase = pci_resource_start(pcidev, 2); in adl_pci7x3x_auto_attach()
368 dev_private->lcr_io_base = pci_resource_start(pcidev, 1); in adl_pci7x3x_auto_attach()
372 if (board->irq_nchan) { in adl_pci7x3x_auto_attach()
374 outb(0x00, dev->iobase + ADL_PT_CLRIRQ); in adl_pci7x3x_auto_attach()
376 if (pcidev->irq) { in adl_pci7x3x_auto_attach()
377 ret = request_irq(pcidev->irq, adl_pci7x3x_interrupt, in adl_pci7x3x_auto_attach()
378 IRQF_SHARED, dev->board_name, dev); in adl_pci7x3x_auto_attach()
380 dev->irq = pcidev->irq; in adl_pci7x3x_auto_attach()
382 dev_private->int_ctrl = EN_PCI_LINT2H_LINT1H; in adl_pci7x3x_auto_attach()
383 outl(dev_private->int_ctrl, in adl_pci7x3x_auto_attach()
384 dev_private->lcr_io_base + PLX9052_INTCSR); in adl_pci7x3x_auto_attach()
389 ret = comedi_alloc_subdevices(dev, board->nsubdevs); in adl_pci7x3x_auto_attach()
395 if (board->di_nchan) { in adl_pci7x3x_auto_attach()
396 nchan = min(board->di_nchan, 32); in adl_pci7x3x_auto_attach()
398 s = &dev->subdevices[subdev]; in adl_pci7x3x_auto_attach()
400 s->type = COMEDI_SUBD_DI; in adl_pci7x3x_auto_attach()
401 s->subdev_flags = SDF_READABLE; in adl_pci7x3x_auto_attach()
402 s->n_chan = nchan; in adl_pci7x3x_auto_attach()
403 s->maxdata = 1; in adl_pci7x3x_auto_attach()
404 s->insn_bits = adl_pci7x3x_di_insn_bits; in adl_pci7x3x_auto_attach()
405 s->range_table = &range_digital; in adl_pci7x3x_auto_attach()
407 s->private = (void *)PCI7X3X_DIO_REG; in adl_pci7x3x_auto_attach()
411 nchan = board->di_nchan - nchan; in adl_pci7x3x_auto_attach()
413 s = &dev->subdevices[subdev]; in adl_pci7x3x_auto_attach()
415 s->type = COMEDI_SUBD_DI; in adl_pci7x3x_auto_attach()
416 s->subdev_flags = SDF_READABLE; in adl_pci7x3x_auto_attach()
417 s->n_chan = nchan; in adl_pci7x3x_auto_attach()
418 s->maxdata = 1; in adl_pci7x3x_auto_attach()
419 s->insn_bits = adl_pci7x3x_di_insn_bits; in adl_pci7x3x_auto_attach()
420 s->range_table = &range_digital; in adl_pci7x3x_auto_attach()
422 s->private = (void *)PCI743X_DIO_REG; in adl_pci7x3x_auto_attach()
428 if (board->do_nchan) { in adl_pci7x3x_auto_attach()
429 nchan = min(board->do_nchan, 32); in adl_pci7x3x_auto_attach()
431 s = &dev->subdevices[subdev]; in adl_pci7x3x_auto_attach()
433 s->type = COMEDI_SUBD_DO; in adl_pci7x3x_auto_attach()
434 s->subdev_flags = SDF_WRITABLE; in adl_pci7x3x_auto_attach()
435 s->n_chan = nchan; in adl_pci7x3x_auto_attach()
436 s->maxdata = 1; in adl_pci7x3x_auto_attach()
437 s->insn_bits = adl_pci7x3x_do_insn_bits; in adl_pci7x3x_auto_attach()
438 s->range_table = &range_digital; in adl_pci7x3x_auto_attach()
440 s->private = (void *)PCI7X3X_DIO_REG; in adl_pci7x3x_auto_attach()
444 nchan = board->do_nchan - nchan; in adl_pci7x3x_auto_attach()
446 s = &dev->subdevices[subdev]; in adl_pci7x3x_auto_attach()
448 s->type = COMEDI_SUBD_DO; in adl_pci7x3x_auto_attach()
449 s->subdev_flags = SDF_WRITABLE; in adl_pci7x3x_auto_attach()
450 s->n_chan = nchan; in adl_pci7x3x_auto_attach()
451 s->maxdata = 1; in adl_pci7x3x_auto_attach()
452 s->insn_bits = adl_pci7x3x_do_insn_bits; in adl_pci7x3x_auto_attach()
453 s->range_table = &range_digital; in adl_pci7x3x_auto_attach()
455 s->private = (void *)PCI743X_DIO_REG; in adl_pci7x3x_auto_attach()
461 for (ic = 0; ic < board->irq_nchan; ++ic) { in adl_pci7x3x_auto_attach()
466 s = &dev->subdevices[subdev]; in adl_pci7x3x_auto_attach()
468 s->type = COMEDI_SUBD_DI; in adl_pci7x3x_auto_attach()
469 s->subdev_flags = SDF_READABLE; in adl_pci7x3x_auto_attach()
470 s->n_chan = nchan; in adl_pci7x3x_auto_attach()
471 s->maxdata = 1; in adl_pci7x3x_auto_attach()
472 s->insn_bits = adl_pci7x3x_dirq_insn_bits; in adl_pci7x3x_auto_attach()
473 s->range_table = &range_digital; in adl_pci7x3x_auto_attach()
477 return -ENOMEM; in adl_pci7x3x_auto_attach()
479 spin_lock_init(&sd_priv->subd_slock); in adl_pci7x3x_auto_attach()
480 sd_priv->port_offset = PCI7X3X_DIO_REG; in adl_pci7x3x_auto_attach()
481 sd_priv->cmd_running = 0; in adl_pci7x3x_auto_attach()
483 if (dev->irq) { in adl_pci7x3x_auto_attach()
484 dev->read_subdev = s; in adl_pci7x3x_auto_attach()
485 s->type = COMEDI_SUBD_DI; in adl_pci7x3x_auto_attach()
486 s->subdev_flags = SDF_READABLE | SDF_CMD_READ; in adl_pci7x3x_auto_attach()
487 s->len_chanlist = 1; in adl_pci7x3x_auto_attach()
488 s->do_cmdtest = adl_pci7x3x_asy_cmdtest; in adl_pci7x3x_auto_attach()
489 s->do_cmd = adl_pci7x3x_asy_cmd; in adl_pci7x3x_auto_attach()
490 s->cancel = adl_pci7x3x_asy_cancel; in adl_pci7x3x_auto_attach()
501 if (dev->iobase) in adl_pci7x3x_detach()
517 id->driver_data); in adl_pci7x3x_pci_probe()
539 MODULE_DESCRIPTION("ADLINK PCI-723x/743x Isolated Digital I/O boards");