// SPDX-License-Identifier: GPL-2.0+
/*
 * comedi/drivers/ni_labpc_common.c
 *
 * Common support code for "ni_labpc", "ni_labpc_pci" and "ni_labpc_cs".
 *
 * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net>
 */

#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/comedi/comedidev.h>
#include <linux/comedi/comedi_8255.h>
#include <linux/comedi/comedi_8254.h>

#include "ni_labpc.h"
#include "ni_labpc_regs.h"
#include "ni_labpc_isadma.h"

enum scan_mode {
	MODE_SINGLE_CHAN,
	MODE_SINGLE_CHAN_INTERVAL,
	MODE_MULT_CHAN_UP,
	MODE_MULT_CHAN_DOWN,
};

static const struct comedi_lrange range_labpc_plus_ai = {
	16, {
		BIP_RANGE(5),
		BIP_RANGE(4),
		BIP_RANGE(2.5),
		BIP_RANGE(1),
		BIP_RANGE(0.5),
		BIP_RANGE(0.25),
		BIP_RANGE(0.1),
		BIP_RANGE(0.05),
		UNI_RANGE(10),
		UNI_RANGE(8),
		UNI_RANGE(5),
		UNI_RANGE(2),
		UNI_RANGE(1),
		UNI_RANGE(0.5),
		UNI_RANGE(0.2),
		UNI_RANGE(0.1)
	}
};

static const struct comedi_lrange range_labpc_1200_ai = {
	14, {
		BIP_RANGE(5),
		BIP_RANGE(2.5),
		BIP_RANGE(1),
		BIP_RANGE(0.5),
		BIP_RANGE(0.25),
		BIP_RANGE(0.1),
		BIP_RANGE(0.05),
		UNI_RANGE(10),
		UNI_RANGE(5),
		UNI_RANGE(2),
		UNI_RANGE(1),
		UNI_RANGE(0.5),
		UNI_RANGE(0.2),
		UNI_RANGE(0.1)
	}
};

static const struct comedi_lrange range_labpc_ao = {
	2, {
		BIP_RANGE(5),
		UNI_RANGE(10)
	}
};

/*
 * functions that do inb/outb and readb/writeb so we can use
 * function pointers to decide which to use
 */

#ifdef CONFIG_HAS_IOPORT

static unsigned int labpc_inb(struct comedi_device *dev, unsigned long reg)
{
	return inb(dev->iobase + reg);
}

static void labpc_outb(struct comedi_device *dev,
		       unsigned int byte, unsigned long reg)
{
	outb(byte, dev->iobase + reg);
}

#endif	/* CONFIG_HAS_IOPORT */

static unsigned int labpc_readb(struct comedi_device *dev, unsigned long reg)
{
	return readb(dev->mmio + reg);
}

static void labpc_writeb(struct comedi_device *dev,
			 unsigned int byte, unsigned long reg)
{
	writeb(byte, dev->mmio + reg);
}

static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
	struct labpc_private *devpriv = dev->private;
	unsigned long flags;

	spin_lock_irqsave(&dev->spinlock, flags);
	devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
	devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
	spin_unlock_irqrestore(&dev->spinlock, flags);

	devpriv->cmd3 = 0;
	devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);

	return 0;
}

static void labpc_ai_set_chan_and_gain(struct comedi_device *dev,
				       enum scan_mode mode,
				       unsigned int chan,
				       unsigned int range,
				       unsigned int aref)
{
	const struct labpc_boardinfo *board = dev->board_ptr;
	struct labpc_private *devpriv = dev->private;

	if (board->is_labpc1200) {
		/*
		 * The LabPC-1200 boards do not have a gain
		 * of '0x10'. Skip the range values that would
		 * result in this gain.
		 */
		range += (range > 0) + (range > 7);
	}

	/* munge channel bits for differential/scan disabled mode */
	if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) &&
	    aref == AREF_DIFF)
		chan *= 2;
	devpriv->cmd1 = CMD1_MA(chan);
	devpriv->cmd1 |= CMD1_GAIN(range);

	devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
}

static void labpc_setup_cmd6_reg(struct comedi_device *dev,
				 struct comedi_subdevice *s,
				 enum scan_mode mode,
				 enum transfer_type xfer,
				 unsigned int range,
				 unsigned int aref,
				 bool ena_intr)
{
	const struct labpc_boardinfo *board = dev->board_ptr;
	struct labpc_private *devpriv = dev->private;

	if (!board->is_labpc1200)
		return;

	/* reference inputs to ground or common? */
	if (aref != AREF_GROUND)
		devpriv->cmd6 |= CMD6_NRSE;
	else
		devpriv->cmd6 &= ~CMD6_NRSE;

	/* bipolar or unipolar range? */
	if (comedi_range_is_unipolar(s, range))
		devpriv->cmd6 |= CMD6_ADCUNI;
	else
		devpriv->cmd6 &= ~CMD6_ADCUNI;

	/*  interrupt on fifo half full? */
	if (xfer == fifo_half_full_transfer)
		devpriv->cmd6 |= CMD6_HFINTEN;
	else
		devpriv->cmd6 &= ~CMD6_HFINTEN;

	/* enable interrupt on counter a1 terminal count? */
	if (ena_intr)
		devpriv->cmd6 |= CMD6_DQINTEN;
	else
		devpriv->cmd6 &= ~CMD6_DQINTEN;

	/* are we scanning up or down through channels? */
	if (mode == MODE_MULT_CHAN_UP)
		devpriv->cmd6 |= CMD6_SCANUP;
	else
		devpriv->cmd6 &= ~CMD6_SCANUP;

	devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
}

