// SPDX-License-Identifier: GPL-2.0+
/*
 * gsc_hpdi.c
 * Comedi driver the General Standards Corporation
 * High Speed Parallel Digital Interface rs485 boards.
 *
 * Author:  Frank Mori Hess <fmhess@users.sourceforge.net>
 * Copyright (C) 2003 Coherent Imaging Systems
 *
 * COMEDI - Linux Control and Measurement Device Interface
 * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
 */

/*
 * Driver: gsc_hpdi
 * Description: General Standards Corporation High
 *    Speed Parallel Digital Interface rs485 boards
 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
 * Status: only receive mode works, transmit not supported
 * Updated: Thu, 01 Nov 2012 16:17:38 +0000
 * Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
 *   PMC-HPDI32
 *
 * Configuration options:
 *    None.
 *
 * Manual configuration of supported devices is not supported; they are
 * configured automatically.
 *
 * There are some additional hpdi models available from GSC for which
 * support could be added to this driver.
 */

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

#include "../comedi_pci.h"

#include "plx9080.h"

/*
 * PCI BAR2 Register map (dev->mmio)
 */
#define FIRMWARE_REV_REG			0x00
#define FEATURES_REG_PRESENT_BIT		BIT(15)
#define BOARD_CONTROL_REG			0x04
#define BOARD_RESET_BIT				BIT(0)
#define TX_FIFO_RESET_BIT			BIT(1)
#define RX_FIFO_RESET_BIT			BIT(2)
#define TX_ENABLE_BIT				BIT(4)
#define RX_ENABLE_BIT				BIT(5)
#define DEMAND_DMA_DIRECTION_TX_BIT		BIT(6)  /* ch 0 only */
#define LINE_VALID_ON_STATUS_VALID_BIT		BIT(7)
#define START_TX_BIT				BIT(8)
#define CABLE_THROTTLE_ENABLE_BIT		BIT(9)
#define TEST_MODE_ENABLE_BIT			BIT(31)
#define BOARD_STATUS_REG			0x08
#define COMMAND_LINE_STATUS_MASK		(0x7f << 0)
#define TX_IN_PROGRESS_BIT			BIT(7)
#define TX_NOT_EMPTY_BIT			BIT(8)
#define TX_NOT_ALMOST_EMPTY_BIT			BIT(9)
#define TX_NOT_ALMOST_FULL_BIT			BIT(10)
#define TX_NOT_FULL_BIT				BIT(11)
#define RX_NOT_EMPTY_BIT			BIT(12)
#define RX_NOT_ALMOST_EMPTY_BIT			BIT(13)
#define RX_NOT_ALMOST_FULL_BIT			BIT(14)
#define RX_NOT_FULL_BIT				BIT(15)
#define BOARD_JUMPER0_INSTALLED_BIT		BIT(16)
#define BOARD_JUMPER1_INSTALLED_BIT		BIT(17)
#define TX_OVERRUN_BIT				BIT(21)
#define RX_UNDERRUN_BIT				BIT(22)
#define RX_OVERRUN_BIT				BIT(23)
#define TX_PROG_ALMOST_REG			0x0c
#define RX_PROG_ALMOST_REG			0x10
#define ALMOST_EMPTY_BITS(x)			(((x) & 0xffff) << 0)
#define ALMOST_FULL_BITS(x)			(((x) & 0xff) << 16)
#define FEATURES_REG				0x14
#define FIFO_SIZE_PRESENT_BIT			BIT(0)
#define FIFO_WORDS_PRESENT_BIT			BIT(1)
#define LEVEL_EDGE_INTERRUPTS_PRESENT_BIT	BIT(2)
#define GPIO_SUPPORTED_BIT			BIT(3)
#define PLX_DMA_CH1_SUPPORTED_BIT		BIT(4)
#define OVERRUN_UNDERRUN_SUPPORTED_BIT		BIT(5)
#define FIFO_REG				0x18
#define TX_STATUS_COUNT_REG			0x1c
#define TX_LINE_VALID_COUNT_REG			0x20,
#define TX_LINE_INVALID_COUNT_REG		0x24
#define RX_STATUS_COUNT_REG			0x28
#define RX_LINE_COUNT_REG			0x2c
#define INTERRUPT_CONTROL_REG			0x30
#define FRAME_VALID_START_INTR			BIT(0)
#define FRAME_VALID_END_INTR			BIT(1)
#define TX_FIFO_EMPTY_INTR			BIT(8)
#define TX_FIFO_ALMOST_EMPTY_INTR		BIT(9)
#define TX_FIFO_ALMOST_FULL_INTR		BIT(10)
#define TX_FIFO_FULL_INTR			BIT(11)
#define RX_EMPTY_INTR				BIT(12)
#define RX_ALMOST_EMPTY_INTR			BIT(13)
#define RX_ALMOST_FULL_INTR			BIT(14)
#define RX_FULL_INTR				BIT(15)
#define INTERRUPT_STATUS_REG			0x34
#define TX_CLOCK_DIVIDER_REG			0x38
#define TX_FIFO_SIZE_REG			0x40
#define RX_FIFO_SIZE_REG			0x44
#define FIFO_SIZE_MASK				(0xfffff << 0)
#define TX_FIFO_WORDS_REG			0x48
#define RX_FIFO_WORDS_REG			0x4c
#define INTERRUPT_EDGE_LEVEL_REG		0x50
#define INTERRUPT_POLARITY_REG			0x54

