// SPDX-License-Identifier: GPL-2.0+
/*
 * ni_6527.c
 * Comedi driver for National Instruments PCI-6527
 *
 * COMEDI - Linux Control and Measurement Device Interface
 * Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
 */

/*
 * Driver: ni_6527
 * Description: National Instruments 6527
 * Devices: [National Instruments] PCI-6527 (pci-6527), PXI-6527 (pxi-6527)
 * Author: David A. Schleef <ds@schleef.org>
 * Updated: Sat, 25 Jan 2003 13:24:40 -0800
 * Status: works
 *
 * Configuration Options: not applicable, uses PCI auto config
 */

#include <linux/module.h>
#include <linux/interrupt.h>

#include "../comedi_pci.h"

/*
 * PCI BAR1 - Register memory map
 *
 * Manuals (available from ftp://ftp.natinst.com/support/manuals)
 *	370106b.pdf	6527 Register Level Programmer Manual
 */
#define NI6527_DI_REG(x)		(0x00 + (x))
#define NI6527_DO_REG(x)		(0x03 + (x))
#define NI6527_ID_REG			0x06
#define NI6527_CLR_REG			0x07
#define NI6527_CLR_EDGE			BIT(3)
#define NI6527_CLR_OVERFLOW		BIT(2)
#define NI6527_CLR_FILT			BIT(1)
#define NI6527_CLR_INTERVAL		BIT(0)
#define NI6527_CLR_IRQS			(NI6527_CLR_EDGE | NI6527_CLR_OVERFLOW)
#define NI6527_CLR_RESET_FILT		(NI6527_CLR_FILT | NI6527_CLR_INTERVAL)
#define NI6527_FILT_INTERVAL_REG(x)	(0x08 + (x))
#define NI6527_FILT_ENA_REG(x)		(0x0c + (x))
#define NI6527_STATUS_REG		0x14
#define NI6527_STATUS_IRQ		BIT(2)
#define NI6527_STATUS_OVERFLOW		BIT(1)
#define NI6527_STATUS_EDGE		BIT(0)
#define NI6527_CTRL_REG			0x15
#define NI6527_CTRL_FALLING		BIT(4)
#define NI6527_CTRL_RISING		BIT(3)
#define NI6527_CTRL_IRQ			BIT(2)
#define NI6527_CTRL_OVERFLOW		BIT(1)
#define NI6527_CTRL_EDGE		BIT(0)
#define NI6527_CTRL_DISABLE_IRQS	0
#define NI6527_CTRL_ENABLE_IRQS		(NI6527_CTRL_FALLING | \
					 NI6527_CTRL_RISING | \
					 NI6527_CTRL_IRQ | NI6527_CTRL_EDGE)
#define NI6527_RISING_EDGE_REG(x)	(0x18 + (x))
#define NI6527_FALLING_EDGE_REG(x)	(0x20 + (x))

enum ni6527_boardid {
	BOARD_PCI6527,
	BOARD_PXI6527,
};

struct ni6527_board {
	const char *name;
};

static const struct ni6527_board ni6527_boards[] = {
	[BOARD_PCI6527] = {
		.name		= "pci-6527",
	},
	[BOARD_PXI6527] = {
		.name		= "pxi-6527",
	},
};

struct ni6527_private {
	unsigned int filter_interval;
	unsigned int filter_enable;
};

static void ni6527_set_filter_interval(struct comedi_device *dev,
				       unsigned int val)
{
	struct ni6527_private *devpriv = dev->private;

	if (val != devpriv->filter_interval) {
		writeb(val & 0xff, dev->mmio + NI6527_FILT_INTERVAL_REG(0));
		writeb((val >> 8) & 0xff,
		       dev->mmio + NI6527_FILT_INTERVAL_REG(1));
		writeb((val >> 16) & 0x0f,
		       dev->mmio + NI6527_FILT_INTERVAL_REG(2));

		writeb(NI6527_CLR_INTERVAL, dev->mmio + NI6527_CLR_REG);

		devpriv->filter_interval = val;
	}
}

