1 // SPDX-License-Identifier: GPL-2.0+
3 * comedi/drivers/ni_labpc_common.c
5 * Common support code for "ni_labpc", "ni_labpc_pci" and "ni_labpc_cs".
7 * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net>
10 #include <linux/module.h>
11 #include <linux/interrupt.h>
13 #include <linux/delay.h>
14 #include <linux/slab.h>
15 #include <linux/comedi/comedidev.h>
16 #include <linux/comedi/comedi_8255.h>
17 #include <linux/comedi/comedi_8254.h>
20 #include "ni_labpc_regs.h"
21 #include "ni_labpc_isadma.h"
25 MODE_SINGLE_CHAN_INTERVAL,
30 static const struct comedi_lrange range_labpc_plus_ai = {
51 static const struct comedi_lrange range_labpc_1200_ai = {
70 static const struct comedi_lrange range_labpc_ao = {
78 * functions that do inb/outb and readb/writeb so we can use
79 * function pointers to decide which to use
82 #ifdef CONFIG_HAS_IOPORT
84 static unsigned int labpc_inb(struct comedi_device *dev, unsigned long reg)
86 return inb(dev->iobase + reg);
89 static void labpc_outb(struct comedi_device *dev,
90 unsigned int byte, unsigned long reg)
92 outb(byte, dev->iobase + reg);
95 #endif /* CONFIG_HAS_IOPORT */
97 static unsigned int labpc_readb(struct comedi_device *dev, unsigned long reg)
99 return readb(dev->mmio + reg);
102 static void labpc_writeb(struct comedi_device *dev,
103 unsigned int byte, unsigned long reg)
105 writeb(byte, dev->mmio + reg);
108 static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
110 struct labpc_private *devpriv = dev->private;
113 spin_lock_irqsave(&dev->spinlock, flags);
114 devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
115 devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
116 spin_unlock_irqrestore(&dev->spinlock, flags);
119 devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
124 static void labpc_ai_set_chan_and_gain(struct comedi_device *dev,
130 const struct labpc_boardinfo *board = dev->board_ptr;
131 struct labpc_private *devpriv = dev->private;
133 if (board->is_labpc1200) {
135 * The LabPC-1200 boards do not have a gain
136 * of '0x10'. Skip the range values that would
137 * result in this gain.
139 range += (range > 0) + (range > 7);
142 /* munge channel bits for differential/scan disabled mode */
143 if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) &&
146 devpriv->cmd1 = CMD1_MA(chan);
147 devpriv->cmd1 |= CMD1_GAIN(range);
149 devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
152 static void labpc_setup_cmd6_reg(struct comedi_device *dev,
153 struct comedi_subdevice *s,
155 enum transfer_type xfer,
160 const struct labpc_boardinfo *board = dev->board_ptr;
161 struct labpc_private *devpriv = dev->private;
163 if (!board->is_labpc1200)
166 /* reference inputs to ground or common? */
167 if (aref != AREF_GROUND)
168 devpriv->cmd6 |= CMD6_NRSE;
170 devpriv->cmd6 &= ~CMD6_NRSE;
172 /* bipolar or unipolar range? */
173 if (comedi_range_is_unipolar(s, range))
174 devpriv->cmd6 |= CMD6_ADCUNI;
176 devpriv->cmd6 &= ~CMD6_ADCUNI;
178 /* interrupt on fifo half full? */
179 if (xfer == fifo_half_full_transfer)
180 devpriv->cmd6 |= CMD6_HFINTEN;
182 devpriv->cmd6 &= ~CMD6_HFINTEN;
184 /* enable interrupt on counter a1 terminal count? */
186 devpriv->cmd6 |= CMD6_DQINTEN;
188 devpriv->cmd6 &= ~CMD6_DQINTEN;
190 /* are we scanning up or down through channels? */
191 if (mode == MODE_MULT_CHAN_UP)
192 devpriv->cmd6 |= CMD6_SCANUP;
194 devpriv->cmd6 &= ~CMD6_SCANUP;
196 devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
199 static unsigned int labpc_read_adc_fifo(struct comedi_device *dev)
201 struct labpc_private *devpriv = dev->private;
202 unsigned int lsb = devpriv->read_byte(dev, ADC_FIFO_REG);
203 unsigned int msb = devpriv->read_byte(dev, ADC_FIFO_REG);
205 return (msb << 8) | lsb;
208 static void labpc_clear_adc_fifo(struct comedi_device *dev)
210 struct labpc_private *devpriv = dev->private;
212 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
213 labpc_read_adc_fifo(dev);
216 static int labpc_ai_eoc(struct comedi_device *dev,
217 struct comedi_subdevice *s,
218 struct comedi_insn *insn,
219 unsigned long context)
221 struct labpc_private *devpriv = dev->private;
223 devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
224 if (devpriv->stat1 & STAT1_DAVAIL)
229 static int labpc_ai_insn_read(struct comedi_device *dev,
230 struct comedi_subdevice *s,
231 struct comedi_insn *insn,
234 struct labpc_private *devpriv = dev->private;
235 unsigned int chan = CR_CHAN(insn->chanspec);
236 unsigned int range = CR_RANGE(insn->chanspec);
237 unsigned int aref = CR_AREF(insn->chanspec);
241 /* disable timed conversions, interrupt generation and dma */
242 labpc_cancel(dev, s);
244 labpc_ai_set_chan_and_gain(dev, MODE_SINGLE_CHAN, chan, range, aref);
246 labpc_setup_cmd6_reg(dev, s, MODE_SINGLE_CHAN, fifo_not_empty_transfer,
249 /* setup cmd4 register */
251 devpriv->cmd4 |= CMD4_ECLKRCV;
252 /* single-ended/differential */
253 if (aref == AREF_DIFF)
254 devpriv->cmd4 |= CMD4_SEDIFF;
255 devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
257 /* initialize pacer counter to prevent any problems */
258 comedi_8254_set_mode(devpriv->counter, 0, I8254_MODE2 | I8254_BINARY);
260 labpc_clear_adc_fifo(dev);
262 for (i = 0; i < insn->n; i++) {
263 /* trigger conversion */
264 devpriv->write_byte(dev, 0x1, ADC_START_CONVERT_REG);
266 ret = comedi_timeout(dev, s, insn, labpc_ai_eoc, 0);
270 data[i] = labpc_read_adc_fifo(dev);
276 static bool labpc_use_continuous_mode(const struct comedi_cmd *cmd,
279 if (mode == MODE_SINGLE_CHAN || cmd->scan_begin_src == TRIG_FOLLOW)
285 static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd,
288 if (cmd->convert_src != TRIG_TIMER)
291 if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER)
292 return cmd->scan_begin_arg;
294 return cmd->convert_arg;
297 static void labpc_set_ai_convert_period(struct comedi_cmd *cmd,
298 enum scan_mode mode, unsigned int ns)
300 if (cmd->convert_src != TRIG_TIMER)
303 if (mode == MODE_SINGLE_CHAN &&
304 cmd->scan_begin_src == TRIG_TIMER) {
305 cmd->scan_begin_arg = ns;
306 if (cmd->convert_arg > cmd->scan_begin_arg)
307 cmd->convert_arg = cmd->scan_begin_arg;
309 cmd->convert_arg = ns;
313 static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd,
316 if (cmd->scan_begin_src != TRIG_TIMER)
319 if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
322 return cmd->scan_begin_arg;
325 static void labpc_set_ai_scan_period(struct comedi_cmd *cmd,
326 enum scan_mode mode, unsigned int ns)
328 if (cmd->scan_begin_src != TRIG_TIMER)
331 if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
334 cmd->scan_begin_arg = ns;
337 /* figures out what counter values to use based on command */
338 static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
341 struct comedi_8254 *pacer = dev->pacer;
342 unsigned int convert_period = labpc_ai_convert_period(cmd, mode);
343 unsigned int scan_period = labpc_ai_scan_period(cmd, mode);
344 unsigned int base_period;
347 * If both convert and scan triggers are TRIG_TIMER, then they
348 * both rely on counter b0. If only one TRIG_TIMER is used, we
349 * can use the generic cascaded timing functions.
351 if (convert_period && scan_period) {
353 * pick the lowest divisor value we can (for maximum input
354 * clock speed on convert and scan counters)
356 pacer->next_div1 = (scan_period - 1) /
357 (pacer->osc_base * I8254_MAX_COUNT) + 1;
359 comedi_check_trigger_arg_min(&pacer->next_div1, 2);
360 comedi_check_trigger_arg_max(&pacer->next_div1,
363 base_period = pacer->osc_base * pacer->next_div1;
365 /* set a0 for conversion frequency and b1 for scan frequency */
366 switch (cmd->flags & CMDF_ROUND_MASK) {
368 case CMDF_ROUND_NEAREST:
369 pacer->next_div = DIV_ROUND_CLOSEST(convert_period,
371 pacer->next_div2 = DIV_ROUND_CLOSEST(scan_period,
375 pacer->next_div = DIV_ROUND_UP(convert_period,
377 pacer->next_div2 = DIV_ROUND_UP(scan_period,
380 case CMDF_ROUND_DOWN:
381 pacer->next_div = convert_period / base_period;
382 pacer->next_div2 = scan_period / base_period;
385 /* make sure a0 and b1 values are acceptable */
386 comedi_check_trigger_arg_min(&pacer->next_div, 2);
387 comedi_check_trigger_arg_max(&pacer->next_div, I8254_MAX_COUNT);
388 comedi_check_trigger_arg_min(&pacer->next_div2, 2);
389 comedi_check_trigger_arg_max(&pacer->next_div2,
392 /* write corrected timings to command */
393 labpc_set_ai_convert_period(cmd, mode,
394 base_period * pacer->next_div);
395 labpc_set_ai_scan_period(cmd, mode,
396 base_period * pacer->next_div2);
397 } else if (scan_period) {
399 * calculate cascaded counter values
400 * that give desired scan timing
401 * (pacer->next_div2 / pacer->next_div1)
403 comedi_8254_cascade_ns_to_timer(pacer, &scan_period,
405 labpc_set_ai_scan_period(cmd, mode, scan_period);
406 } else if (convert_period) {
408 * calculate cascaded counter values
409 * that give desired conversion timing
410 * (pacer->next_div / pacer->next_div1)
412 comedi_8254_cascade_ns_to_timer(pacer, &convert_period,
414 /* transfer div2 value so correct timer gets updated */
415 pacer->next_div = pacer->next_div2;
416 labpc_set_ai_convert_period(cmd, mode, convert_period);
420 static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
425 if (cmd->chanlist_len == 1)
426 return MODE_SINGLE_CHAN;
428 /* chanlist may be NULL during cmdtest */
430 return MODE_MULT_CHAN_UP;
432 chan0 = CR_CHAN(cmd->chanlist[0]);
433 chan1 = CR_CHAN(cmd->chanlist[1]);
436 return MODE_MULT_CHAN_UP;
439 return MODE_MULT_CHAN_DOWN;
441 return MODE_SINGLE_CHAN_INTERVAL;
444 static int labpc_ai_check_chanlist(struct comedi_device *dev,
445 struct comedi_subdevice *s,
446 struct comedi_cmd *cmd)
448 enum scan_mode mode = labpc_ai_scan_mode(cmd);
449 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
450 unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
451 unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
454 for (i = 0; i < cmd->chanlist_len; i++) {
455 unsigned int chan = CR_CHAN(cmd->chanlist[i]);
456 unsigned int range = CR_RANGE(cmd->chanlist[i]);
457 unsigned int aref = CR_AREF(cmd->chanlist[i]);
460 case MODE_SINGLE_CHAN:
462 case MODE_SINGLE_CHAN_INTERVAL:
464 dev_dbg(dev->class_dev,
465 "channel scanning order specified in chanlist is not supported by hardware\n");
469 case MODE_MULT_CHAN_UP:
471 dev_dbg(dev->class_dev,
472 "channel scanning order specified in chanlist is not supported by hardware\n");
476 case MODE_MULT_CHAN_DOWN:
477 if (chan != (cmd->chanlist_len - i - 1)) {
478 dev_dbg(dev->class_dev,
479 "channel scanning order specified in chanlist is not supported by hardware\n");
485 if (range != range0) {
486 dev_dbg(dev->class_dev,
487 "entries in chanlist must all have the same range\n");
492 dev_dbg(dev->class_dev,
493 "entries in chanlist must all have the same reference\n");
501 static int labpc_ai_cmdtest(struct comedi_device *dev,
502 struct comedi_subdevice *s, struct comedi_cmd *cmd)
504 const struct labpc_boardinfo *board = dev->board_ptr;
507 unsigned int stop_mask;
510 /* Step 1 : check if triggers are trivially valid */
512 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
513 err |= comedi_check_trigger_src(&cmd->scan_begin_src,
514 TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
515 err |= comedi_check_trigger_src(&cmd->convert_src,
516 TRIG_TIMER | TRIG_EXT);
517 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
519 stop_mask = TRIG_COUNT | TRIG_NONE;
520 if (board->is_labpc1200)
521 stop_mask |= TRIG_EXT;
522 err |= comedi_check_trigger_src(&cmd->stop_src, stop_mask);
527 /* Step 2a : make sure trigger sources are unique */
529 err |= comedi_check_trigger_is_unique(cmd->start_src);
530 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
531 err |= comedi_check_trigger_is_unique(cmd->convert_src);
532 err |= comedi_check_trigger_is_unique(cmd->stop_src);
534 /* Step 2b : and mutually compatible */
536 /* can't have external stop and start triggers at once */
537 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
543 /* Step 3: check if arguments are trivially valid */
545 switch (cmd->start_src) {
547 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
550 /* start_arg value is ignored */
554 if (!cmd->chanlist_len)
556 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
559 if (cmd->convert_src == TRIG_TIMER) {
560 err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
564 /* make sure scan timing is not too fast */
565 if (cmd->scan_begin_src == TRIG_TIMER) {
566 if (cmd->convert_src == TRIG_TIMER) {
567 err |= comedi_check_trigger_arg_min(
568 &cmd->scan_begin_arg,
569 cmd->convert_arg * cmd->chanlist_len);
571 err |= comedi_check_trigger_arg_min(
572 &cmd->scan_begin_arg,
573 board->ai_speed * cmd->chanlist_len);
576 switch (cmd->stop_src) {
578 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
581 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
584 * TRIG_EXT doesn't care since it doesn't
585 * trigger off a numbered channel
594 /* step 4: fix up any arguments */
596 tmp = cmd->convert_arg;
597 tmp2 = cmd->scan_begin_arg;
598 mode = labpc_ai_scan_mode(cmd);
599 labpc_adc_timing(dev, cmd, mode);
600 if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
606 /* Step 5: check channel list if it exists */
607 if (cmd->chanlist && cmd->chanlist_len > 0)
608 err |= labpc_ai_check_chanlist(dev, s, cmd);
616 static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
618 const struct labpc_boardinfo *board = dev->board_ptr;
619 struct labpc_private *devpriv = dev->private;
620 struct comedi_async *async = s->async;
621 struct comedi_cmd *cmd = &async->cmd;
622 enum scan_mode mode = labpc_ai_scan_mode(cmd);
623 unsigned int chanspec = (mode == MODE_MULT_CHAN_UP) ?
624 cmd->chanlist[cmd->chanlist_len - 1] :
626 unsigned int chan = CR_CHAN(chanspec);
627 unsigned int range = CR_RANGE(chanspec);
628 unsigned int aref = CR_AREF(chanspec);
629 enum transfer_type xfer;
632 /* make sure board is disabled before setting up acquisition */
633 labpc_cancel(dev, s);
635 /* initialize software conversion count */
636 if (cmd->stop_src == TRIG_COUNT)
637 devpriv->count = cmd->stop_arg * cmd->chanlist_len;
639 /* setup hardware conversion counter */
640 if (cmd->stop_src == TRIG_EXT) {
642 * load counter a1 with count of 3
643 * (pc+ manual says this is minimum allowed) using mode 0
645 comedi_8254_load(devpriv->counter, 1,
646 3, I8254_MODE0 | I8254_BINARY);
648 /* just put counter a1 in mode 0 to set its output low */
649 comedi_8254_set_mode(devpriv->counter, 1,
650 I8254_MODE0 | I8254_BINARY);
653 /* figure out what method we will use to transfer data */
655 (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0) {
657 * dma unsafe at RT priority,
658 * and too much setup time for CMDF_WAKE_EOS
660 xfer = isa_dma_transfer;
661 } else if (board->is_labpc1200 &&
662 (cmd->flags & CMDF_WAKE_EOS) == 0 &&
663 (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) {
665 * pc-plus has no fifo-half full interrupt
666 * wake-end-of-scan should interrupt on fifo not empty
667 * make sure we are taking more than just a few points
669 xfer = fifo_half_full_transfer;
671 xfer = fifo_not_empty_transfer;
673 devpriv->current_transfer = xfer;
675 labpc_ai_set_chan_and_gain(dev, mode, chan, range, aref);
677 labpc_setup_cmd6_reg(dev, s, mode, xfer, range, aref,
678 (cmd->stop_src == TRIG_EXT));
680 /* manual says to set scan enable bit on second pass */
681 if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) {
682 devpriv->cmd1 |= CMD1_SCANEN;
684 * Need a brief delay before enabling scan, or scan
685 * list will get screwed when you switch between
686 * scan up to scan down mode - dunno why.
689 devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
692 devpriv->write_byte(dev, cmd->chanlist_len, INTERVAL_COUNT_REG);
694 devpriv->write_byte(dev, 0x1, INTERVAL_STROBE_REG);
696 if (cmd->convert_src == TRIG_TIMER ||
697 cmd->scan_begin_src == TRIG_TIMER) {
698 struct comedi_8254 *pacer = dev->pacer;
699 struct comedi_8254 *counter = devpriv->counter;
701 comedi_8254_update_divisors(pacer);
704 comedi_8254_load(pacer, 0, pacer->divisor1,
705 I8254_MODE3 | I8254_BINARY);
707 /* set up conversion pacing */
708 comedi_8254_set_mode(counter, 0, I8254_MODE2 | I8254_BINARY);
709 if (labpc_ai_convert_period(cmd, mode))
710 comedi_8254_write(counter, 0, pacer->divisor);
712 /* set up scan pacing */
713 if (labpc_ai_scan_period(cmd, mode))
714 comedi_8254_load(pacer, 1, pacer->divisor2,
715 I8254_MODE2 | I8254_BINARY);
718 labpc_clear_adc_fifo(dev);
720 if (xfer == isa_dma_transfer)
721 labpc_setup_dma(dev, s);
723 /* enable error interrupts */
724 devpriv->cmd3 |= CMD3_ERRINTEN;
725 /* enable fifo not empty interrupt? */
726 if (xfer == fifo_not_empty_transfer)
727 devpriv->cmd3 |= CMD3_FIFOINTEN;
728 devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
730 /* setup any external triggering/pacing (cmd4 register) */
732 if (cmd->convert_src != TRIG_EXT)
733 devpriv->cmd4 |= CMD4_ECLKRCV;
735 * XXX should discard first scan when using interval scanning
736 * since manual says it is not synced with scan clock.
738 if (!labpc_use_continuous_mode(cmd, mode)) {
739 devpriv->cmd4 |= CMD4_INTSCAN;
740 if (cmd->scan_begin_src == TRIG_EXT)
741 devpriv->cmd4 |= CMD4_EOIRCV;
743 /* single-ended/differential */
744 if (aref == AREF_DIFF)
745 devpriv->cmd4 |= CMD4_SEDIFF;
746 devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
748 /* startup acquisition */
750 spin_lock_irqsave(&dev->spinlock, flags);
752 /* use 2 cascaded counters for pacing */
753 devpriv->cmd2 |= CMD2_TBSEL;
755 devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
756 if (cmd->start_src == TRIG_EXT)
757 devpriv->cmd2 |= CMD2_HWTRIG;
759 devpriv->cmd2 |= CMD2_SWTRIG;
760 if (cmd->stop_src == TRIG_EXT)
761 devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG);
763 devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
765 spin_unlock_irqrestore(&dev->spinlock, flags);
770 /* read all available samples from ai fifo */
771 static int labpc_drain_fifo(struct comedi_device *dev)
773 struct labpc_private *devpriv = dev->private;
774 struct comedi_async *async = dev->read_subdev->async;
775 struct comedi_cmd *cmd = &async->cmd;
777 const int timeout = 10000;
780 devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
782 for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout;
784 /* quit if we have all the data we want */
785 if (cmd->stop_src == TRIG_COUNT) {
786 if (devpriv->count == 0)
790 data = labpc_read_adc_fifo(dev);
791 comedi_buf_write_samples(dev->read_subdev, &data, 1);
792 devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
795 dev_err(dev->class_dev, "ai timeout, fifo never empties\n");
796 async->events |= COMEDI_CB_ERROR;
804 * Makes sure all data acquired by board is transferred to comedi (used
805 * when acquisition is terminated by stop_src == TRIG_EXT).
807 static void labpc_drain_dregs(struct comedi_device *dev)
809 struct labpc_private *devpriv = dev->private;
811 if (devpriv->current_transfer == isa_dma_transfer)
812 labpc_drain_dma(dev);
814 labpc_drain_fifo(dev);
817 /* interrupt service routine */
818 static irqreturn_t labpc_interrupt(int irq, void *d)
820 struct comedi_device *dev = d;
821 const struct labpc_boardinfo *board = dev->board_ptr;
822 struct labpc_private *devpriv = dev->private;
823 struct comedi_subdevice *s = dev->read_subdev;
824 struct comedi_async *async;
825 struct comedi_cmd *cmd;
827 if (!dev->attached) {
828 dev_err(dev->class_dev, "premature interrupt\n");
835 /* read board status */
836 devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
837 if (board->is_labpc1200)
838 devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
840 if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
841 STAT1_OVERRUN | STAT1_DAVAIL)) == 0 &&
842 (devpriv->stat2 & STAT2_OUTA1) == 0 &&
843 (devpriv->stat2 & STAT2_FIFONHF)) {
847 if (devpriv->stat1 & STAT1_OVERRUN) {
848 /* clear error interrupt */
849 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
850 async->events |= COMEDI_CB_ERROR;
851 comedi_handle_events(dev, s);
852 dev_err(dev->class_dev, "overrun\n");
856 if (devpriv->current_transfer == isa_dma_transfer)
857 labpc_handle_dma_status(dev);
859 labpc_drain_fifo(dev);
861 if (devpriv->stat1 & STAT1_CNTINT) {
862 dev_err(dev->class_dev, "handled timer interrupt?\n");
864 devpriv->write_byte(dev, 0x1, TIMER_CLEAR_REG);
867 if (devpriv->stat1 & STAT1_OVERFLOW) {
868 /* clear error interrupt */
869 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
870 async->events |= COMEDI_CB_ERROR;
871 comedi_handle_events(dev, s);
872 dev_err(dev->class_dev, "overflow\n");
875 /* handle external stop trigger */
876 if (cmd->stop_src == TRIG_EXT) {
877 if (devpriv->stat2 & STAT2_OUTA1) {
878 labpc_drain_dregs(dev);
879 async->events |= COMEDI_CB_EOA;
883 /* TRIG_COUNT end of acquisition */
884 if (cmd->stop_src == TRIG_COUNT) {
885 if (devpriv->count == 0)
886 async->events |= COMEDI_CB_EOA;
889 comedi_handle_events(dev, s);
893 static void labpc_ao_write(struct comedi_device *dev,
894 struct comedi_subdevice *s,
895 unsigned int chan, unsigned int val)
897 struct labpc_private *devpriv = dev->private;
899 devpriv->write_byte(dev, val & 0xff, DAC_LSB_REG(chan));
900 devpriv->write_byte(dev, (val >> 8) & 0xff, DAC_MSB_REG(chan));
902 s->readback[chan] = val;
905 static int labpc_ao_insn_write(struct comedi_device *dev,
906 struct comedi_subdevice *s,
907 struct comedi_insn *insn,
910 const struct labpc_boardinfo *board = dev->board_ptr;
911 struct labpc_private *devpriv = dev->private;
912 unsigned int channel;
917 channel = CR_CHAN(insn->chanspec);
920 * Turn off pacing of analog output channel.
921 * NOTE: hardware bug in daqcard-1200 means pacing cannot
922 * be independently enabled/disabled for its the two channels.
924 spin_lock_irqsave(&dev->spinlock, flags);
925 devpriv->cmd2 &= ~CMD2_LDAC(channel);
926 devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
927 spin_unlock_irqrestore(&dev->spinlock, flags);
930 if (board->is_labpc1200) {
931 range = CR_RANGE(insn->chanspec);
932 if (comedi_range_is_unipolar(s, range))
933 devpriv->cmd6 |= CMD6_DACUNI(channel);
935 devpriv->cmd6 &= ~CMD6_DACUNI(channel);
936 /* write to register */
937 devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
940 for (i = 0; i < insn->n; i++)
941 labpc_ao_write(dev, s, channel, data[i]);
946 /* lowlevel write to eeprom/dac */
947 static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
948 unsigned int value_width)
950 struct labpc_private *devpriv = dev->private;
953 for (i = 1; i <= value_width; i++) {
954 /* clear serial clock */
955 devpriv->cmd5 &= ~CMD5_SCLK;
956 /* send bits most significant bit first */
957 if (value & (1 << (value_width - i)))
958 devpriv->cmd5 |= CMD5_SDATA;
960 devpriv->cmd5 &= ~CMD5_SDATA;
962 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
963 /* set clock to load bit */
964 devpriv->cmd5 |= CMD5_SCLK;
966 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
970 /* lowlevel read from eeprom */
971 static unsigned int labpc_serial_in(struct comedi_device *dev)
973 struct labpc_private *devpriv = dev->private;
974 unsigned int value = 0;
976 const int value_width = 8; /* number of bits wide values are */
978 for (i = 1; i <= value_width; i++) {
979 /* set serial clock */
980 devpriv->cmd5 |= CMD5_SCLK;
982 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
983 /* clear clock bit */
984 devpriv->cmd5 &= ~CMD5_SCLK;
986 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
987 /* read bits most significant bit first */
989 devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
990 if (devpriv->stat2 & STAT2_PROMOUT)
991 value |= 1 << (value_width - i);
997 static unsigned int labpc_eeprom_read(struct comedi_device *dev,
998 unsigned int address)
1000 struct labpc_private *devpriv = dev->private;
1002 /* bits to tell eeprom to expect a read */
1003 const int read_instruction = 0x3;
1004 /* 8 bit write lengths to eeprom */
1005 const int write_length = 8;
1007 /* enable read/write to eeprom */
1008 devpriv->cmd5 &= ~CMD5_EEPROMCS;
1010 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1011 devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
1013 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1015 /* send read instruction */
1016 labpc_serial_out(dev, read_instruction, write_length);
1017 /* send 8 bit address to read from */
1018 labpc_serial_out(dev, address, write_length);
1020 value = labpc_serial_in(dev);
1022 /* disable read/write to eeprom */
1023 devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
1025 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1030 static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
1032 struct labpc_private *devpriv = dev->private;
1034 const int read_status_instruction = 0x5;
1035 const int write_length = 8; /* 8 bit write lengths to eeprom */
1037 /* enable read/write to eeprom */
1038 devpriv->cmd5 &= ~CMD5_EEPROMCS;
1040 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1041 devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
1043 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1045 /* send read status instruction */
1046 labpc_serial_out(dev, read_status_instruction, write_length);
1048 value = labpc_serial_in(dev);
1050 /* disable read/write to eeprom */
1051 devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
1053 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1058 static void labpc_eeprom_write(struct comedi_device *dev,
1059 unsigned int address, unsigned int value)
1061 struct labpc_private *devpriv = dev->private;
1062 const int write_enable_instruction = 0x6;
1063 const int write_instruction = 0x2;
1064 const int write_length = 8; /* 8 bit write lengths to eeprom */
1066 /* enable read/write to eeprom */
1067 devpriv->cmd5 &= ~CMD5_EEPROMCS;
1069 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1070 devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
1072 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1074 /* send write_enable instruction */
1075 labpc_serial_out(dev, write_enable_instruction, write_length);
1076 devpriv->cmd5 &= ~CMD5_EEPROMCS;
1078 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1080 /* send write instruction */
1081 devpriv->cmd5 |= CMD5_EEPROMCS;
1083 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1084 labpc_serial_out(dev, write_instruction, write_length);
1085 /* send 8 bit address to write to */
1086 labpc_serial_out(dev, address, write_length);
1088 labpc_serial_out(dev, value, write_length);
1089 devpriv->cmd5 &= ~CMD5_EEPROMCS;
1091 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1093 /* disable read/write to eeprom */
1094 devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
1096 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1099 /* writes to 8 bit calibration dacs */
1100 static void write_caldac(struct comedi_device *dev, unsigned int channel,
1103 struct labpc_private *devpriv = dev->private;
1105 /* clear caldac load bit and make sure we don't write to eeprom */
1106 devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT);
1108 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1110 /* write 4 bit channel */
1111 labpc_serial_out(dev, channel, 4);
1112 /* write 8 bit caldac value */
1113 labpc_serial_out(dev, value, 8);
1115 /* set and clear caldac bit to load caldac value */
1116 devpriv->cmd5 |= CMD5_CALDACLD;
1118 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1119 devpriv->cmd5 &= ~CMD5_CALDACLD;
1121 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1124 static int labpc_calib_insn_write(struct comedi_device *dev,
1125 struct comedi_subdevice *s,
1126 struct comedi_insn *insn,
1129 unsigned int chan = CR_CHAN(insn->chanspec);
1132 * Only write the last data value to the caldac. Preceding
1133 * data would be overwritten anyway.
1136 unsigned int val = data[insn->n - 1];
1138 if (s->readback[chan] != val) {
1139 write_caldac(dev, chan, val);
1140 s->readback[chan] = val;
1147 static int labpc_eeprom_ready(struct comedi_device *dev,
1148 struct comedi_subdevice *s,
1149 struct comedi_insn *insn,
1150 unsigned long context)
1152 unsigned int status;
1154 /* make sure there isn't already a write in progress */
1155 status = labpc_eeprom_read_status(dev);
1156 if ((status & 0x1) == 0)
1161 static int labpc_eeprom_insn_write(struct comedi_device *dev,
1162 struct comedi_subdevice *s,
1163 struct comedi_insn *insn,
1166 unsigned int chan = CR_CHAN(insn->chanspec);
1169 /* only allow writes to user area of eeprom */
1170 if (chan < 16 || chan > 127)
1174 * Only write the last data value to the eeprom. Preceding
1175 * data would be overwritten anyway.
1178 unsigned int val = data[insn->n - 1];
1180 ret = comedi_timeout(dev, s, insn, labpc_eeprom_ready, 0);
1184 labpc_eeprom_write(dev, chan, val);
1185 s->readback[chan] = val;
1191 int labpc_common_attach(struct comedi_device *dev,
1192 unsigned int irq, unsigned long isr_flags)
1194 const struct labpc_boardinfo *board = dev->board_ptr;
1195 struct labpc_private *devpriv;
1196 struct comedi_subdevice *s;
1200 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1205 devpriv->read_byte = labpc_readb;
1206 devpriv->write_byte = labpc_writeb;
1208 #ifdef CONFIG_HAS_IOPORT
1209 devpriv->read_byte = labpc_inb;
1210 devpriv->write_byte = labpc_outb;
1216 /* initialize board's command registers */
1217 devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
1218 devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
1219 devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
1220 devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
1221 if (board->is_labpc1200) {
1222 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1223 devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
1227 ret = request_irq(irq, labpc_interrupt, isr_flags,
1228 dev->board_name, dev);
1235 comedi_8254_mm_alloc(dev->mmio + COUNTER_B_BASE_REG,
1236 I8254_OSC_BASE_2MHZ, I8254_IO8, 0);
1238 comedi_8254_mm_alloc(dev->mmio + COUNTER_A_BASE_REG,
1239 I8254_OSC_BASE_2MHZ, I8254_IO8, 0);
1242 comedi_8254_io_alloc(dev->iobase + COUNTER_B_BASE_REG,
1243 I8254_OSC_BASE_2MHZ, I8254_IO8, 0);
1245 comedi_8254_io_alloc(dev->iobase + COUNTER_A_BASE_REG,
1246 I8254_OSC_BASE_2MHZ, I8254_IO8, 0);
1248 if (IS_ERR(dev->pacer))
1249 return PTR_ERR(dev->pacer);
1250 if (IS_ERR(devpriv->counter))
1251 return PTR_ERR(devpriv->counter);
1253 ret = comedi_alloc_subdevices(dev, 5);
1257 /* analog input subdevice */
1258 s = &dev->subdevices[0];
1259 s->type = COMEDI_SUBD_AI;
1260 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1262 s->len_chanlist = 8;
1263 s->maxdata = 0x0fff;
1264 s->range_table = board->is_labpc1200 ?
1265 &range_labpc_1200_ai : &range_labpc_plus_ai;
1266 s->insn_read = labpc_ai_insn_read;
1268 dev->read_subdev = s;
1269 s->subdev_flags |= SDF_CMD_READ;
1270 s->do_cmd = labpc_ai_cmd;
1271 s->do_cmdtest = labpc_ai_cmdtest;
1272 s->cancel = labpc_cancel;
1276 s = &dev->subdevices[1];
1277 if (board->has_ao) {
1278 s->type = COMEDI_SUBD_AO;
1279 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1281 s->maxdata = 0x0fff;
1282 s->range_table = &range_labpc_ao;
1283 s->insn_write = labpc_ao_insn_write;
1285 ret = comedi_alloc_subdev_readback(s);
1289 /* initialize analog outputs to a known value */
1290 for (i = 0; i < s->n_chan; i++)
1291 labpc_ao_write(dev, s, i, s->maxdata / 2);
1293 s->type = COMEDI_SUBD_UNUSED;
1297 s = &dev->subdevices[2];
1299 ret = subdev_8255_mm_init(dev, s, DIO_BASE_REG);
1301 ret = subdev_8255_io_init(dev, s, DIO_BASE_REG);
1305 /* calibration subdevices for boards that have one */
1306 s = &dev->subdevices[3];
1307 if (board->is_labpc1200) {
1308 s->type = COMEDI_SUBD_CALIB;
1309 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1312 s->insn_write = labpc_calib_insn_write;
1314 ret = comedi_alloc_subdev_readback(s);
1318 for (i = 0; i < s->n_chan; i++) {
1319 write_caldac(dev, i, s->maxdata / 2);
1320 s->readback[i] = s->maxdata / 2;
1323 s->type = COMEDI_SUBD_UNUSED;
1326 /* EEPROM (256 bytes) */
1327 s = &dev->subdevices[4];
1328 if (board->is_labpc1200) {
1329 s->type = COMEDI_SUBD_MEMORY;
1330 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1333 s->insn_write = labpc_eeprom_insn_write;
1335 ret = comedi_alloc_subdev_readback(s);
1339 for (i = 0; i < s->n_chan; i++)
1340 s->readback[i] = labpc_eeprom_read(dev, i);
1342 s->type = COMEDI_SUBD_UNUSED;
1347 EXPORT_SYMBOL_GPL(labpc_common_attach);
1349 void labpc_common_detach(struct comedi_device *dev)
1351 struct labpc_private *devpriv = dev->private;
1354 if (!IS_ERR(devpriv->counter))
1355 kfree(devpriv->counter);
1358 EXPORT_SYMBOL_GPL(labpc_common_detach);
1360 static int __init labpc_common_init(void)
1364 module_init(labpc_common_init);
1366 static void __exit labpc_common_exit(void)
1369 module_exit(labpc_common_exit);
1371 MODULE_AUTHOR("Comedi https://www.comedi.org");
1372 MODULE_DESCRIPTION("Comedi helper for ni_labpc, ni_labpc_pci, ni_labpc_cs");
1373 MODULE_LICENSE("GPL");