#define TIMER_BASE				50	/* 20MHz master clock */
#define DMA_BUFFER_SIZE				0x10000
#define NUM_DMA_BUFFERS				4
#define NUM_DMA_DESCRIPTORS			256

struct hpdi_private {
	void __iomem *plx9080_mmio;
	u32 *dio_buffer[NUM_DMA_BUFFERS];	/* dma buffers */
	/* physical addresses of dma buffers */
	dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];
	/*
	 * array of dma descriptors read by plx9080, allocated to get proper
	 * alignment
	 */
	struct plx_dma_desc *dma_desc;
	/* physical address of dma descriptor array */
	dma_addr_t dma_desc_phys_addr;
	unsigned int num_dma_descriptors;
	/* pointer to start of buffers indexed by descriptor */
	u32 *desc_dio_buffer[NUM_DMA_DESCRIPTORS];
	/* index of the dma descriptor that is currently being used */
	unsigned int dma_desc_index;
	unsigned int tx_fifo_size;
	unsigned int rx_fifo_size;
	unsigned long dio_count;
	/* number of bytes at which to generate COMEDI_CB_BLOCK events */
	unsigned int block_size;
};

static void gsc_hpdi_drain_dma(struct comedi_device *dev, unsigned int channel)
{
	struct hpdi_private *devpriv = dev->private;
	struct comedi_subdevice *s = dev->read_subdev;
	struct comedi_cmd *cmd = &s->async->cmd;
	unsigned int idx;
	unsigned int start;
	unsigned int desc;
	unsigned int size;
	unsigned int next;

	next = readl(devpriv->plx9080_mmio + PLX_REG_DMAPADR(channel));

	idx = devpriv->dma_desc_index;
	start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr);
	/* loop until we have read all the full buffers */
	for (desc = 0; (next < start || next >= start + devpriv->block_size) &&
	     desc < devpriv->num_dma_descriptors; desc++) {
		/* transfer data from dma buffer to comedi buffer */
		size = devpriv->block_size / sizeof(u32);
		if (cmd->stop_src == TRIG_COUNT) {
			if (size > devpriv->dio_count)
				size = devpriv->dio_count;
			devpriv->dio_count -= size;
		}
		comedi_buf_write_samples(s, devpriv->desc_dio_buffer[idx],
					 size);
		idx++;
		idx %= devpriv->num_dma_descriptors;
		start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr);

		devpriv->dma_desc_index = idx;
	}
	/* XXX check for buffer overrun somehow */
}