static void ni6527_set_filter_enable(struct comedi_device *dev,
				     unsigned int val)
{
	writeb(val & 0xff, dev->mmio + NI6527_FILT_ENA_REG(0));
	writeb((val >> 8) & 0xff, dev->mmio + NI6527_FILT_ENA_REG(1));
	writeb((val >> 16) & 0xff, dev->mmio + NI6527_FILT_ENA_REG(2));
}

static int ni6527_di_insn_config(struct comedi_device *dev,
				 struct comedi_subdevice *s,
				 struct comedi_insn *insn,
				 unsigned int *data)
{
	struct ni6527_private *devpriv = dev->private;
	unsigned int chan = CR_CHAN(insn->chanspec);
	unsigned int interval;

	switch (data[0]) {
	case INSN_CONFIG_FILTER:
		/*
		 * The deglitch filter interval is specified in nanoseconds.
		 * The hardware supports intervals in 200ns increments. Round
		 * the user values up and return the actual interval.
		 */
		interval = (data[1] + 100) / 200;
		data[1] = interval * 200;

		if (interval) {
			ni6527_set_filter_interval(dev, interval);
			devpriv->filter_enable |= 1 << chan;
		} else {
			devpriv->filter_enable &= ~(1 << chan);
		}
		ni6527_set_filter_enable(dev, devpriv->filter_enable);
		break;
	default:
		return -EINVAL;
	}

	return insn->n;
}

static int ni6527_di_insn_bits(struct comedi_device *dev,
			       struct comedi_subdevice *s,
			       struct comedi_insn *insn,
			       unsigned int *data)
{
	unsigned int val;

	val = readb(dev->mmio + NI6527_DI_REG(0));
	val |= (readb(dev->mmio + NI6527_DI_REG(1)) << 8);
	val |= (readb(dev->mmio + NI6527_DI_REG(2)) << 16);

	data[1] = val;

	return insn->n;
}

static int ni6527_do_insn_bits(struct comedi_device *dev,
			       struct comedi_subdevice *s,
			       struct comedi_insn *insn,
			       unsigned int *data)
{
	unsigned int mask;

	mask = comedi_dio_update_state(s, data);
	if (mask) {
		/* Outputs are inverted */
		unsigned int val = s->state ^ 0xffffff;

		if (mask & 0x0000ff)
			writeb(val & 0xff, dev->mmio + NI6527_DO_REG(0));
		if (mask & 0x00ff00)
			writeb((val >> 8) & 0xff,
			       dev->mmio + NI6527_DO_REG(1));
		if (mask & 0xff0000)
			writeb((val >> 16) & 0xff,
			       dev->mmio + NI6527_DO_REG(2));
	}

	data[1] = s->state;

	return insn->n;
}

static irqreturn_t ni6527_interrupt(int irq, void *d)
{
	struct comedi_device *dev = d;
	struct comedi_subdevice *s = dev->read_subdev;
	unsigned int status;

	status = readb(dev->mmio + NI6527_STATUS_REG);
	if (!(status & NI6527_STATUS_IRQ))
		return IRQ_NONE;

	if (status & NI6527_STATUS_EDGE) {
		comedi_buf_write_samples(s, &s->state, 1);
		comedi_handle_events(dev, s);
	}

	writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG);

	return IRQ_HANDLED;
}

static int ni6527_intr_cmdtest(struct comedi_device *dev,
			       struct comedi_subdevice *s,
			       struct comedi_cmd *cmd)
{
	int err = 0;

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

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

	if (err)
		return 1;

	/* Step 2a : make sure trigger sources are unique */
	/* Step 2b : and mutually compatible */

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

	err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
	err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
	err |= comedi_check_trigger_arg_is(&cmd->convert_arg, 0);
	err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
					   cmd->chanlist_len);
	err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);

	if (err)
		return 3;

	/* Step 4: fix up any arguments */

	/* Step 5: check channel list if it exists */

	return 0;
}

