// SPDX-License-Identifier: GPL-2.0+
/*
 * comedi/drivers/ni_usb6501.c
 * Comedi driver for National Instruments USB-6501
 *
 * COMEDI - Linux Control and Measurement Device Interface
 * Copyright (C) 2014 Luca Ellero <luca.ellero@brickedbrain.com>
 */

/*
 * Driver: ni_usb6501
 * Description: National Instruments USB-6501 module
 * Devices: [National Instruments] USB-6501 (ni_usb6501)
 * Author: Luca Ellero <luca.ellero@brickedbrain.com>
 * Updated: 8 Sep 2014
 * Status: works
 *
 *
 * Configuration Options:
 * none
 */

/*
 * NI-6501 - USB PROTOCOL DESCRIPTION
 *
 * Every command is composed by two USB packets:
 *	- request (out)
 *	- response (in)
 *
 * Every packet is at least 12 bytes long, here is the meaning of
 * every field (all values are hex):
 *
 *	byte 0 is always 00
 *	byte 1 is always 01
 *	byte 2 is always 00
 *	byte 3 is the total packet length
 *
 *	byte 4 is always 00
 *	byte 5 is the total packet length - 4
 *	byte 6 is always 01
 *	byte 7 is the command
 *
 *	byte 8 is 02 (request) or 00 (response)
 *	byte 9 is 00 (response) or 10 (port request) or 20 (counter request)
 *	byte 10 is always 00
 *	byte 11 is 00 (request) or 02 (response)
 *
 * PORT PACKETS
 *
 *	CMD: 0xE READ_PORT
 *	REQ: 00 01 00 10 00 0C 01 0E 02 10 00 00 00 03 <PORT> 00
 *	RES: 00 01 00 10 00 0C 01 00 00 00 00 02 00 03 <BMAP> 00
 *
 *	CMD: 0xF WRITE_PORT
 *	REQ: 00 01 00 14 00 10 01 0F 02 10 00 00 00 03 <PORT> 00 03 <BMAP> 00 00
 *	RES: 00 01 00 0C 00 08 01 00 00 00 00 02
 *
 *	CMD: 0x12 SET_PORT_DIR (0 = input, 1 = output)
 *	REQ: 00 01 00 18 00 14 01 12 02 10 00 00
 *	     00 05 <PORT 0> <PORT 1> <PORT 2> 00 05 00 00 00 00 00
 *	RES: 00 01 00 0C 00 08 01 00 00 00 00 02
 *
 * COUNTER PACKETS
 *
 *	CMD 0x9: START_COUNTER
 *	REQ: 00 01 00 0C 00 08 01 09 02 20 00 00
 *	RES: 00 01 00 0C 00 08 01 00 00 00 00 02
 *
 *	CMD 0xC: STOP_COUNTER
 *	REQ: 00 01 00 0C 00 08 01 0C 02 20 00 00
 *	RES: 00 01 00 0C 00 08 01 00 00 00 00 02
 *
 *	CMD 0xE: READ_COUNTER
 *	REQ: 00 01 00 0C 00 08 01 0E 02 20 00 00
 *	RES: 00 01 00 10 00 0C 01 00 00 00 00 02 <u32 counter value, Big Endian>
 *
 *	CMD 0xF: WRITE_COUNTER
 *	REQ: 00 01 00 10 00 0C 01 0F 02 20 00 00 <u32 counter value, Big Endian>
 *	RES: 00 01 00 0C 00 08 01 00 00 00 00 02
 *
 *
 *	Please  visit https://www.brickedbrain.com if you need
 *	additional information or have any questions.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>

#include "../comedi_usb.h"

#define	NI6501_TIMEOUT	1000

/* Port request packets */
static const u8 READ_PORT_REQUEST[]	= {0x00, 0x01, 0x00, 0x10,
					   0x00, 0x0C, 0x01, 0x0E,
					   0x02, 0x10, 0x00, 0x00,
					   0x00, 0x03, 0x00, 0x00};