static irqreturn_t gsc_hpdi_interrupt(int irq, void *d)
{
	struct comedi_device *dev = d;
	struct hpdi_private *devpriv = dev->private;
	struct comedi_subdevice *s = dev->read_subdev;
	struct comedi_async *async = s->async;
	u32 hpdi_intr_status, hpdi_board_status;
	u32 plx_status;
	u32 plx_bits;
	u8 dma0_status, dma1_status;
	unsigned long flags;

	if (!dev->attached)
		return IRQ_NONE;

	plx_status = readl(devpriv->plx9080_mmio + PLX_REG_INTCSR);
	if ((plx_status &
	     (PLX_INTCSR_DMA0IA | PLX_INTCSR_DMA1IA | PLX_INTCSR_PLIA)) == 0)
		return IRQ_NONE;

	hpdi_intr_status = readl(dev->mmio + INTERRUPT_STATUS_REG);
	hpdi_board_status = readl(dev->mmio + BOARD_STATUS_REG);

	if (hpdi_intr_status)
		writel(hpdi_intr_status, dev->mmio + INTERRUPT_STATUS_REG);

	/* spin lock makes sure no one else changes plx dma control reg */
	spin_lock_irqsave(&dev->spinlock, flags);
	dma0_status = readb(devpriv->plx9080_mmio + PLX_REG_DMACSR0);
	if (plx_status & PLX_INTCSR_DMA0IA) {
		/* dma chan 0 interrupt */
		writeb((dma0_status & PLX_DMACSR_ENABLE) | PLX_DMACSR_CLEARINTR,
		       devpriv->plx9080_mmio + PLX_REG_DMACSR0);

		if (dma0_status & PLX_DMACSR_ENABLE)
			gsc_hpdi_drain_dma(dev, 0);
	}
	spin_unlock_irqrestore(&dev->spinlock, flags);

	/* spin lock makes sure no one else changes plx dma control reg */
	spin_lock_irqsave(&dev->spinlock, flags);
	dma1_status = readb(devpriv->plx9080_mmio + PLX_REG_DMACSR1);
	if (plx_status & PLX_INTCSR_DMA1IA) {
		/* XXX */ /* dma chan 1 interrupt */
		writeb((dma1_status & PLX_DMACSR_ENABLE) | PLX_DMACSR_CLEARINTR,
		       devpriv->plx9080_mmio + PLX_REG_DMACSR1);
	}
	spin_unlock_irqrestore(&dev->spinlock, flags);

	/* clear possible plx9080 interrupt sources */
	if (plx_status & PLX_INTCSR_LDBIA) {
		/* clear local doorbell interrupt */
		plx_bits = readl(devpriv->plx9080_mmio + PLX_REG_L2PDBELL);
		writel(plx_bits, devpriv->plx9080_mmio + PLX_REG_L2PDBELL);
	}

	if (hpdi_board_status & RX_OVERRUN_BIT) {
		dev_err(dev->class_dev, "rx fifo overrun\n");
		async->events |= COMEDI_CB_ERROR;
	}

	if (hpdi_board_status & RX_UNDERRUN_BIT) {
		dev_err(dev->class_dev, "rx fifo underrun\n");
		async->events |= COMEDI_CB_ERROR;
	}

	if (devpriv->dio_count == 0)
		async->events |= COMEDI_CB_EOA;

	comedi_handle_events(dev, s);

	return IRQ_HANDLED;
}

static void gsc_hpdi_abort_dma(struct comedi_device *dev, unsigned int channel)
{
	struct hpdi_private *devpriv = dev->private;
	unsigned long flags;

	/* spinlock for plx dma control/status reg */
	spin_lock_irqsave(&dev->spinlock, flags);

	plx9080_abort_dma(devpriv->plx9080_mmio, channel);

	spin_unlock_irqrestore(&dev->spinlock, flags);
}

static int gsc_hpdi_cancel(struct comedi_device *dev,
			   struct comedi_subdevice *s)
{
	writel(0, dev->mmio + BOARD_CONTROL_REG);
	writel(0, dev->mmio + INTERRUPT_CONTROL_REG);

	gsc_hpdi_abort_dma(dev, 0);

	return 0;
}

static int gsc_hpdi_cmd(struct comedi_device *dev,
			struct comedi_subdevice *s)
{
	struct hpdi_private *devpriv = dev->private;
	struct comedi_async *async = s->async;
	struct comedi_cmd *cmd = &async->cmd;
	unsigned long flags;
	u32 bits;

	if (s->io_bits)
		return -EINVAL;

	writel(RX_FIFO_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);

	gsc_hpdi_abort_dma(dev, 0);

	devpriv->dma_desc_index = 0;

	/*
	 * These register are supposedly unused during chained dma,
	 * but I have found that left over values from last operation
	 * occasionally cause problems with transfer of first dma
	 * block.  Initializing them to zero seems to fix the problem.
	 */
	writel(0, devpriv->plx9080_mmio + PLX_REG_DMASIZ0);
	writel(0, devpriv->plx9080_mmio + PLX_REG_DMAPADR0);
	writel(0, devpriv->plx9080_mmio + PLX_REG_DMALADR0);