static unsigned int labpc_read_adc_fifo(struct comedi_device *dev)
{
	struct labpc_private *devpriv = dev->private;
	unsigned int lsb = devpriv->read_byte(dev, ADC_FIFO_REG);
	unsigned int msb = devpriv->read_byte(dev, ADC_FIFO_REG);

	return (msb << 8) | lsb;
}

static void labpc_clear_adc_fifo(struct comedi_device *dev)
{
	struct labpc_private *devpriv = dev->private;

	devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
	labpc_read_adc_fifo(dev);
}

static int labpc_ai_eoc(struct comedi_device *dev,
			struct comedi_subdevice *s,
			struct comedi_insn *insn,
			unsigned long context)
{
	struct labpc_private *devpriv = dev->private;

	devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
	if (devpriv->stat1 & STAT1_DAVAIL)
		return 0;
	return -EBUSY;
}

static int labpc_ai_insn_read(struct comedi_device *dev,
			      struct comedi_subdevice *s,
			      struct comedi_insn *insn,
			      unsigned int *data)
{
	struct labpc_private *devpriv = dev->private;
	unsigned int chan = CR_CHAN(insn->chanspec);
	unsigned int range = CR_RANGE(insn->chanspec);
	unsigned int aref = CR_AREF(insn->chanspec);
	int ret;
	int i;

	/* disable timed conversions, interrupt generation and dma */
	labpc_cancel(dev, s);

	labpc_ai_set_chan_and_gain(dev, MODE_SINGLE_CHAN, chan, range, aref);

	labpc_setup_cmd6_reg(dev, s, MODE_SINGLE_CHAN, fifo_not_empty_transfer,
			     range, aref, false);

	/* setup cmd4 register */
	devpriv->cmd4 = 0;
	devpriv->cmd4 |= CMD4_ECLKRCV;
	/* single-ended/differential */
	if (aref == AREF_DIFF)
		devpriv->cmd4 |= CMD4_SEDIFF;
	devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);

	/* initialize pacer counter to prevent any problems */
	comedi_8254_set_mode(devpriv->counter, 0, I8254_MODE2 | I8254_BINARY);

	labpc_clear_adc_fifo(dev);

	for (i = 0; i < insn->n; i++) {
		/* trigger conversion */
		devpriv->write_byte(dev, 0x1, ADC_START_CONVERT_REG);

		ret = comedi_timeout(dev, s, insn, labpc_ai_eoc, 0);
		if (ret)
			return ret;

		data[i] = labpc_read_adc_fifo(dev);
	}

	return insn->n;
}

static bool labpc_use_continuous_mode(const struct comedi_cmd *cmd,
				      enum scan_mode mode)
{
	if (mode == MODE_SINGLE_CHAN || cmd->scan_begin_src == TRIG_FOLLOW)
		return true;

	return false;
}

static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd,
					    enum scan_mode mode)
{
	if (cmd->convert_src != TRIG_TIMER)
		return 0;

	if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER)
		return cmd->scan_begin_arg;

	return cmd->convert_arg;
}

static void labpc_set_ai_convert_period(struct comedi_cmd *cmd,
					enum scan_mode mode, unsigned int ns)
{
	if (cmd->convert_src != TRIG_TIMER)
		return;

	if (mode == MODE_SINGLE_CHAN &&
	    cmd->scan_begin_src == TRIG_TIMER) {
		cmd->scan_begin_arg = ns;
		if (cmd->convert_arg > cmd->scan_begin_arg)
			cmd->convert_arg = cmd->scan_begin_arg;
	} else {
		cmd->convert_arg = ns;
	}
}

static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd,
					 enum scan_mode mode)
{
	if (cmd->scan_begin_src != TRIG_TIMER)
		return 0;

	if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
		return 0;

	return cmd->scan_begin_arg;
}

static void labpc_set_ai_scan_period(struct comedi_cmd *cmd,
				     enum scan_mode mode, unsigned int ns)
{
	if (cmd->scan_begin_src != TRIG_TIMER)
		return;

	if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER)
		return;

	cmd->scan_begin_arg = ns;
}

/* figures out what counter values to use based on command */
static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd,
			     enum scan_mode mode)
{
	struct comedi_8254 *pacer = dev->pacer;
	unsigned int convert_period = labpc_ai_convert_period(cmd, mode);
	unsigned int scan_period = labpc_ai_scan_period(cmd, mode);
	unsigned int base_period;

