// SPDX-License-Identifier: GPL-2.0+
/*
 * aio_iiro_16.c
 * Comedi driver for Access I/O Products 104-IIRO-16 board
 * Copyright (C) 2006 C&C Technologies, Inc.
 */

/*
 * Driver: aio_iiro_16
 * Description: Access I/O Products PC/104 Isolated Input/Relay Output Board
 * Author: Zachary Ware <zach.ware@cctechnol.com>
 * Devices: [Access I/O] 104-IIRO-16 (aio_iiro_16)
 * Status: experimental
 *
 * Configuration Options:
 *   [0] - I/O port base address
 *   [1] - IRQ (optional)
 *
 * The board supports interrupts on change of state of the digital inputs.
 * The sample data returned by the async command indicates which inputs
 * changed state and the current state of the inputs:
 *
 *	Bit 23 - IRQ Enable (1) / Disable (0)
 *	Bit 17 - Input 8-15 Changed State (1 = Changed, 0 = No Change)
 *	Bit 16 - Input 0-7 Changed State (1 = Changed, 0 = No Change)
 *	Bit 15 - Digital input 15
 *	...
 *	Bit 0  - Digital input 0
 */

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

#include "../comedidev.h"

#define AIO_IIRO_16_RELAY_0_7		0x00
#define AIO_IIRO_16_INPUT_0_7		0x01
#define AIO_IIRO_16_IRQ			0x02
#define AIO_IIRO_16_RELAY_8_15		0x04
#define AIO_IIRO_16_INPUT_8_15		0x05
#define AIO_IIRO_16_STATUS		0x07
#define AIO_IIRO_16_STATUS_IRQE		BIT(7)
#define AIO_IIRO_16_STATUS_INPUT_8_15	BIT(1)
#define AIO_IIRO_16_STATUS_INPUT_0_7	BIT(0)

static unsigned int aio_iiro_16_read_inputs(struct comedi_device *dev)
{
	unsigned int val;

	val = inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
	val |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;

	return val;
}

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

	status = inb(dev->iobase + AIO_IIRO_16_STATUS);
	if (!(status & AIO_IIRO_16_STATUS_IRQE))
		return IRQ_NONE;

	val = aio_iiro_16_read_inputs(dev);
	val |= (status << 16);

	comedi_buf_write_samples(s, &val, 1);
	comedi_handle_events(dev, s);

	return IRQ_HANDLED;
}

static void aio_iiro_enable_irq(struct comedi_device *dev, bool enable)
{
	if (enable)
		inb(dev->iobase + AIO_IIRO_16_IRQ);
	else
		outb(0, dev->iobase + AIO_IIRO_16_IRQ);
}

static int aio_iiro_16_cos_cancel(struct comedi_device *dev,
				  struct comedi_subdevice *s)
{
	aio_iiro_enable_irq(dev, false);

	return 0;
}

static int aio_iiro_16_cos_cmd(struct comedi_device *dev,
			       struct comedi_subdevice *s)
{
	aio_iiro_enable_irq(dev, true);

	return 0;
}

static int aio_iiro_16_cos_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_EXT);
	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_NONE);

	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 aio_iiro_16_do_insn_bits(struct comedi_device *dev,
				    struct comedi_subdevice *s,
				    struct comedi_insn *insn,
				    unsigned int *data)
{
	if (comedi_dio_update_state(s, data)) {
		outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
		outb((s->state >> 8) & 0xff,
		     dev->iobase + AIO_IIRO_16_RELAY_8_15);
	}

	data[1] = s->state;

	return insn->n;
}

static int aio_iiro_16_di_insn_bits(struct comedi_device *dev,
				    struct comedi_subdevice *s,
				    struct comedi_insn *insn,
				    unsigned int *data)
{
	data[1] = aio_iiro_16_read_inputs(dev);

	return insn->n;
}

static int aio_iiro_16_attach(struct comedi_device *dev,
			      struct comedi_devconfig *it)
{
	struct comedi_subdevice *s;
	int ret;

	ret = comedi_request_region(dev, it->options[0], 0x8);
	if (ret)
		return ret;

	aio_iiro_enable_irq(dev, false);

	/*
	 * Digital input change of state interrupts are optionally supported
	 * using IRQ 2-7, 10-12, 14, or 15.
	 */
	if ((1 << it->options[1]) & 0xdcfc) {
		ret = request_irq(it->options[1], aio_iiro_16_cos, 0,
				  dev->board_name, dev);
		if (ret == 0)
			dev->irq = it->options[1];
	}

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

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

	/* get the initial state of the relays */
	s->state = inb(dev->iobase + AIO_IIRO_16_RELAY_0_7) |
		   (inb(dev->iobase + AIO_IIRO_16_RELAY_8_15) << 8);

	/* Digital Input subdevice */
	s = &dev->subdevices[1];
	s->type		= COMEDI_SUBD_DI;
	s->subdev_flags	= SDF_READABLE;
	s->n_chan	= 16;
	s->maxdata	= 1;
	s->range_table	= &range_digital;
	s->insn_bits	= aio_iiro_16_di_insn_bits;
	if (dev->irq) {
		dev->read_subdev = s;
		s->subdev_flags	|= SDF_CMD_READ | SDF_LSAMPL;
		s->len_chanlist	= 1;
		s->do_cmdtest	= aio_iiro_16_cos_cmdtest;
		s->do_cmd	= aio_iiro_16_cos_cmd;
		s->cancel	= aio_iiro_16_cos_cancel;
	}

	return 0;
}

static struct comedi_driver aio_iiro_16_driver = {
	.driver_name	= "aio_iiro_16",
	.module		= THIS_MODULE,
	.attach		= aio_iiro_16_attach,
	.detach		= comedi_legacy_detach,
};
module_comedi_driver(aio_iiro_16_driver);

MODULE_AUTHOR("Comedi https://www.comedi.org");
MODULE_DESCRIPTION("Comedi driver for Access I/O Products 104-IIRO-16 board");
MODULE_LICENSE("GPL");
