Lines Matching +full:msb +full:- +full:justified
1 // SPDX-License-Identifier: GPL-2.0+
14 * Devices: [Keithley Metrabyte] DAS6402-12 (das6402-12),
15 * DAS6402-16 (das6402-16)
17 * Updated: Fri, 14 Mar 2014 10:18:43 -0700
21 * [0] - I/O base address
22 * [1] - IRQ (optional, needed for async command support)
122 .name = "das6402-12",
125 .name = "das6402-16",
138 outb(DAS6402_MODE_ENHANCED | mode, dev->iobase + DAS6402_MODE_REG); in das6402_set_mode()
144 outb(DAS6402_STATUS_W_EXTEND, dev->iobase + DAS6402_STATUS_REG); in das6402_set_extended()
145 outb(DAS6402_STATUS_W_EXTEND | val, dev->iobase + DAS6402_STATUS_REG); in das6402_set_extended()
146 outb(val, dev->iobase + DAS6402_STATUS_REG); in das6402_set_extended()
153 DAS6402_STATUS_W_CLRXIN, dev->iobase + DAS6402_STATUS_REG); in das6402_clear_all_interrupts()
158 outb(DAS6402_STATUS_W_CLRINT, dev->iobase + DAS6402_STATUS_REG); in das6402_ai_clear_eoc()
166 val = inw(dev->iobase + DAS6402_AI_DATA_REG); in das6402_ai_read_sample()
167 if (s->maxdata == 0x0fff) in das6402_ai_read_sample()
175 struct comedi_subdevice *s = dev->read_subdev; in das6402_interrupt()
176 struct comedi_async *async = s->async; in das6402_interrupt()
177 struct comedi_cmd *cmd = &async->cmd; in das6402_interrupt()
180 status = inb(dev->iobase + DAS6402_STATUS_REG); in das6402_interrupt()
185 async->events |= COMEDI_CB_OVERFLOW; in das6402_interrupt()
192 if (cmd->stop_src == TRIG_COUNT && in das6402_interrupt()
193 async->scans_done >= cmd->stop_arg) in das6402_interrupt()
194 async->events |= COMEDI_CB_EOA; in das6402_interrupt()
224 struct das6402_private *devpriv = dev->private; in das6402_ai_cmd()
225 struct comedi_cmd *cmd = &s->async->cmd; in das6402_ai_cmd()
226 unsigned int chan_lo = CR_CHAN(cmd->chanlist[0]); in das6402_ai_cmd()
227 unsigned int chan_hi = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]); in das6402_ai_cmd()
229 das6402_ai_set_mode(dev, s, cmd->chanlist[0], DAS6402_MODE_FIFONEPTY); in das6402_ai_cmd()
233 dev->iobase + DAS6402_AI_MUX_REG); in das6402_ai_cmd()
235 comedi_8254_update_divisors(dev->pacer); in das6402_ai_cmd()
236 comedi_8254_pacer_enable(dev->pacer, 1, 2, true); in das6402_ai_cmd()
240 DAS6402_CTRL_IRQ(devpriv->irq) | in das6402_ai_cmd()
241 DAS6402_CTRL_PACER_TRIG, dev->iobase + DAS6402_CTRL_REG); in das6402_ai_cmd()
250 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); in das6402_ai_check_chanlist()
251 unsigned int range0 = CR_RANGE(cmd->chanlist[0]); in das6402_ai_check_chanlist()
252 unsigned int aref0 = CR_AREF(cmd->chanlist[0]); in das6402_ai_check_chanlist()
255 for (i = 1; i < cmd->chanlist_len; i++) { in das6402_ai_check_chanlist()
256 unsigned int chan = CR_CHAN(cmd->chanlist[i]); in das6402_ai_check_chanlist()
257 unsigned int range = CR_RANGE(cmd->chanlist[i]); in das6402_ai_check_chanlist()
258 unsigned int aref = CR_AREF(cmd->chanlist[i]); in das6402_ai_check_chanlist()
261 dev_dbg(dev->class_dev, in das6402_ai_check_chanlist()
263 return -EINVAL; in das6402_ai_check_chanlist()
267 dev_dbg(dev->class_dev, in das6402_ai_check_chanlist()
269 return -EINVAL; in das6402_ai_check_chanlist()
273 dev_dbg(dev->class_dev, in das6402_ai_check_chanlist()
275 return -EINVAL; in das6402_ai_check_chanlist()
278 if (aref0 == AREF_DIFF && chan > (s->n_chan / 2)) { in das6402_ai_check_chanlist()
279 dev_dbg(dev->class_dev, in das6402_ai_check_chanlist()
281 return -EINVAL; in das6402_ai_check_chanlist()
296 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW); in das6402_ai_cmdtest()
297 err |= comedi_check_trigger_src(&cmd->scan_begin_src, TRIG_FOLLOW); in das6402_ai_cmdtest()
298 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER); in das6402_ai_cmdtest()
299 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); in das6402_ai_cmdtest()
300 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); in das6402_ai_cmdtest()
307 err |= comedi_check_trigger_is_unique(cmd->stop_src); in das6402_ai_cmdtest()
316 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); in das6402_ai_cmdtest()
317 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0); in das6402_ai_cmdtest()
318 err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000); in das6402_ai_cmdtest()
319 err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1); in das6402_ai_cmdtest()
320 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, in das6402_ai_cmdtest()
321 cmd->chanlist_len); in das6402_ai_cmdtest()
323 if (cmd->stop_src == TRIG_COUNT) in das6402_ai_cmdtest()
324 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); in das6402_ai_cmdtest()
326 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); in das6402_ai_cmdtest()
333 arg = cmd->convert_arg; in das6402_ai_cmdtest()
334 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); in das6402_ai_cmdtest()
335 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); in das6402_ai_cmdtest()
341 if (cmd->chanlist && cmd->chanlist_len > 0) in das6402_ai_cmdtest()
353 outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG); in das6402_ai_cancel()
360 outw(0, dev->iobase + DAS6402_AI_DATA_REG); in das6402_ai_soft_trig()
370 status = inb(dev->iobase + DAS6402_STATUS_REG); in das6402_ai_eoc()
373 return -EBUSY; in das6402_ai_eoc()
381 unsigned int chan = CR_CHAN(insn->chanspec); in das6402_ai_insn_read()
382 unsigned int aref = CR_AREF(insn->chanspec); in das6402_ai_insn_read()
386 if (aref == AREF_DIFF && chan > (s->n_chan / 2)) in das6402_ai_insn_read()
387 return -EINVAL; in das6402_ai_insn_read()
390 outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG); in das6402_ai_insn_read()
392 das6402_ai_set_mode(dev, s, insn->chanspec, DAS6402_MODE_POLLED); in das6402_ai_insn_read()
396 dev->iobase + DAS6402_AI_MUX_REG); in das6402_ai_insn_read()
398 for (i = 0; i < insn->n; i++) { in das6402_ai_insn_read()
411 return insn->n; in das6402_ai_insn_read()
419 struct das6402_private *devpriv = dev->private; in das6402_ao_insn_write()
420 unsigned int chan = CR_CHAN(insn->chanspec); in das6402_ao_insn_write()
421 unsigned int range = CR_RANGE(insn->chanspec); in das6402_ao_insn_write()
426 val = devpriv->ao_range; in das6402_ao_insn_write()
429 if (val != devpriv->ao_range) { in das6402_ao_insn_write()
430 devpriv->ao_range = val; in das6402_ao_insn_write()
431 outb(val, dev->iobase + DAS6402_TRIG_REG); in das6402_ao_insn_write()
437 * DAC's. In UPDATE mode, when the MSB is written, that DAC in das6402_ao_insn_write()
446 for (i = 0; i < insn->n; i++) { in das6402_ao_insn_write()
449 s->readback[chan] = val; in das6402_ao_insn_write()
451 if (s->maxdata == 0x0fff) { in das6402_ao_insn_write()
453 * DAS6402/12 has the two 8-bit DAC registers, left in das6402_ao_insn_write()
454 * justified (the 4 LSB bits are don't care). Data in das6402_ao_insn_write()
458 outw(val, dev->iobase + DAS6402_AO_DATA_REG(chan)); in das6402_ao_insn_write()
461 * DAS6402/16 uses both 8-bit DAC registers and needs in das6402_ao_insn_write()
462 * to be written LSB then MSB. in das6402_ao_insn_write()
465 dev->iobase + DAS6402_AO_LSB_REG(chan)); in das6402_ao_insn_write()
467 dev->iobase + DAS6402_AO_LSB_REG(chan)); in das6402_ao_insn_write()
471 return insn->n; in das6402_ao_insn_write()
479 unsigned int chan = CR_CHAN(insn->chanspec); in das6402_ao_insn_read()
485 inw(dev->iobase + DAS6402_AO_LSB_REG(chan)); in das6402_ao_insn_read()
495 data[1] = inb(dev->iobase + DAS6402_DI_DO_REG); in das6402_di_insn_bits()
497 return insn->n; in das6402_di_insn_bits()
506 outb(s->state, dev->iobase + DAS6402_DI_DO_REG); in das6402_do_insn_bits()
508 data[1] = s->state; in das6402_do_insn_bits()
510 return insn->n; in das6402_do_insn_bits()
515 struct das6402_private *devpriv = dev->private; in das6402_reset()
518 outb(DAS6402_MODE_ENHANCED, dev->iobase + DAS6402_MODE_REG); in das6402_reset()
524 outb(DAS6402_CTRL_SOFT_TRIG, dev->iobase + DAS6402_CTRL_REG); in das6402_reset()
526 /* default ADC to single-ended unipolar 10V inputs */ in das6402_reset()
534 dev->iobase + DAS6402_AI_MUX_REG); in das6402_reset()
537 devpriv->ao_range = DAS6402_AO_RANGE(0, 2) | DAS6402_AO_RANGE(1, 2); in das6402_reset()
538 outb(devpriv->ao_range, dev->iobase + DAS6402_TRIG_REG); in das6402_reset()
541 outw(0, dev->iobase + DAS6402_AO_DATA_REG(0)); in das6402_reset()
542 outw(0, dev->iobase + DAS6402_AO_DATA_REG(0)); in das6402_reset()
543 inw(dev->iobase + DAS6402_AO_LSB_REG(0)); in das6402_reset()
546 outb(0, dev->iobase + DAS6402_DI_DO_REG); in das6402_reset()
554 const struct das6402_boardinfo *board = dev->board_ptr; in das6402_attach()
561 return -ENOMEM; in das6402_attach()
563 ret = comedi_request_region(dev, it->options[0], 0x10); in das6402_attach()
570 if ((1 << it->options[1]) & 0x8cec) { in das6402_attach()
571 ret = request_irq(it->options[1], das6402_interrupt, 0, in das6402_attach()
572 dev->board_name, dev); in das6402_attach()
574 dev->irq = it->options[1]; in das6402_attach()
576 switch (dev->irq) { in das6402_attach()
578 devpriv->irq = 4; in das6402_attach()
581 devpriv->irq = 1; in das6402_attach()
584 devpriv->irq = 6; in das6402_attach()
587 devpriv->irq = dev->irq; in das6402_attach()
593 dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS6402_TIMER_BASE, in das6402_attach()
595 if (IS_ERR(dev->pacer)) in das6402_attach()
596 return PTR_ERR(dev->pacer); in das6402_attach()
603 s = &dev->subdevices[0]; in das6402_attach()
604 s->type = COMEDI_SUBD_AI; in das6402_attach()
605 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; in das6402_attach()
606 s->n_chan = 64; in das6402_attach()
607 s->maxdata = board->maxdata; in das6402_attach()
608 s->range_table = &das6402_ai_ranges; in das6402_attach()
609 s->insn_read = das6402_ai_insn_read; in das6402_attach()
610 if (dev->irq) { in das6402_attach()
611 dev->read_subdev = s; in das6402_attach()
612 s->subdev_flags |= SDF_CMD_READ; in das6402_attach()
613 s->len_chanlist = s->n_chan; in das6402_attach()
614 s->do_cmdtest = das6402_ai_cmdtest; in das6402_attach()
615 s->do_cmd = das6402_ai_cmd; in das6402_attach()
616 s->cancel = das6402_ai_cancel; in das6402_attach()
620 s = &dev->subdevices[1]; in das6402_attach()
621 s->type = COMEDI_SUBD_AO; in das6402_attach()
622 s->subdev_flags = SDF_WRITABLE; in das6402_attach()
623 s->n_chan = 2; in das6402_attach()
624 s->maxdata = board->maxdata; in das6402_attach()
625 s->range_table = &das6402_ao_ranges; in das6402_attach()
626 s->insn_write = das6402_ao_insn_write; in das6402_attach()
627 s->insn_read = das6402_ao_insn_read; in das6402_attach()
634 s = &dev->subdevices[2]; in das6402_attach()
635 s->type = COMEDI_SUBD_DI; in das6402_attach()
636 s->subdev_flags = SDF_READABLE; in das6402_attach()
637 s->n_chan = 8; in das6402_attach()
638 s->maxdata = 1; in das6402_attach()
639 s->range_table = &range_digital; in das6402_attach()
640 s->insn_bits = das6402_di_insn_bits; in das6402_attach()
643 s = &dev->subdevices[3]; in das6402_attach()
644 s->type = COMEDI_SUBD_DO; in das6402_attach()
645 s->subdev_flags = SDF_WRITABLE; in das6402_attach()
646 s->n_chan = 8; in das6402_attach()
647 s->maxdata = 1; in das6402_attach()
648 s->range_table = &range_digital; in das6402_attach()
649 s->insn_bits = das6402_do_insn_bits; in das6402_attach()