	/*
	 * If both convert and scan triggers are TRIG_TIMER, then they
	 * both rely on counter b0. If only one TRIG_TIMER is used, we
	 * can use the generic cascaded timing functions.
	 */
	if (convert_period && scan_period) {
		/*
		 * pick the lowest divisor value we can (for maximum input
		 * clock speed on convert and scan counters)
		 */
		pacer->next_div1 = (scan_period - 1) /
				   (pacer->osc_base * I8254_MAX_COUNT) + 1;

		comedi_check_trigger_arg_min(&pacer->next_div1, 2);
		comedi_check_trigger_arg_max(&pacer->next_div1,
					     I8254_MAX_COUNT);

		base_period = pacer->osc_base * pacer->next_div1;

		/*  set a0 for conversion frequency and b1 for scan frequency */
		switch (cmd->flags & CMDF_ROUND_MASK) {
		default:
		case CMDF_ROUND_NEAREST:
			pacer->next_div = DIV_ROUND_CLOSEST(convert_period,
							    base_period);
			pacer->next_div2 = DIV_ROUND_CLOSEST(scan_period,
							     base_period);
			break;
		case CMDF_ROUND_UP:
			pacer->next_div = DIV_ROUND_UP(convert_period,
						       base_period);
			pacer->next_div2 = DIV_ROUND_UP(scan_period,
							base_period);
			break;
		case CMDF_ROUND_DOWN:
			pacer->next_div = convert_period / base_period;
			pacer->next_div2 = scan_period / base_period;
			break;
		}
		/*  make sure a0 and b1 values are acceptable */
		comedi_check_trigger_arg_min(&pacer->next_div, 2);
		comedi_check_trigger_arg_max(&pacer->next_div, I8254_MAX_COUNT);
		comedi_check_trigger_arg_min(&pacer->next_div2, 2);
		comedi_check_trigger_arg_max(&pacer->next_div2,
					     I8254_MAX_COUNT);

		/*  write corrected timings to command */
		labpc_set_ai_convert_period(cmd, mode,
					    base_period * pacer->next_div);
		labpc_set_ai_scan_period(cmd, mode,
					 base_period * pacer->next_div2);
	} else if (scan_period) {
		/*
		 * calculate cascaded counter values
		 * that give desired scan timing
		 * (pacer->next_div2 / pacer->next_div1)
		 */
		comedi_8254_cascade_ns_to_timer(pacer, &scan_period,
						cmd->flags);
		labpc_set_ai_scan_period(cmd, mode, scan_period);
	} else if (convert_period) {
		/*
		 * calculate cascaded counter values
		 * that give desired conversion timing
		 * (pacer->next_div / pacer->next_div1)
		 */
		comedi_8254_cascade_ns_to_timer(pacer, &convert_period,
						cmd->flags);
		/* transfer div2 value so correct timer gets updated */
		pacer->next_div = pacer->next_div2;
		labpc_set_ai_convert_period(cmd, mode, convert_period);
	}
}

static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd)
{
	unsigned int chan0;
	unsigned int chan1;

	if (cmd->chanlist_len == 1)
		return MODE_SINGLE_CHAN;

	/* chanlist may be NULL during cmdtest */
	if (!cmd->chanlist)
		return MODE_MULT_CHAN_UP;

	chan0 = CR_CHAN(cmd->chanlist[0]);
	chan1 = CR_CHAN(cmd->chanlist[1]);

	if (chan0 < chan1)
		return MODE_MULT_CHAN_UP;

	if (chan0 > chan1)
		return MODE_MULT_CHAN_DOWN;

	return MODE_SINGLE_CHAN_INTERVAL;
}

static int labpc_ai_check_chanlist(struct comedi_device *dev,
				   struct comedi_subdevice *s,
				   struct comedi_cmd *cmd)
{
	enum scan_mode mode = labpc_ai_scan_mode(cmd);
	unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
	unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
	unsigned int aref0 = CR_AREF(cmd->chanlist[0]);
	int i;

	for (i = 0; i < cmd->chanlist_len; i++) {
		unsigned int chan = CR_CHAN(cmd->chanlist[i]);
		unsigned int range = CR_RANGE(cmd->chanlist[i]);
		unsigned int aref = CR_AREF(cmd->chanlist[i]);

		switch (mode) {
		case MODE_SINGLE_CHAN:
			break;
		case MODE_SINGLE_CHAN_INTERVAL:
			if (chan != chan0) {
				dev_dbg(dev->class_dev,
					"channel scanning order specified in chanlist is not supported by hardware\n");
				return -EINVAL;
			}
			break;
		case MODE_MULT_CHAN_UP:
			if (chan != i) {
				dev_dbg(dev->class_dev,
					"channel scanning order specified in chanlist is not supported by hardware\n");
				return -EINVAL;
			}
			break;
		case MODE_MULT_CHAN_DOWN:
			if (chan != (cmd->chanlist_len - i - 1)) {
				dev_dbg(dev->class_dev,
					"channel scanning order specified in chanlist is not supported by hardware\n");
				return -EINVAL;
			}
			break;
		}

		if (range != range0) {
			dev_dbg(dev->class_dev,
				"entries in chanlist must all have the same range\n");
			return -EINVAL;
		}

		if (aref != aref0) {
			dev_dbg(dev->class_dev,
				"entries in chanlist must all have the same reference\n");
			return -EINVAL;
		}
	}

	return 0;
}