	/* give location of first dma descriptor */
	bits = devpriv->dma_desc_phys_addr | PLX_DMADPR_DESCPCI |
	       PLX_DMADPR_TCINTR | PLX_DMADPR_XFERL2P;
	writel(bits, devpriv->plx9080_mmio + PLX_REG_DMADPR0);

	/* enable dma transfer */
	spin_lock_irqsave(&dev->spinlock, flags);
	writeb(PLX_DMACSR_ENABLE | PLX_DMACSR_START | PLX_DMACSR_CLEARINTR,
	       devpriv->plx9080_mmio + PLX_REG_DMACSR0);
	spin_unlock_irqrestore(&dev->spinlock, flags);

	if (cmd->stop_src == TRIG_COUNT)
		devpriv->dio_count = cmd->stop_arg;
	else
		devpriv->dio_count = 1;

	/* clear over/under run status flags */
	writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT, dev->mmio + BOARD_STATUS_REG);

	/* enable interrupts */
	writel(RX_FULL_INTR, dev->mmio + INTERRUPT_CONTROL_REG);

	writel(RX_ENABLE_BIT, dev->mmio + BOARD_CONTROL_REG);

	return 0;
}

static int gsc_hpdi_check_chanlist(struct comedi_device *dev,
				   struct comedi_subdevice *s,
				   struct comedi_cmd *cmd)
{
	int i;

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

		if (chan != i) {
			dev_dbg(dev->class_dev,
				"chanlist must be ch 0 to 31 in order\n");
			return -EINVAL;
		}
	}

	return 0;
}

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

	if (s->io_bits)
		return -EINVAL;

	/* 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_EXT);
	err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW);
	err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
	err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);

	if (err)
		return 1;

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

	err |= comedi_check_trigger_is_unique(cmd->stop_src);

	/* Step 2b : and mutually compatible */

	if (err)
		return 2;

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

	err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);

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

	if (cmd->stop_src == TRIG_COUNT)
		err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
	else	/* TRIG_NONE */
		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 */

	if (cmd->chanlist && cmd->chanlist_len > 0)
		err |= gsc_hpdi_check_chanlist(dev, s, cmd);

	if (err)
		return 5;

	return 0;
}

/* setup dma descriptors so a link completes every 'len' bytes */
static int gsc_hpdi_setup_dma_descriptors(struct comedi_device *dev,
					  unsigned int len)
{
	struct hpdi_private *devpriv = dev->private;
	dma_addr_t phys_addr = devpriv->dma_desc_phys_addr;
	u32 next_bits = PLX_DMADPR_DESCPCI | PLX_DMADPR_TCINTR |
			PLX_DMADPR_XFERL2P;
	unsigned int offset = 0;
	unsigned int idx = 0;
	unsigned int i;

	if (len > DMA_BUFFER_SIZE)
		len = DMA_BUFFER_SIZE;
	len -= len % sizeof(u32);
	if (len == 0)
		return -EINVAL;

	for (i = 0; i < NUM_DMA_DESCRIPTORS && idx < NUM_DMA_BUFFERS; i++) {
		devpriv->dma_desc[i].pci_start_addr =
		    cpu_to_le32(devpriv->dio_buffer_phys_addr[idx] + offset);
		devpriv->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
		devpriv->dma_desc[i].transfer_size = cpu_to_le32(len);
		devpriv->dma_desc[i].next = cpu_to_le32((phys_addr +
			(i + 1) * sizeof(devpriv->dma_desc[0])) | next_bits);

		devpriv->desc_dio_buffer[i] = devpriv->dio_buffer[idx] +
					      (offset / sizeof(u32));

		offset += len;
		if (len + offset > DMA_BUFFER_SIZE) {
			offset = 0;
			idx++;
		}
	}
	devpriv->num_dma_descriptors = i;
	/* fix last descriptor to point back to first */
	devpriv->dma_desc[i - 1].next = cpu_to_le32(phys_addr | next_bits);

	devpriv->block_size = len;

	return len;
}

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

	switch (data[0]) {
	case INSN_CONFIG_BLOCK_SIZE:
		ret = gsc_hpdi_setup_dma_descriptors(dev, data[1]);
		if (ret)
			return ret;

		data[1] = ret;
		break;
	default:
		ret = comedi_dio_insn_config(dev, s, insn, data, 0xffffffff);
		if (ret)
			return ret;
		break;
	}

	return insn->n;
}