static int ni6527_intr_cmd(struct comedi_device *dev,
			   struct comedi_subdevice *s)
{
	writeb(NI6527_CLR_IRQS, dev->mmio + NI6527_CLR_REG);
	writeb(NI6527_CTRL_ENABLE_IRQS, dev->mmio + NI6527_CTRL_REG);

	return 0;
}

static int ni6527_intr_cancel(struct comedi_device *dev,
			      struct comedi_subdevice *s)
{
	writeb(NI6527_CTRL_DISABLE_IRQS, dev->mmio + NI6527_CTRL_REG);

	return 0;
}

static int ni6527_intr_insn_bits(struct comedi_device *dev,
				 struct comedi_subdevice *s,
				 struct comedi_insn *insn, unsigned int *data)
{
	data[1] = 0;
	return insn->n;
}

static void ni6527_set_edge_detection(struct comedi_device *dev,
				      unsigned int mask,
				      unsigned int rising,
				      unsigned int falling)
{
	unsigned int i;

	rising &= mask;
	falling &= mask;
	for (i = 0; i < 2; i++) {
		if (mask & 0xff) {
			if (~mask & 0xff) {
				/* preserve rising-edge detection channels */
				rising |= readb(dev->mmio +
						NI6527_RISING_EDGE_REG(i)) &
					  (~mask & 0xff);
				/* preserve falling-edge detection channels */
				falling |= readb(dev->mmio +
						 NI6527_FALLING_EDGE_REG(i)) &
					   (~mask & 0xff);
			}
			/* update rising-edge detection channels */
			writeb(rising & 0xff,
			       dev->mmio + NI6527_RISING_EDGE_REG(i));
			/* update falling-edge detection channels */
			writeb(falling & 0xff,
			       dev->mmio + NI6527_FALLING_EDGE_REG(i));
		}
		rising >>= 8;
		falling >>= 8;
		mask >>= 8;
	}
}

static int ni6527_intr_insn_config(struct comedi_device *dev,
				   struct comedi_subdevice *s,
				   struct comedi_insn *insn,
				   unsigned int *data)
{
	unsigned int mask = 0xffffffff;
	unsigned int rising, falling, shift;

	switch (data[0]) {
	case INSN_CONFIG_CHANGE_NOTIFY:
		/* check_insn_config_length() does not check this instruction */
		if (insn->n != 3)
			return -EINVAL;
		rising = data[1];
		falling = data[2];
		ni6527_set_edge_detection(dev, mask, rising, falling);
		break;
	case INSN_CONFIG_DIGITAL_TRIG:
		/* check trigger number */
		if (data[1] != 0)
			return -EINVAL;
		/* check digital trigger operation */
		switch (data[2]) {
		case COMEDI_DIGITAL_TRIG_DISABLE:
			rising = 0;
			falling = 0;
			break;
		case COMEDI_DIGITAL_TRIG_ENABLE_EDGES:
			/* check shift amount */
			shift = data[3];
			if (shift >= 32) {
				mask = 0;
				rising = 0;
				falling = 0;
			} else {
				mask <<= shift;
				rising = data[4] << shift;
				falling = data[5] << shift;
			}
			break;
		default:
			return -EINVAL;
		}
		ni6527_set_edge_detection(dev, mask, rising, falling);
		break;
	default:
		return -EINVAL;
	}

	return insn->n;
}

static void ni6527_reset(struct comedi_device *dev)
{
	/* disable deglitch filters on all channels */
	ni6527_set_filter_enable(dev, 0);

	/* disable edge detection */
	ni6527_set_edge_detection(dev, 0xffffffff, 0, 0);

	writeb(NI6527_CLR_IRQS | NI6527_CLR_RESET_FILT,
	       dev->mmio + NI6527_CLR_REG);
	writeb(NI6527_CTRL_DISABLE_IRQS, dev->mmio + NI6527_CTRL_REG);
}