static int labpc_ai_cmdtest(struct comedi_device *dev,
			    struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
	const struct labpc_boardinfo *board = dev->board_ptr;
	int err = 0;
	int tmp, tmp2;
	unsigned int stop_mask;
	enum scan_mode mode;

	/* Step 1 : check if triggers are trivially valid */

	err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
	err |= comedi_check_trigger_src(&cmd->scan_begin_src,
					TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
	err |= comedi_check_trigger_src(&cmd->convert_src,
					TRIG_TIMER | TRIG_EXT);
	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);

	stop_mask = TRIG_COUNT | TRIG_NONE;
	if (board->is_labpc1200)
		stop_mask |= TRIG_EXT;
	err |= comedi_check_trigger_src(&cmd->stop_src, stop_mask);

	if (err)
		return 1;

	/* Step 2a : make sure trigger sources are unique */

	err |= comedi_check_trigger_is_unique(cmd->start_src);
	err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
	err |= comedi_check_trigger_is_unique(cmd->convert_src);
	err |= comedi_check_trigger_is_unique(cmd->stop_src);

	/* Step 2b : and mutually compatible */

	/* can't have external stop and start triggers at once */
	if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
		err++;

	if (err)
		return 2;

	/* Step 3: check if arguments are trivially valid */

	switch (cmd->start_src) {
	case TRIG_NOW:
		err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
		break;
	case TRIG_EXT:
		/* start_arg value is ignored */
		break;
	}

	if (!cmd->chanlist_len)
		err |= -EINVAL;
	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
					   cmd->chanlist_len);

	if (cmd->convert_src == TRIG_TIMER) {
		err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
						    board->ai_speed);
	}

	/* make sure scan timing is not too fast */
	if (cmd->scan_begin_src == TRIG_TIMER) {
		if (cmd->convert_src == TRIG_TIMER) {
			err |= comedi_check_trigger_arg_min(
					&cmd->scan_begin_arg,
					cmd->convert_arg * cmd->chanlist_len);
		}
		err |= comedi_check_trigger_arg_min(
					&cmd->scan_begin_arg,
					board->ai_speed * cmd->chanlist_len);
	}

	switch (cmd->stop_src) {
	case TRIG_COUNT:
		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
		break;
	case TRIG_NONE:
		err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
		break;
		/*
		 * TRIG_EXT doesn't care since it doesn't
		 * trigger off a numbered channel
		 */
	default:
		break;
	}

	if (err)
		return 3;

	/* step 4: fix up any arguments */

	tmp = cmd->convert_arg;
	tmp2 = cmd->scan_begin_arg;
	mode = labpc_ai_scan_mode(cmd);
	labpc_adc_timing(dev, cmd, mode);
	if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
		err++;

	if (err)
		return 4;

	/* Step 5: check channel list if it exists */
	if (cmd->chanlist && cmd->chanlist_len > 0)
		err |= labpc_ai_check_chanlist(dev, s, cmd);

	if (err)
		return 5;

	return 0;
}