static void gsc_hpdi_free_dma(struct comedi_device *dev)
{
	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
	struct hpdi_private *devpriv = dev->private;
	int i;

	if (!devpriv)
		return;

	/* free pci dma buffers */
	for (i = 0; i < NUM_DMA_BUFFERS; i++) {
		if (devpriv->dio_buffer[i])
			dma_free_coherent(&pcidev->dev,
					  DMA_BUFFER_SIZE,
					  devpriv->dio_buffer[i],
					  devpriv->dio_buffer_phys_addr[i]);
	}
	/* free dma descriptors */
	if (devpriv->dma_desc)
		dma_free_coherent(&pcidev->dev,
				  sizeof(struct plx_dma_desc) *
				  NUM_DMA_DESCRIPTORS,
				  devpriv->dma_desc,
				  devpriv->dma_desc_phys_addr);
}

static int gsc_hpdi_init(struct comedi_device *dev)
{
	struct hpdi_private *devpriv = dev->private;
	u32 plx_intcsr_bits;

	/* wait 10usec after reset before accessing fifos */
	writel(BOARD_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);
	usleep_range(10, 1000);

	writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
	       dev->mmio + RX_PROG_ALMOST_REG);
	writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
	       dev->mmio + TX_PROG_ALMOST_REG);

	devpriv->tx_fifo_size = readl(dev->mmio + TX_FIFO_SIZE_REG) &
				FIFO_SIZE_MASK;
	devpriv->rx_fifo_size = readl(dev->mmio + RX_FIFO_SIZE_REG) &
				FIFO_SIZE_MASK;

	writel(0, dev->mmio + INTERRUPT_CONTROL_REG);

	/* enable interrupts */
	plx_intcsr_bits =
	    PLX_INTCSR_LSEABORTEN | PLX_INTCSR_LSEPARITYEN | PLX_INTCSR_PIEN |
	    PLX_INTCSR_PLIEN | PLX_INTCSR_PABORTIEN | PLX_INTCSR_LIOEN |
	    PLX_INTCSR_DMA0IEN;
	writel(plx_intcsr_bits, devpriv->plx9080_mmio + PLX_REG_INTCSR);

	return 0;
}

static void gsc_hpdi_init_plx9080(struct comedi_device *dev)
{
	struct hpdi_private *devpriv = dev->private;
	u32 bits;
	void __iomem *plx_iobase = devpriv->plx9080_mmio;

#ifdef __BIG_ENDIAN
	bits = PLX_BIGEND_DMA0 | PLX_BIGEND_DMA1;
#else
	bits = 0;
#endif
	writel(bits, devpriv->plx9080_mmio + PLX_REG_BIGEND);

	writel(0, devpriv->plx9080_mmio + PLX_REG_INTCSR);

	gsc_hpdi_abort_dma(dev, 0);
	gsc_hpdi_abort_dma(dev, 1);

	/* configure dma0 mode */
	bits = 0;
	/* enable ready input */
	bits |= PLX_DMAMODE_READYIEN;
	/* enable dma chaining */
	bits |= PLX_DMAMODE_CHAINEN;
	/*
	 * enable interrupt on dma done
	 * (probably don't need this, since chain never finishes)
	 */
	bits |= PLX_DMAMODE_DONEIEN;
	/*
	 * don't increment local address during transfers
	 * (we are transferring from a fixed fifo register)
	 */
	bits |= PLX_DMAMODE_LACONST;
	/* route dma interrupt to pci bus */
	bits |= PLX_DMAMODE_INTRPCI;
	/* enable demand mode */
	bits |= PLX_DMAMODE_DEMAND;
	/* enable local burst mode */
	bits |= PLX_DMAMODE_BURSTEN;
	bits |= PLX_DMAMODE_WIDTH_32;
	writel(bits, plx_iobase + PLX_REG_DMAMODE0);
}