static int ni6527_auto_attach(struct comedi_device *dev,
			      unsigned long context)
{
	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
	const struct ni6527_board *board = NULL;
	struct ni6527_private *devpriv;
	struct comedi_subdevice *s;
	int ret;

	if (context < ARRAY_SIZE(ni6527_boards))
		board = &ni6527_boards[context];
	if (!board)
		return -ENODEV;
	dev->board_ptr = board;
	dev->board_name = board->name;

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

	ret = comedi_pci_enable(dev);
	if (ret)
		return ret;

	dev->mmio = pci_ioremap_bar(pcidev, 1);
	if (!dev->mmio)
		return -ENOMEM;

	/* make sure this is actually a 6527 device */
	if (readb(dev->mmio + NI6527_ID_REG) != 0x27)
		return -ENODEV;

	ni6527_reset(dev);

	ret = request_irq(pcidev->irq, ni6527_interrupt, IRQF_SHARED,
			  dev->board_name, dev);
	if (ret == 0)
		dev->irq = pcidev->irq;

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

	/* Digital Input subdevice */
	s = &dev->subdevices[0];
	s->type		= COMEDI_SUBD_DI;
	s->subdev_flags	= SDF_READABLE;
	s->n_chan	= 24;
	s->maxdata	= 1;
	s->range_table	= &range_digital;
	s->insn_config	= ni6527_di_insn_config;
	s->insn_bits	= ni6527_di_insn_bits;

	/* Digital Output subdevice */
	s = &dev->subdevices[1];
	s->type		= COMEDI_SUBD_DO;
	s->subdev_flags	= SDF_WRITABLE;
	s->n_chan	= 24;
	s->maxdata	= 1;
	s->range_table	= &range_digital;
	s->insn_bits	= ni6527_do_insn_bits;

	/* Edge detection interrupt subdevice */
	s = &dev->subdevices[2];
	if (dev->irq) {
		dev->read_subdev = s;
		s->type		= COMEDI_SUBD_DI;
		s->subdev_flags	= SDF_READABLE | SDF_CMD_READ;
		s->n_chan	= 1;
		s->maxdata	= 1;
		s->range_table	= &range_digital;
		s->insn_config	= ni6527_intr_insn_config;
		s->insn_bits	= ni6527_intr_insn_bits;
		s->len_chanlist	= 1;
		s->do_cmdtest	= ni6527_intr_cmdtest;
		s->do_cmd	= ni6527_intr_cmd;
		s->cancel	= ni6527_intr_cancel;
	} else {
		s->type = COMEDI_SUBD_UNUSED;
	}

	return 0;
}

static void ni6527_detach(struct comedi_device *dev)
{
	if (dev->mmio)
		ni6527_reset(dev);
	comedi_pci_detach(dev);
}

static struct comedi_driver ni6527_driver = {
	.driver_name	= "ni_6527",
	.module		= THIS_MODULE,
	.auto_attach	= ni6527_auto_attach,
	.detach		= ni6527_detach,
};

static int ni6527_pci_probe(struct pci_dev *dev,
			    const struct pci_device_id *id)
{
	return comedi_pci_auto_config(dev, &ni6527_driver, id->driver_data);
}

static const struct pci_device_id ni6527_pci_table[] = {
	{ PCI_VDEVICE(NI, 0x2b10), BOARD_PXI6527 },
	{ PCI_VDEVICE(NI, 0x2b20), BOARD_PCI6527 },
	{ 0 }
};
MODULE_DEVICE_TABLE(pci, ni6527_pci_table);

static struct pci_driver ni6527_pci_driver = {
	.name		= "ni_6527",
	.id_table	= ni6527_pci_table,
	.probe		= ni6527_pci_probe,
	.remove		= comedi_pci_auto_unconfig,
};
module_comedi_pci_driver(ni6527_driver, ni6527_pci_driver);

MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi driver for National Instruments PCI-6527");
MODULE_LICENSE("GPL");