static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
	const struct labpc_boardinfo *board = dev->board_ptr;
	struct labpc_private *devpriv = dev->private;
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;
	enum scan_mode mode = labpc_ai_scan_mode(cmd);
	unsigned int chanspec = (mode == MODE_MULT_CHAN_UP) ?
				cmd->chanlist[cmd->chanlist_len - 1] :
				cmd->chanlist[0];
	unsigned int chan = CR_CHAN(chanspec);
	unsigned int range = CR_RANGE(chanspec);
	unsigned int aref = CR_AREF(chanspec);
	enum transfer_type xfer;
	unsigned long flags;

	/* make sure board is disabled before setting up acquisition */
	labpc_cancel(dev, s);

	/*  initialize software conversion count */
	if (cmd->stop_src == TRIG_COUNT)
		devpriv->count = cmd->stop_arg * cmd->chanlist_len;

	/*  setup hardware conversion counter */
	if (cmd->stop_src == TRIG_EXT) {
		/*
		 * load counter a1 with count of 3
		 * (pc+ manual says this is minimum allowed) using mode 0
		 */
		comedi_8254_load(devpriv->counter, 1,
				 3, I8254_MODE0 | I8254_BINARY);
	} else	{
		/* just put counter a1 in mode 0 to set its output low */
		comedi_8254_set_mode(devpriv->counter, 1,
				     I8254_MODE0 | I8254_BINARY);
	}

	/* figure out what method we will use to transfer data */
	if (devpriv->dma &&
	    (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0) {
		/*
		 * dma unsafe at RT priority,
		 * and too much setup time for CMDF_WAKE_EOS
		 */
		xfer = isa_dma_transfer;
	} else if (board->is_labpc1200 &&
		   (cmd->flags & CMDF_WAKE_EOS) == 0 &&
		   (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) {
		/*
		 * pc-plus has no fifo-half full interrupt
		 * wake-end-of-scan should interrupt on fifo not empty
		 * make sure we are taking more than just a few points
		 */
		xfer = fifo_half_full_transfer;
	} else {
		xfer = fifo_not_empty_transfer;
	}
	devpriv->current_transfer = xfer;

	labpc_ai_set_chan_and_gain(dev, mode, chan, range, aref);

	labpc_setup_cmd6_reg(dev, s, mode, xfer, range, aref,
			     (cmd->stop_src == TRIG_EXT));

	/* manual says to set scan enable bit on second pass */
	if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) {
		devpriv->cmd1 |= CMD1_SCANEN;
		/*
		 * Need a brief delay before enabling scan, or scan
		 * list will get screwed when you switch between
		 * scan up to scan down mode - dunno why.
		 */
		udelay(1);
		devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
	}

	devpriv->write_byte(dev, cmd->chanlist_len, INTERVAL_COUNT_REG);
	/*  load count */
	devpriv->write_byte(dev, 0x1, INTERVAL_STROBE_REG);

	if (cmd->convert_src == TRIG_TIMER ||
	    cmd->scan_begin_src == TRIG_TIMER) {
		struct comedi_8254 *pacer = dev->pacer;
		struct comedi_8254 *counter = devpriv->counter;

		comedi_8254_update_divisors(pacer);

		/* set up pacing */
		comedi_8254_load(pacer, 0, pacer->divisor1,
				 I8254_MODE3 | I8254_BINARY);

		/* set up conversion pacing */
		comedi_8254_set_mode(counter, 0, I8254_MODE2 | I8254_BINARY);
		if (labpc_ai_convert_period(cmd, mode))
			comedi_8254_write(counter, 0, pacer->divisor);

		/* set up scan pacing */
		if (labpc_ai_scan_period(cmd, mode))
			comedi_8254_load(pacer, 1, pacer->divisor2,
					 I8254_MODE2 | I8254_BINARY);
	}

	labpc_clear_adc_fifo(dev);

	if (xfer == isa_dma_transfer)
		labpc_setup_dma(dev, s);

	/*  enable error interrupts */
	devpriv->cmd3 |= CMD3_ERRINTEN;
	/*  enable fifo not empty interrupt? */
	if (xfer == fifo_not_empty_transfer)
		devpriv->cmd3 |= CMD3_FIFOINTEN;
	devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);

	/*  setup any external triggering/pacing (cmd4 register) */
	devpriv->cmd4 = 0;
	if (cmd->convert_src != TRIG_EXT)
		devpriv->cmd4 |= CMD4_ECLKRCV;
	/*
	 * XXX should discard first scan when using interval scanning
	 * since manual says it is not synced with scan clock.
	 */
	if (!labpc_use_continuous_mode(cmd, mode)) {
		devpriv->cmd4 |= CMD4_INTSCAN;
		if (cmd->scan_begin_src == TRIG_EXT)
			devpriv->cmd4 |= CMD4_EOIRCV;
	}
	/*  single-ended/differential */
	if (aref == AREF_DIFF)
		devpriv->cmd4 |= CMD4_SEDIFF;
	devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);

	/*  startup acquisition */

	spin_lock_irqsave(&dev->spinlock, flags);

	/* use 2 cascaded counters for pacing */
	devpriv->cmd2 |= CMD2_TBSEL;

	devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
	if (cmd->start_src == TRIG_EXT)
		devpriv->cmd2 |= CMD2_HWTRIG;
	else
		devpriv->cmd2 |= CMD2_SWTRIG;
	if (cmd->stop_src == TRIG_EXT)
		devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG);

	devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);

	spin_unlock_irqrestore(&dev->spinlock, flags);

	return 0;
}

/* read all available samples from ai fifo */
static int labpc_drain_fifo(struct comedi_device *dev)
{
	struct labpc_private *devpriv = dev->private;
	struct comedi_async *async = dev->read_subdev->async;
	struct comedi_cmd *cmd = &async->cmd;
	unsigned short data;
	const int timeout = 10000;
	unsigned int i;

	devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);

	for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout;
	     i++) {
		/*  quit if we have all the data we want */
		if (cmd->stop_src == TRIG_COUNT) {
			if (devpriv->count == 0)
				break;
			devpriv->count--;
		}
		data = labpc_read_adc_fifo(dev);
		comedi_buf_write_samples(dev->read_subdev, &data, 1);
		devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
	}
	if (i == timeout) {
		dev_err(dev->class_dev, "ai timeout, fifo never empties\n");
		async->events |= COMEDI_CB_ERROR;
		return -1;
	}

	return 0;
}

/*
 * Makes sure all data acquired by board is transferred to comedi (used
 * when acquisition is terminated by stop_src == TRIG_EXT).
 */
static void labpc_drain_dregs(struct comedi_device *dev)
{
	struct labpc_private *devpriv = dev->private;

	if (devpriv->current_transfer == isa_dma_transfer)
		labpc_drain_dma(dev);

	labpc_drain_fifo(dev);
}