static const u8 WRITE_PORT_REQUEST[]	= {0x00, 0x01, 0x00, 0x14,
					   0x00, 0x10, 0x01, 0x0F,
					   0x02, 0x10, 0x00, 0x00,
					   0x00, 0x03, 0x00, 0x00,
					   0x03, 0x00, 0x00, 0x00};

static const u8 SET_PORT_DIR_REQUEST[]	= {0x00, 0x01, 0x00, 0x18,
					   0x00, 0x14, 0x01, 0x12,
					   0x02, 0x10, 0x00, 0x00,
					   0x00, 0x05, 0x00, 0x00,
					   0x00, 0x00, 0x05, 0x00,
					   0x00, 0x00, 0x00, 0x00};

/* Counter request packets */
static const u8 START_COUNTER_REQUEST[]	= {0x00, 0x01, 0x00, 0x0C,
					   0x00, 0x08, 0x01, 0x09,
					   0x02, 0x20, 0x00, 0x00};

static const u8 STOP_COUNTER_REQUEST[]	= {0x00, 0x01, 0x00, 0x0C,
					   0x00, 0x08, 0x01, 0x0C,
					   0x02, 0x20, 0x00, 0x00};

static const u8 READ_COUNTER_REQUEST[]	= {0x00, 0x01, 0x00, 0x0C,
					   0x00, 0x08, 0x01, 0x0E,
					   0x02, 0x20, 0x00, 0x00};

static const u8 WRITE_COUNTER_REQUEST[]	= {0x00, 0x01, 0x00, 0x10,
					   0x00, 0x0C, 0x01, 0x0F,
					   0x02, 0x20, 0x00, 0x00,
					   0x00, 0x00, 0x00, 0x00};

/* Response packets */
static const u8 GENERIC_RESPONSE[]	= {0x00, 0x01, 0x00, 0x0C,
					   0x00, 0x08, 0x01, 0x00,
					   0x00, 0x00, 0x00, 0x02};

static const u8 READ_PORT_RESPONSE[]	= {0x00, 0x01, 0x00, 0x10,
					   0x00, 0x0C, 0x01, 0x00,
					   0x00, 0x00, 0x00, 0x02,
					   0x00, 0x03, 0x00, 0x00};

static const u8 READ_COUNTER_RESPONSE[]	= {0x00, 0x01, 0x00, 0x10,
					   0x00, 0x0C, 0x01, 0x00,
					   0x00, 0x00, 0x00, 0x02,
					   0x00, 0x00, 0x00, 0x00};

/* Largest supported packets */
static const size_t TX_MAX_SIZE	= sizeof(SET_PORT_DIR_REQUEST);
static const size_t RX_MAX_SIZE	= sizeof(READ_PORT_RESPONSE);

enum commands {
	READ_PORT,
	WRITE_PORT,
	SET_PORT_DIR,
	START_COUNTER,
	STOP_COUNTER,
	READ_COUNTER,
	WRITE_COUNTER
};

struct ni6501_private {
	struct usb_endpoint_descriptor *ep_rx;
	struct usb_endpoint_descriptor *ep_tx;
	struct mutex mut;
	u8 *usb_rx_buf;
	u8 *usb_tx_buf;
};