static int gsc_hpdi_auto_attach(struct comedi_device *dev,
				unsigned long context_unused)
{
	struct pci_dev *pcidev = comedi_to_pci_dev(dev);
	struct hpdi_private *devpriv;
	struct comedi_subdevice *s;
	int i;
	int retval;

	dev->board_name = "pci-hpdi32";

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

	retval = comedi_pci_enable(dev);
	if (retval)
		return retval;
	pci_set_master(pcidev);

	devpriv->plx9080_mmio = pci_ioremap_bar(pcidev, 0);
	dev->mmio = pci_ioremap_bar(pcidev, 2);
	if (!devpriv->plx9080_mmio || !dev->mmio) {
		dev_warn(dev->class_dev, "failed to remap io memory\n");
		return -ENOMEM;
	}

	gsc_hpdi_init_plx9080(dev);

	/* get irq */
	if (request_irq(pcidev->irq, gsc_hpdi_interrupt, IRQF_SHARED,
			dev->board_name, dev)) {
		dev_warn(dev->class_dev,
			 "unable to allocate irq %u\n", pcidev->irq);
		return -EINVAL;
	}
	dev->irq = pcidev->irq;

	dev_dbg(dev->class_dev, " irq %u\n", dev->irq);

	/* allocate pci dma buffers */
	for (i = 0; i < NUM_DMA_BUFFERS; i++) {
		devpriv->dio_buffer[i] =
		    dma_alloc_coherent(&pcidev->dev, DMA_BUFFER_SIZE,
				       &devpriv->dio_buffer_phys_addr[i],
				       GFP_KERNEL);
		if (!devpriv->dio_buffer[i]) {
			dev_warn(dev->class_dev,
				 "failed to allocate DMA buffer\n");
			return -ENOMEM;
		}
	}
	/* allocate dma descriptors */
	devpriv->dma_desc = dma_alloc_coherent(&pcidev->dev,
					       sizeof(struct plx_dma_desc) *
					       NUM_DMA_DESCRIPTORS,
					       &devpriv->dma_desc_phys_addr,
					       GFP_KERNEL);
	if (!devpriv->dma_desc) {
		dev_warn(dev->class_dev,
			 "failed to allocate DMA descriptors\n");
		return -ENOMEM;
	}
	if (devpriv->dma_desc_phys_addr & 0xf) {
		dev_warn(dev->class_dev,
			 " dma descriptors not quad-word aligned (bug)\n");
		return -EIO;
	}

	retval = gsc_hpdi_setup_dma_descriptors(dev, 0x1000);
	if (retval < 0)
		return retval;

	retval = comedi_alloc_subdevices(dev, 1);
	if (retval)
		return retval;

	/* Digital I/O subdevice */
	s = &dev->subdevices[0];
	dev->read_subdev = s;
	s->type		= COMEDI_SUBD_DIO;
	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
			  SDF_CMD_READ;
	s->n_chan	= 32;
	s->len_chanlist	= 32;
	s->maxdata	= 1;
	s->range_table	= &range_digital;
	s->insn_config	= gsc_hpdi_dio_insn_config;
	s->do_cmd	= gsc_hpdi_cmd;
	s->do_cmdtest	= gsc_hpdi_cmd_test;
	s->cancel	= gsc_hpdi_cancel;

	return gsc_hpdi_init(dev);
}

static void gsc_hpdi_detach(struct comedi_device *dev)
{
	struct hpdi_private *devpriv = dev->private;

	if (dev->irq)
		free_irq(dev->irq, dev);
	if (devpriv) {
		if (devpriv->plx9080_mmio) {
			writel(0, devpriv->plx9080_mmio + PLX_REG_INTCSR);
			iounmap(devpriv->plx9080_mmio);
		}
		if (dev->mmio)
			iounmap(dev->mmio);
	}
	comedi_pci_disable(dev);
	gsc_hpdi_free_dma(dev);
}

static struct comedi_driver gsc_hpdi_driver = {
	.driver_name	= "gsc_hpdi",
	.module		= THIS_MODULE,
	.auto_attach	= gsc_hpdi_auto_attach,
	.detach		= gsc_hpdi_detach,
};

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

static const struct pci_device_id gsc_hpdi_pci_table[] = {
	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080,
			 PCI_VENDOR_ID_PLX, 0x2400) },
	{ 0 }
};
MODULE_DEVICE_TABLE(pci, gsc_hpdi_pci_table);

static struct pci_driver gsc_hpdi_pci_driver = {
	.name		= "gsc_hpdi",
	.id_table	= gsc_hpdi_pci_table,
	.probe		= gsc_hpdi_pci_probe,
	.remove		= comedi_pci_auto_unconfig,
};
module_comedi_pci_driver(gsc_hpdi_driver, gsc_hpdi_pci_driver);

MODULE_AUTHOR("Comedi https://www.comedi.org");
MODULE_DESCRIPTION("Comedi driver for General Standards PCI-HPDI32/PMC-HPDI32");
MODULE_LICENSE("GPL");