/* interrupt service routine */
static irqreturn_t labpc_interrupt(int irq, void *d)
{
	struct comedi_device *dev = d;
	const struct labpc_boardinfo *board = dev->board_ptr;
	struct labpc_private *devpriv = dev->private;
	struct comedi_subdevice *s = dev->read_subdev;
	struct comedi_async *async;
	struct comedi_cmd *cmd;

	if (!dev->attached) {
		dev_err(dev->class_dev, "premature interrupt\n");
		return IRQ_HANDLED;
	}

	async = s->async;
	cmd = &async->cmd;

	/* read board status */
	devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
	if (board->is_labpc1200)
		devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);

	if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
			       STAT1_OVERRUN | STAT1_DAVAIL)) == 0 &&
	    (devpriv->stat2 & STAT2_OUTA1) == 0 &&
	    (devpriv->stat2 & STAT2_FIFONHF)) {
		return IRQ_NONE;
	}

	if (devpriv->stat1 & STAT1_OVERRUN) {
		/* clear error interrupt */
		devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
		async->events |= COMEDI_CB_ERROR;
		comedi_handle_events(dev, s);
		dev_err(dev->class_dev, "overrun\n");
		return IRQ_HANDLED;
	}

	if (devpriv->current_transfer == isa_dma_transfer)
		labpc_handle_dma_status(dev);
	else
		labpc_drain_fifo(dev);

	if (devpriv->stat1 & STAT1_CNTINT) {
		dev_err(dev->class_dev, "handled timer interrupt?\n");
		/*  clear it */
		devpriv->write_byte(dev, 0x1, TIMER_CLEAR_REG);
	}

	if (devpriv->stat1 & STAT1_OVERFLOW) {
		/*  clear error interrupt */
		devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
		async->events |= COMEDI_CB_ERROR;
		comedi_handle_events(dev, s);
		dev_err(dev->class_dev, "overflow\n");
		return IRQ_HANDLED;
	}
	/*  handle external stop trigger */
	if (cmd->stop_src == TRIG_EXT) {
		if (devpriv->stat2 & STAT2_OUTA1) {
			labpc_drain_dregs(dev);
			async->events |= COMEDI_CB_EOA;
		}
	}

	/* TRIG_COUNT end of acquisition */
	if (cmd->stop_src == TRIG_COUNT) {
		if (devpriv->count == 0)
			async->events |= COMEDI_CB_EOA;
	}

	comedi_handle_events(dev, s);
	return IRQ_HANDLED;
}

static void labpc_ao_write(struct comedi_device *dev,
			   struct comedi_subdevice *s,
			   unsigned int chan, unsigned int val)
{
	struct labpc_private *devpriv = dev->private;

	devpriv->write_byte(dev, val & 0xff, DAC_LSB_REG(chan));
	devpriv->write_byte(dev, (val >> 8) & 0xff, DAC_MSB_REG(chan));

	s->readback[chan] = val;
}

static int labpc_ao_insn_write(struct comedi_device *dev,
			       struct comedi_subdevice *s,
			       struct comedi_insn *insn,
			       unsigned int *data)
{
	const struct labpc_boardinfo *board = dev->board_ptr;
	struct labpc_private *devpriv = dev->private;
	unsigned int channel;
	unsigned int range;
	unsigned int i;
	unsigned long flags;

	channel = CR_CHAN(insn->chanspec);

	/*
	 * Turn off pacing of analog output channel.
	 * NOTE: hardware bug in daqcard-1200 means pacing cannot
	 * be independently enabled/disabled for its the two channels.
	 */
	spin_lock_irqsave(&dev->spinlock, flags);
	devpriv->cmd2 &= ~CMD2_LDAC(channel);
	devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
	spin_unlock_irqrestore(&dev->spinlock, flags);

	/* set range */
	if (board->is_labpc1200) {
		range = CR_RANGE(insn->chanspec);
		if (comedi_range_is_unipolar(s, range))
			devpriv->cmd6 |= CMD6_DACUNI(channel);
		else
			devpriv->cmd6 &= ~CMD6_DACUNI(channel);
		/*  write to register */
		devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
	}
	/* send data */
	for (i = 0; i < insn->n; i++)
		labpc_ao_write(dev, s, channel, data[i]);

	return insn->n;
}

/* lowlevel write to eeprom/dac */
static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
			     unsigned int value_width)
{
	struct labpc_private *devpriv = dev->private;
	int i;

	for (i = 1; i <= value_width; i++) {
		/*  clear serial clock */
		devpriv->cmd5 &= ~CMD5_SCLK;
		/*  send bits most significant bit first */
		if (value & (1 << (value_width - i)))
			devpriv->cmd5 |= CMD5_SDATA;
		else
			devpriv->cmd5 &= ~CMD5_SDATA;
		udelay(1);
		devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
		/*  set clock to load bit */
		devpriv->cmd5 |= CMD5_SCLK;
		udelay(1);
		devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
	}
}

/* lowlevel read from eeprom */
static unsigned int labpc_serial_in(struct comedi_device *dev)
{
	struct labpc_private *devpriv = dev->private;
	unsigned int value = 0;
	int i;
	const int value_width = 8;	/*  number of bits wide values are */

	for (i = 1; i <= value_width; i++) {
		/*  set serial clock */
		devpriv->cmd5 |= CMD5_SCLK;
		udelay(1);
		devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
		/*  clear clock bit */
		devpriv->cmd5 &= ~CMD5_SCLK;
		udelay(1);
		devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
		/*  read bits most significant bit first */
		udelay(1);
		devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
		if (devpriv->stat2 & STAT2_PROMOUT)
			value |= 1 << (value_width - i);
	}

	return value;
}