static int ni6501_port_command(struct comedi_device *dev, int command,
			       unsigned int val, u8 *bitmap)
{
	struct usb_device *usb = comedi_to_usb_dev(dev);
	struct ni6501_private *devpriv = dev->private;
	int request_size, response_size;
	u8 *tx = devpriv->usb_tx_buf;
	int ret;

	if (command != SET_PORT_DIR && !bitmap)
		return -EINVAL;

	mutex_lock(&devpriv->mut);

	switch (command) {
	case READ_PORT:
		request_size = sizeof(READ_PORT_REQUEST);
		response_size = sizeof(READ_PORT_RESPONSE);
		memcpy(tx, READ_PORT_REQUEST, request_size);
		tx[14] = val & 0xff;
		break;
	case WRITE_PORT:
		request_size = sizeof(WRITE_PORT_REQUEST);
		response_size = sizeof(GENERIC_RESPONSE);
		memcpy(tx, WRITE_PORT_REQUEST, request_size);
		tx[14] = val & 0xff;
		tx[17] = *bitmap;
		break;
	case SET_PORT_DIR:
		request_size = sizeof(SET_PORT_DIR_REQUEST);
		response_size = sizeof(GENERIC_RESPONSE);
		memcpy(tx, SET_PORT_DIR_REQUEST, request_size);
		tx[14] = val & 0xff;
		tx[15] = (val >> 8) & 0xff;
		tx[16] = (val >> 16) & 0xff;
		break;
	default:
		ret = -EINVAL;
		goto end;
	}

	ret = usb_bulk_msg(usb,
			   usb_sndbulkpipe(usb,
					   devpriv->ep_tx->bEndpointAddress),
			   devpriv->usb_tx_buf,
			   request_size,
			   NULL,
			   NI6501_TIMEOUT);
	if (ret)
		goto end;

	ret = usb_bulk_msg(usb,
			   usb_rcvbulkpipe(usb,
					   devpriv->ep_rx->bEndpointAddress),
			   devpriv->usb_rx_buf,
			   response_size,
			   NULL,
			   NI6501_TIMEOUT);
	if (ret)
		goto end;

	/* Check if results are valid */

	if (command == READ_PORT) {
		*bitmap = devpriv->usb_rx_buf[14];
		/* mask bitmap for comparing */
		devpriv->usb_rx_buf[14] = 0x00;

		if (memcmp(devpriv->usb_rx_buf, READ_PORT_RESPONSE,
			   sizeof(READ_PORT_RESPONSE))) {
			ret = -EINVAL;
		}
	} else if (memcmp(devpriv->usb_rx_buf, GENERIC_RESPONSE,
			  sizeof(GENERIC_RESPONSE))) {
		ret = -EINVAL;
	}
end:
	mutex_unlock(&devpriv->mut);

	return ret;
}

static int ni6501_counter_command(struct comedi_device *dev, int command,
				  u32 *val)
{
	struct usb_device *usb = comedi_to_usb_dev(dev);
	struct ni6501_private *devpriv = dev->private;
	int request_size, response_size;
	u8 *tx = devpriv->usb_tx_buf;
	int ret;

	if ((command == READ_COUNTER || command ==  WRITE_COUNTER) && !val)
		return -EINVAL;

	mutex_lock(&devpriv->mut);

	switch (command) {
	case START_COUNTER:
		request_size = sizeof(START_COUNTER_REQUEST);
		response_size = sizeof(GENERIC_RESPONSE);
		memcpy(tx, START_COUNTER_REQUEST, request_size);
		break;
	case STOP_COUNTER:
		request_size = sizeof(STOP_COUNTER_REQUEST);
		response_size = sizeof(GENERIC_RESPONSE);
		memcpy(tx, STOP_COUNTER_REQUEST, request_size);
		break;
	case READ_COUNTER:
		request_size = sizeof(READ_COUNTER_REQUEST);
		response_size = sizeof(READ_COUNTER_RESPONSE);
		memcpy(tx, READ_COUNTER_REQUEST, request_size);
		break;
	case WRITE_COUNTER:
		request_size = sizeof(WRITE_COUNTER_REQUEST);
		response_size = sizeof(GENERIC_RESPONSE);
		memcpy(tx, WRITE_COUNTER_REQUEST, request_size);
		/* Setup tx packet: bytes 12,13,14,15 hold the */
		/* u32 counter value (Big Endian)	       */
		*((__be32 *)&tx[12]) = cpu_to_be32(*val);
		break;
	default:
		ret = -EINVAL;
		goto end;
	}

	ret = usb_bulk_msg(usb,
			   usb_sndbulkpipe(usb,
					   devpriv->ep_tx->bEndpointAddress),
			   devpriv->usb_tx_buf,
			   request_size,
			   NULL,
			   NI6501_TIMEOUT);
	if (ret)
		goto end;

	ret = usb_bulk_msg(usb,
			   usb_rcvbulkpipe(usb,
					   devpriv->ep_rx->bEndpointAddress),
			   devpriv->usb_rx_buf,
			   response_size,
			   NULL,
			   NI6501_TIMEOUT);
	if (ret)
		goto end;

	/* Check if results are valid */

	if (command == READ_COUNTER) {
		int i;

		/* Read counter value: bytes 12,13,14,15 of rx packet */
		/* hold the u32 counter value (Big Endian)	      */
		*val = be32_to_cpu(*((__be32 *)&devpriv->usb_rx_buf[12]));

		/* mask counter value for comparing */
		for (i = 12; i < sizeof(READ_COUNTER_RESPONSE); ++i)
			devpriv->usb_rx_buf[i] = 0x00;

		if (memcmp(devpriv->usb_rx_buf, READ_COUNTER_RESPONSE,
			   sizeof(READ_COUNTER_RESPONSE))) {
			ret = -EINVAL;
		}
	} else if (memcmp(devpriv->usb_rx_buf, GENERIC_RESPONSE,
			  sizeof(GENERIC_RESPONSE))) {
		ret = -EINVAL;
	}
end:
	mutex_unlock(&devpriv->mut);

	return ret;
}

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

	ret = comedi_dio_insn_config(dev, s, insn, data, 0);
	if (ret)
		return ret;

	ret = ni6501_port_command(dev, SET_PORT_DIR, s->io_bits, NULL);
	if (ret)
		return ret;

	return insn->n;
}