static unsigned int labpc_eeprom_read(struct comedi_device *dev,
				      unsigned int address)
{
	struct labpc_private *devpriv = dev->private;
	unsigned int value;
	/*  bits to tell eeprom to expect a read */
	const int read_instruction = 0x3;
	/*  8 bit write lengths to eeprom */
	const int write_length = 8;

	/*  enable read/write to eeprom */
	devpriv->cmd5 &= ~CMD5_EEPROMCS;
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
	devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);

	/*  send read instruction */
	labpc_serial_out(dev, read_instruction, write_length);
	/*  send 8 bit address to read from */
	labpc_serial_out(dev, address, write_length);
	/*  read result */
	value = labpc_serial_in(dev);

	/*  disable read/write to eeprom */
	devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);

	return value;
}

static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
{
	struct labpc_private *devpriv = dev->private;
	unsigned int value;
	const int read_status_instruction = 0x5;
	const int write_length = 8;	/*  8 bit write lengths to eeprom */

	/*  enable read/write to eeprom */
	devpriv->cmd5 &= ~CMD5_EEPROMCS;
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
	devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);

	/*  send read status instruction */
	labpc_serial_out(dev, read_status_instruction, write_length);
	/*  read result */
	value = labpc_serial_in(dev);

	/*  disable read/write to eeprom */
	devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);

	return value;
}

static void labpc_eeprom_write(struct comedi_device *dev,
			       unsigned int address, unsigned int value)
{
	struct labpc_private *devpriv = dev->private;
	const int write_enable_instruction = 0x6;
	const int write_instruction = 0x2;
	const int write_length = 8;	/*  8 bit write lengths to eeprom */

	/*  enable read/write to eeprom */
	devpriv->cmd5 &= ~CMD5_EEPROMCS;
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
	devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);

	/*  send write_enable instruction */
	labpc_serial_out(dev, write_enable_instruction, write_length);
	devpriv->cmd5 &= ~CMD5_EEPROMCS;
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);

	/*  send write instruction */
	devpriv->cmd5 |= CMD5_EEPROMCS;
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
	labpc_serial_out(dev, write_instruction, write_length);
	/*  send 8 bit address to write to */
	labpc_serial_out(dev, address, write_length);
	/*  write value */
	labpc_serial_out(dev, value, write_length);
	devpriv->cmd5 &= ~CMD5_EEPROMCS;
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);

	/*  disable read/write to eeprom */
	devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
}

/* writes to 8 bit calibration dacs */
static void write_caldac(struct comedi_device *dev, unsigned int channel,
			 unsigned int value)
{
	struct labpc_private *devpriv = dev->private;

	/*  clear caldac load bit and make sure we don't write to eeprom */
	devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT);
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);

	/*  write 4 bit channel */
	labpc_serial_out(dev, channel, 4);
	/*  write 8 bit caldac value */
	labpc_serial_out(dev, value, 8);

	/*  set and clear caldac bit to load caldac value */
	devpriv->cmd5 |= CMD5_CALDACLD;
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
	devpriv->cmd5 &= ~CMD5_CALDACLD;
	udelay(1);
	devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
}

static int labpc_calib_insn_write(struct comedi_device *dev,
				  struct comedi_subdevice *s,
				  struct comedi_insn *insn,
				  unsigned int *data)
{
	unsigned int chan = CR_CHAN(insn->chanspec);

	/*
	 * Only write the last data value to the caldac. Preceding
	 * data would be overwritten anyway.
	 */
	if (insn->n > 0) {
		unsigned int val = data[insn->n - 1];

		if (s->readback[chan] != val) {
			write_caldac(dev, chan, val);
			s->readback[chan] = val;
		}
	}

	return insn->n;
}

static int labpc_eeprom_ready(struct comedi_device *dev,
			      struct comedi_subdevice *s,
			      struct comedi_insn *insn,
			      unsigned long context)
{
	unsigned int status;

	/* make sure there isn't already a write in progress */
	status = labpc_eeprom_read_status(dev);
	if ((status & 0x1) == 0)
		return 0;
	return -EBUSY;
}

static int labpc_eeprom_insn_write(struct comedi_device *dev,
				   struct comedi_subdevice *s,
				   struct comedi_insn *insn,
				   unsigned int *data)
{
	unsigned int chan = CR_CHAN(insn->chanspec);
	int ret;

	/* only allow writes to user area of eeprom */
	if (chan < 16 || chan > 127)
		return -EINVAL;

	/*
	 * Only write the last data value to the eeprom. Preceding
	 * data would be overwritten anyway.
	 */
	if (insn->n > 0) {
		unsigned int val = data[insn->n - 1];

		ret = comedi_timeout(dev, s, insn, labpc_eeprom_ready, 0);
		if (ret)
			return ret;

		labpc_eeprom_write(dev, chan, val);
		s->readback[chan] = val;
	}

	return insn->n;
}

int labpc_common_attach(struct comedi_device *dev,
			unsigned int irq, unsigned long isr_flags)
{
	const struct labpc_boardinfo *board = dev->board_ptr;
	struct labpc_private *devpriv;
	struct comedi_subdevice *s;
	int ret;
	int i;

	devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
	if (!devpriv)
		return -ENOMEM;

	if (dev->mmio) {
		devpriv->read_byte = labpc_readb;
		devpriv->write_byte = labpc_writeb;
	} else {
#ifdef CONFIG_HAS_IOPORT
		devpriv->read_byte = labpc_inb;
		devpriv->write_byte = labpc_outb;
#else
		return -ENXIO;
#endif
	}

	/* initialize board's command registers */
	devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
	devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
	devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
	devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
	if (board->is_labpc1200) {
		devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
		devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
	}

	if (irq) {
		ret = request_irq(irq, labpc_interrupt, isr_flags,
				  dev->board_name, dev);
		if (ret == 0)
			dev->irq = irq;
	}

	if (dev->mmio) {
		dev->pacer =
		    comedi_8254_mm_alloc(dev->mmio + COUNTER_B_BASE_REG,
					 I8254_OSC_BASE_2MHZ, I8254_IO8, 0);
		devpriv->counter =
		    comedi_8254_mm_alloc(dev->mmio + COUNTER_A_BASE_REG,
					 I8254_OSC_BASE_2MHZ, I8254_IO8, 0);
	} else {
		dev->pacer =
		    comedi_8254_io_alloc(dev->iobase + COUNTER_B_BASE_REG,
					 I8254_OSC_BASE_2MHZ, I8254_IO8, 0);
		devpriv->counter =
		    comedi_8254_io_alloc(dev->iobase + COUNTER_A_BASE_REG,
					 I8254_OSC_BASE_2MHZ, I8254_IO8, 0);
	}
	if (IS_ERR(dev->pacer))
		return PTR_ERR(dev->pacer);
	if (IS_ERR(devpriv->counter))
		return PTR_ERR(devpriv->counter);

	ret = comedi_alloc_subdevices(dev, 5);
	if (ret)
		return ret;

	/* analog input subdevice */
	s = &dev->subdevices[0];
	s->type		= COMEDI_SUBD_AI;
	s->subdev_flags	= SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
	s->n_chan	= 8;
	s->len_chanlist	= 8;
	s->maxdata	= 0x0fff;
	s->range_table	= board->is_labpc1200 ?
			  &range_labpc_1200_ai : &range_labpc_plus_ai;
	s->insn_read	= labpc_ai_insn_read;
	if (dev->irq) {
		dev->read_subdev = s;
		s->subdev_flags	|= SDF_CMD_READ;
		s->do_cmd	= labpc_ai_cmd;
		s->do_cmdtest	= labpc_ai_cmdtest;
		s->cancel	= labpc_cancel;
	}

	/* analog output */
	s = &dev->subdevices[1];
	if (board->has_ao) {
		s->type		= COMEDI_SUBD_AO;
		s->subdev_flags	= SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
		s->n_chan	= 2;
		s->maxdata	= 0x0fff;
		s->range_table	= &range_labpc_ao;
		s->insn_write	= labpc_ao_insn_write;

		ret = comedi_alloc_subdev_readback(s);
		if (ret)
			return ret;

		/* initialize analog outputs to a known value */
		for (i = 0; i < s->n_chan; i++)
			labpc_ao_write(dev, s, i, s->maxdata / 2);
	} else {
		s->type		= COMEDI_SUBD_UNUSED;
	}

	/* 8255 dio */
	s = &dev->subdevices[2];
	if (dev->mmio)
		ret = subdev_8255_mm_init(dev, s, DIO_BASE_REG);
	else
		ret = subdev_8255_io_init(dev, s, DIO_BASE_REG);
	if (ret)
		return ret;

	/*  calibration subdevices for boards that have one */
	s = &dev->subdevices[3];
	if (board->is_labpc1200) {
		s->type		= COMEDI_SUBD_CALIB;
		s->subdev_flags	= SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
		s->n_chan	= 16;
		s->maxdata	= 0xff;
		s->insn_write	= labpc_calib_insn_write;

		ret = comedi_alloc_subdev_readback(s);
		if (ret)
			return ret;

		for (i = 0; i < s->n_chan; i++) {
			write_caldac(dev, i, s->maxdata / 2);
			s->readback[i] = s->maxdata / 2;
		}
	} else {
		s->type		= COMEDI_SUBD_UNUSED;
	}

	/* EEPROM (256 bytes) */
	s = &dev->subdevices[4];
	if (board->is_labpc1200) {
		s->type		= COMEDI_SUBD_MEMORY;
		s->subdev_flags	= SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
		s->n_chan	= 256;
		s->maxdata	= 0xff;
		s->insn_write	= labpc_eeprom_insn_write;

		ret = comedi_alloc_subdev_readback(s);
		if (ret)
			return ret;

		for (i = 0; i < s->n_chan; i++)
			s->readback[i] = labpc_eeprom_read(dev, i);
	} else {
		s->type		= COMEDI_SUBD_UNUSED;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(labpc_common_attach);

void labpc_common_detach(struct comedi_device *dev)
{
	struct labpc_private *devpriv = dev->private;

	if (devpriv) {
		if (!IS_ERR(devpriv->counter))
			kfree(devpriv->counter);
	}
}
EXPORT_SYMBOL_GPL(labpc_common_detach);

static int __init labpc_common_init(void)
{
	return 0;
}
module_init(labpc_common_init);

static void __exit labpc_common_exit(void)
{
}
module_exit(labpc_common_exit);

MODULE_AUTHOR("Comedi https://www.comedi.org");
MODULE_DESCRIPTION("Comedi helper for ni_labpc, ni_labpc_pci, ni_labpc_cs");
MODULE_LICENSE("GPL");