static int ni6501_dio_insn_bits(struct comedi_device *dev,
				struct comedi_subdevice *s,
				struct comedi_insn *insn,
				unsigned int *data)
{
	unsigned int mask;
	int ret;
	u8 port;
	u8 bitmap;

	mask = comedi_dio_update_state(s, data);

	for (port = 0; port < 3; port++) {
		if (mask & (0xFF << port * 8)) {
			bitmap = (s->state >> port * 8) & 0xFF;
			ret = ni6501_port_command(dev, WRITE_PORT,
						  port, &bitmap);
			if (ret)
				return ret;
		}
	}

	data[1] = 0;

	for (port = 0; port < 3; port++) {
		ret = ni6501_port_command(dev, READ_PORT, port, &bitmap);
		if (ret)
			return ret;
		data[1] |= bitmap << port * 8;
	}

	return insn->n;
}

static int ni6501_cnt_insn_config(struct comedi_device *dev,
				  struct comedi_subdevice *s,
				  struct comedi_insn *insn,
				  unsigned int *data)
{
	int ret;
	u32 val = 0;

	switch (data[0]) {
	case INSN_CONFIG_ARM:
		ret = ni6501_counter_command(dev, START_COUNTER, NULL);
		break;
	case INSN_CONFIG_DISARM:
		ret = ni6501_counter_command(dev, STOP_COUNTER, NULL);
		break;
	case INSN_CONFIG_RESET:
		ret = ni6501_counter_command(dev, STOP_COUNTER, NULL);
		if (ret)
			break;
		ret = ni6501_counter_command(dev, WRITE_COUNTER, &val);
		break;
	default:
		return -EINVAL;
	}

	return ret ? ret : insn->n;
}

static int ni6501_cnt_insn_read(struct comedi_device *dev,
				struct comedi_subdevice *s,
				struct comedi_insn *insn,
				unsigned int *data)
{
	int ret;
	u32 val;
	unsigned int i;

	for (i = 0; i < insn->n; i++) {
		ret = ni6501_counter_command(dev, READ_COUNTER,	&val);
		if (ret)
			return ret;
		data[i] = val;
	}

	return insn->n;
}

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

	if (insn->n) {
		u32 val = data[insn->n - 1];

		ret = ni6501_counter_command(dev, WRITE_COUNTER, &val);
		if (ret)
			return ret;
	}

	return insn->n;
}

static int ni6501_alloc_usb_buffers(struct comedi_device *dev)
{
	struct ni6501_private *devpriv = dev->private;
	size_t size;

	size = usb_endpoint_maxp(devpriv->ep_rx);
	devpriv->usb_rx_buf = kzalloc(size, GFP_KERNEL);
	if (!devpriv->usb_rx_buf)
		return -ENOMEM;

	size = usb_endpoint_maxp(devpriv->ep_tx);
	devpriv->usb_tx_buf = kzalloc(size, GFP_KERNEL);
	if (!devpriv->usb_tx_buf)
		return -ENOMEM;

	return 0;
}

static int ni6501_find_endpoints(struct comedi_device *dev)
{
	struct usb_interface *intf = comedi_to_usb_interface(dev);
	struct ni6501_private *devpriv = dev->private;
	struct usb_host_interface *iface_desc = intf->cur_altsetting;
	struct usb_endpoint_descriptor *ep_desc;
	int i;

	if (iface_desc->desc.bNumEndpoints != 2) {
		dev_err(dev->class_dev, "Wrong number of endpoints\n");
		return -ENODEV;
	}

	for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
		ep_desc = &iface_desc->endpoint[i].desc;

		if (usb_endpoint_is_bulk_in(ep_desc)) {
			if (!devpriv->ep_rx)
				devpriv->ep_rx = ep_desc;
			continue;
		}

		if (usb_endpoint_is_bulk_out(ep_desc)) {
			if (!devpriv->ep_tx)
				devpriv->ep_tx = ep_desc;
			continue;
		}
	}

	if (!devpriv->ep_rx || !devpriv->ep_tx)
		return -ENODEV;

	if (usb_endpoint_maxp(devpriv->ep_rx) < RX_MAX_SIZE)
		return -ENODEV;

	if (usb_endpoint_maxp(devpriv->ep_tx) < TX_MAX_SIZE)
		return -ENODEV;

	return 0;
}

static int ni6501_auto_attach(struct comedi_device *dev,
			      unsigned long context)
{
	struct usb_interface *intf = comedi_to_usb_interface(dev);
	struct ni6501_private *devpriv;
	struct comedi_subdevice *s;
	int ret;

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

	mutex_init(&devpriv->mut);
	usb_set_intfdata(intf, devpriv);

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

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

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

	/* Digital Input/Output subdevice */
	s = &dev->subdevices[0];
	s->type		= COMEDI_SUBD_DIO;
	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE;
	s->n_chan	= 24;
	s->maxdata	= 1;
	s->range_table	= &range_digital;
	s->insn_bits	= ni6501_dio_insn_bits;
	s->insn_config	= ni6501_dio_insn_config;

	/* Counter subdevice */
	s = &dev->subdevices[1];
	s->type		= COMEDI_SUBD_COUNTER;
	s->subdev_flags	= SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
	s->n_chan	= 1;
	s->maxdata	= 0xffffffff;
	s->insn_read	= ni6501_cnt_insn_read;
	s->insn_write	= ni6501_cnt_insn_write;
	s->insn_config	= ni6501_cnt_insn_config;

	return 0;
}

static void ni6501_detach(struct comedi_device *dev)
{
	struct usb_interface *intf = comedi_to_usb_interface(dev);
	struct ni6501_private *devpriv = dev->private;

	if (!devpriv)
		return;

	mutex_destroy(&devpriv->mut);

	usb_set_intfdata(intf, NULL);

	kfree(devpriv->usb_rx_buf);
	kfree(devpriv->usb_tx_buf);
}

static struct comedi_driver ni6501_driver = {
	.module		= THIS_MODULE,
	.driver_name	= "ni6501",
	.auto_attach	= ni6501_auto_attach,
	.detach		= ni6501_detach,
};

static int ni6501_usb_probe(struct usb_interface *intf,
			    const struct usb_device_id *id)
{
	return comedi_usb_auto_config(intf, &ni6501_driver, id->driver_info);
}

static const struct usb_device_id ni6501_usb_table[] = {
	{ USB_DEVICE(0x3923, 0x718a) },
	{ }
};
MODULE_DEVICE_TABLE(usb, ni6501_usb_table);

static struct usb_driver ni6501_usb_driver = {
	.name		= "ni6501",
	.id_table	= ni6501_usb_table,
	.probe		= ni6501_usb_probe,
	.disconnect	= comedi_usb_auto_unconfig,
};
module_comedi_usb_driver(ni6501_driver, ni6501_usb_driver);

MODULE_AUTHOR("Luca Ellero");
MODULE_DESCRIPTION("Comedi driver for National Instruments USB-6501");
MODULE_LICENSE("GPL");
