/*
 * serial2002.c
 * Comedi driver for serial connected hardware
 *
 * COMEDI - Linux Control and Measurement Device Interface
 * Copyright (C) 2002 Anders Blomdell <anders.blomdell@control.lth.se>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

/*
 * Driver: serial2002
 * Description: Driver for serial connected hardware
 * Devices:
 * Author: Anders Blomdell
 * Updated: Fri,  7 Jun 2002 12:56:45 -0700
 * Status: in development
 */

#include <linux/module.h>
#include "../comedidev.h"

#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/ktime.h>

#include <linux/termios.h>
#include <asm/ioctls.h>
#include <linux/serial.h>
#include <linux/poll.h>

struct serial2002_range_table_t {
	/*  HACK... */
	int length;
	struct comedi_krange range;
};

struct serial2002_private {
	int port;		/*  /dev/ttyS<port> */
	int speed;		/*  baudrate */
	struct file *tty;
	unsigned int ao_readback[32];
	unsigned char digital_in_mapping[32];
	unsigned char digital_out_mapping[32];
	unsigned char analog_in_mapping[32];
	unsigned char analog_out_mapping[32];
	unsigned char encoder_in_mapping[32];
	struct serial2002_range_table_t in_range[32], out_range[32];
};

struct serial_data {
	enum { is_invalid, is_digital, is_channel } kind;
	int index;
	unsigned long value;
};

/*
 * The configuration serial_data.value read from the device is
 * a bitmask that defines specific options of a channel:
 *
 * 4:0 - the channel to configure
 * 7:5 - the kind of channel
 * 9:8 - the command used to configure the channel
 *
 * The remaining bits vary in use depending on the command:
 *
 * BITS     15:10 - the channel bits (maxdata)
 * MIN/MAX  12:10 - the units multiplier for the scale
 *          13    - the sign of the scale
 *          33:14 - the base value for the range
 */
#define S2002_CFG_CHAN(x)		((x) & 0x1f)
#define S2002_CFG_KIND(x)		(((x) >> 5) & 0x7)
#define S2002_CFG_KIND_INVALID		0
#define S2002_CFG_KIND_DIGITAL_IN	1
#define S2002_CFG_KIND_DIGITAL_OUT	2
#define S2002_CFG_KIND_ANALOG_IN	3
#define S2002_CFG_KIND_ANALOG_OUT	4
#define S2002_CFG_KIND_ENCODER_IN	5
#define S2002_CFG_CMD(x)		(((x) >> 8) & 0x3)
#define S2002_CFG_CMD_BITS		0
#define S2002_CFG_CMD_MIN		1
#define S2002_CFG_CMD_MAX		2
#define S2002_CFG_BITS(x)		(((x) >> 10) & 0x3f)
#define S2002_CFG_UNITS(x)		(((x) >> 10) & 0x7)
#define S2002_CFG_SIGN(x)		(((x) >> 13) & 0x1)
#define S2002_CFG_BASE(x)		(((x) >> 14) & 0xfffff)

static long serial2002_tty_ioctl(struct file *f, unsigned int op,
				 unsigned long param)
{
	if (f->f_op->unlocked_ioctl)
		return f->f_op->unlocked_ioctl(f, op, param);

	return -ENOTTY;
}

static int serial2002_tty_write(struct file *f, unsigned char *buf, int count)
{
	loff_t pos = 0;
	return kernel_write(f, buf, count, &pos);
}

static void serial2002_tty_read_poll_wait(struct file *f, int timeout)
{
	struct poll_wqueues table;
	ktime_t start, now;

	start = ktime_get();
	poll_initwait(&table);
	while (1) {
		long elapsed;
		int mask;

		mask = f->f_op->poll(f, &table.pt);
		if (mask & (POLLRDNORM | POLLRDBAND | POLLIN |
			    POLLHUP | POLLERR)) {
			break;
		}
		now = ktime_get();
		elapsed = ktime_us_delta(now, start);
		if (elapsed > timeout)
			break;
		set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(((timeout - elapsed) * HZ) / 10000);
	}
	poll_freewait(&table);
}

static int serial2002_tty_read(struct file *f, int timeout)
{
	unsigned char ch;
	int result;
	loff_t pos = 0;

	result = -1;
	if (!IS_ERR(f)) {
		if (f->f_op->poll) {
			serial2002_tty_read_poll_wait(f, timeout);

			if (kernel_read(f, &ch, 1, &pos) == 1)
				result = ch;
		} else {
			/* Device does not support poll, busy wait */
			int retries = 0;

			while (1) {
				retries++;
				if (retries >= timeout)
					break;

				if (kernel_read(f, &ch, 1, &pos) == 1) {
					result = ch;
					break;
				}
				usleep_range(100, 1000);
			}
		}
	}
	return result;
}

static void serial2002_tty_setspeed(struct file *f, int speed)
{
	struct termios termios;
	struct serial_struct serial;
	mm_segment_t oldfs;

	oldfs = get_fs();
	set_fs(KERNEL_DS);

	/* Set speed */
	serial2002_tty_ioctl(f, TCGETS, (unsigned long)&termios);
	termios.c_iflag = 0;
	termios.c_oflag = 0;
	termios.c_lflag = 0;
	termios.c_cflag = CLOCAL | CS8 | CREAD;
	termios.c_cc[VMIN] = 0;
	termios.c_cc[VTIME] = 0;
	switch (speed) {
	case 2400:
		termios.c_cflag |= B2400;
		break;
	case 4800:
		termios.c_cflag |= B4800;
		break;
	case 9600:
		termios.c_cflag |= B9600;
		break;
	case 19200:
		termios.c_cflag |= B19200;
		break;
	case 38400:
		termios.c_cflag |= B38400;
		break;
	case 57600:
		termios.c_cflag |= B57600;
		break;
	case 115200:
		termios.c_cflag |= B115200;
		break;
	default:
		termios.c_cflag |= B9600;
		break;
	}
	serial2002_tty_ioctl(f, TCSETS, (unsigned long)&termios);

	/* Set low latency */
	serial2002_tty_ioctl(f, TIOCGSERIAL, (unsigned long)&serial);
	serial.flags |= ASYNC_LOW_LATENCY;
	serial2002_tty_ioctl(f, TIOCSSERIAL, (unsigned long)&serial);

	set_fs(oldfs);
}

static void serial2002_poll_digital(struct file *f, int channel)
{
	char cmd;

	cmd = 0x40 | (channel & 0x1f);
	serial2002_tty_write(f, &cmd, 1);
}

static void serial2002_poll_channel(struct file *f, int channel)
{
	char cmd;

	cmd = 0x60 | (channel & 0x1f);
	serial2002_tty_write(f, &cmd, 1);
}

static struct serial_data serial2002_read(struct file *f, int timeout)
{
	struct serial_data result;
	int length;

	result.kind = is_invalid;
	result.index = 0;
	result.value = 0;
	length = 0;
	while (1) {
		int data = serial2002_tty_read(f, timeout);

		length++;
		if (data < 0) {
			break;
		} else if (data & 0x80) {
			result.value = (result.value << 7) | (data & 0x7f);
		} else {
			if (length == 1) {
				switch ((data >> 5) & 0x03) {
				case 0:
					result.value = 0;
					result.kind = is_digital;
					break;
				case 1:
					result.value = 1;
					result.kind = is_digital;
					break;
				}
			} else {
				result.value =
				    (result.value << 2) | ((data & 0x60) >> 5);
				result.kind = is_channel;
			}
			result.index = data & 0x1f;
			break;
		}
	}
	return result;
}

static void serial2002_write(struct file *f, struct serial_data data)
{
	if (data.kind == is_digital) {
		unsigned char ch =
		    ((data.value << 5) & 0x20) | (data.index & 0x1f);
		serial2002_tty_write(f, &ch, 1);
	} else {
		unsigned char ch[6];
		int i = 0;

		if (data.value >= (1L << 30)) {
			ch[i] = 0x80 | ((data.value >> 30) & 0x03);
			i++;
		}
		if (data.value >= (1L << 23)) {
			ch[i] = 0x80 | ((data.value >> 23) & 0x7f);
			i++;
		}
		if (data.value >= (1L << 16)) {
			ch[i] = 0x80 | ((data.value >> 16) & 0x7f);
			i++;
		}
		if (data.value >= (1L << 9)) {
			ch[i] = 0x80 | ((data.value >> 9) & 0x7f);
			i++;
		}
		ch[i] = 0x80 | ((data.value >> 2) & 0x7f);
		i++;
		ch[i] = ((data.value << 5) & 0x60) | (data.index & 0x1f);
		i++;
		serial2002_tty_write(f, ch, i);
	}
}

struct config_t {
	short int kind;
	short int bits;
	int min;
	int max;
};

static int serial2002_setup_subdevice(struct comedi_subdevice *s,
				      struct config_t *cfg,
				      struct serial2002_range_table_t *range,
				      unsigned char *mapping,
				      int kind)
{
	const struct comedi_lrange **range_table_list = NULL;
	unsigned int *maxdata_list;
	int j, chan;

	for (chan = 0, j = 0; j < 32; j++) {
		if (cfg[j].kind == kind)
			chan++;
	}
	s->n_chan = chan;
	s->maxdata = 0;
	kfree(s->maxdata_list);
	maxdata_list = kmalloc_array(s->n_chan, sizeof(unsigned int),
				     GFP_KERNEL);
	if (!maxdata_list)
		return -ENOMEM;
	s->maxdata_list = maxdata_list;
	kfree(s->range_table_list);
	s->range_table = NULL;
	s->range_table_list = NULL;
	if (kind == 1 || kind == 2) {
		s->range_table = &range_digital;
	} else if (range) {
		range_table_list = kmalloc_array(s->n_chan, sizeof(*range),
						 GFP_KERNEL);
		if (!range_table_list)
			return -ENOMEM;
		s->range_table_list = range_table_list;
	}
	for (chan = 0, j = 0; j < 32; j++) {
		if (cfg[j].kind == kind) {
			if (mapping)
				mapping[chan] = j;
			if (range && range_table_list) {
				range[j].length = 1;
				range[j].range.min = cfg[j].min;
				range[j].range.max = cfg[j].max;
				range_table_list[chan] =
				    (const struct comedi_lrange *)&range[j];
			}
			if (cfg[j].bits < 32)
				maxdata_list[chan] = (1u << cfg[j].bits) - 1;
			else
				maxdata_list[chan] = 0xffffffff;
			chan++;
		}
	}
	return 0;
}

static int serial2002_setup_subdevs(struct comedi_device *dev)
{
	struct serial2002_private *devpriv = dev->private;
	struct config_t *di_cfg;
	struct config_t *do_cfg;
	struct config_t *ai_cfg;
	struct config_t *ao_cfg;
	struct config_t *cfg;
	struct comedi_subdevice *s;
	int result = 0;
	int i;

	/* Allocate the temporary structs to hold the configuration data */
	di_cfg = kcalloc(32, sizeof(*cfg), GFP_KERNEL);
	do_cfg = kcalloc(32, sizeof(*cfg), GFP_KERNEL);
	ai_cfg = kcalloc(32, sizeof(*cfg), GFP_KERNEL);
	ao_cfg = kcalloc(32, sizeof(*cfg), GFP_KERNEL);
	if (!di_cfg || !do_cfg || !ai_cfg || !ao_cfg) {
		result = -ENOMEM;
		goto err_alloc_configs;
	}

	/* Read the configuration from the connected device */
	serial2002_tty_setspeed(devpriv->tty, devpriv->speed);
	serial2002_poll_channel(devpriv->tty, 31);
	while (1) {
		struct serial_data data = serial2002_read(devpriv->tty, 1000);
		int kind = S2002_CFG_KIND(data.value);
		int channel = S2002_CFG_CHAN(data.value);
		int range = S2002_CFG_BASE(data.value);
		int cmd = S2002_CFG_CMD(data.value);

		if (data.kind != is_channel || data.index != 31 ||
		    kind == S2002_CFG_KIND_INVALID)
			break;

		switch (kind) {
		case S2002_CFG_KIND_DIGITAL_IN:
			cfg = di_cfg;
			break;
		case S2002_CFG_KIND_DIGITAL_OUT:
			cfg = do_cfg;
			break;
		case S2002_CFG_KIND_ANALOG_IN:
			cfg = ai_cfg;
			break;
		case S2002_CFG_KIND_ANALOG_OUT:
			cfg = ao_cfg;
			break;
		case S2002_CFG_KIND_ENCODER_IN:
			cfg = ai_cfg;
			break;
		default:
			cfg = NULL;
			break;
		}
		if (!cfg)
			continue;	/* unknown kind, skip it */

		cfg[channel].kind = kind;

		switch (cmd) {
		case S2002_CFG_CMD_BITS:
			cfg[channel].bits = S2002_CFG_BITS(data.value);
			break;
		case S2002_CFG_CMD_MIN:
		case S2002_CFG_CMD_MAX:
			switch (S2002_CFG_UNITS(data.value)) {
			case 0:
				range *= 1000000;
				break;
			case 1:
				range *= 1000;
				break;
			case 2:
				range *= 1;
				break;
			}
			if (S2002_CFG_SIGN(data.value))
				range = -range;
			if (cmd == S2002_CFG_CMD_MIN)
				cfg[channel].min = range;
			else
				cfg[channel].max = range;
			break;
		}
	}

	/* Fill in subdevice data */
	for (i = 0; i <= 4; i++) {
		unsigned char *mapping = NULL;
		struct serial2002_range_table_t *range = NULL;
		int kind = 0;

		s = &dev->subdevices[i];

		switch (i) {
		case 0:
			cfg = di_cfg;
			mapping = devpriv->digital_in_mapping;
			kind = S2002_CFG_KIND_DIGITAL_IN;
			break;
		case 1:
			cfg = do_cfg;
			mapping = devpriv->digital_out_mapping;
			kind = S2002_CFG_KIND_DIGITAL_OUT;
			break;
		case 2:
			cfg = ai_cfg;
			mapping = devpriv->analog_in_mapping;
			range = devpriv->in_range;
			kind = S2002_CFG_KIND_ANALOG_IN;
			break;
		case 3:
			cfg = ao_cfg;
			mapping = devpriv->analog_out_mapping;
			range = devpriv->out_range;
			kind = S2002_CFG_KIND_ANALOG_OUT;
			break;
		case 4:
			cfg = ai_cfg;
			mapping = devpriv->encoder_in_mapping;
			range = devpriv->in_range;
			kind = S2002_CFG_KIND_ENCODER_IN;
			break;
		}

		if (serial2002_setup_subdevice(s, cfg, range, mapping, kind))
			break;	/* err handled below */
	}
	if (i <= 4) {
		/*
		 * Failed to allocate maxdata_list or range_table_list
		 * for a subdevice that needed it.
		 */
		result = -ENOMEM;
		for (i = 0; i <= 4; i++) {
			s = &dev->subdevices[i];
			kfree(s->maxdata_list);
			s->maxdata_list = NULL;
			kfree(s->range_table_list);
			s->range_table_list = NULL;
		}
	}

err_alloc_configs:
	kfree(di_cfg);
	kfree(do_cfg);
	kfree(ai_cfg);
	kfree(ao_cfg);

	if (result) {
		if (devpriv->tty) {
			filp_close(devpriv->tty, NULL);
			devpriv->tty = NULL;
		}
	}

	return result;
}

static int serial2002_open(struct comedi_device *dev)
{
	struct serial2002_private *devpriv = dev->private;
	int result;
	char port[20];

	sprintf(port, "/dev/ttyS%d", devpriv->port);
	devpriv->tty = filp_open(port, O_RDWR, 0);
	if (IS_ERR(devpriv->tty)) {
		result = (int)PTR_ERR(devpriv->tty);
		dev_err(dev->class_dev, "file open error = %d\n", result);
	} else {
		result = serial2002_setup_subdevs(dev);
	}
	return result;
}

static void serial2002_close(struct comedi_device *dev)
{
	struct serial2002_private *devpriv = dev->private;

	if (!IS_ERR(devpriv->tty) && devpriv->tty)
		filp_close(devpriv->tty, NULL);
}

static int serial2002_di_insn_read(struct comedi_device *dev,
				   struct comedi_subdevice *s,
				   struct comedi_insn *insn,
				   unsigned int *data)
{
	struct serial2002_private *devpriv = dev->private;
	int n;
	int chan;

	chan = devpriv->digital_in_mapping[CR_CHAN(insn->chanspec)];
	for (n = 0; n < insn->n; n++) {
		struct serial_data read;

		serial2002_poll_digital(devpriv->tty, chan);
		while (1) {
			read = serial2002_read(devpriv->tty, 1000);
			if (read.kind != is_digital || read.index == chan)
				break;
		}
		data[n] = read.value;
	}
	return n;
}

static int serial2002_do_insn_write(struct comedi_device *dev,
				    struct comedi_subdevice *s,
				    struct comedi_insn *insn,
				    unsigned int *data)
{
	struct serial2002_private *devpriv = dev->private;
	int n;
	int chan;

	chan = devpriv->digital_out_mapping[CR_CHAN(insn->chanspec)];
	for (n = 0; n < insn->n; n++) {
		struct serial_data write;

		write.kind = is_digital;
		write.index = chan;
		write.value = data[n];
		serial2002_write(devpriv->tty, write);
	}
	return n;
}

static int serial2002_ai_insn_read(struct comedi_device *dev,
				   struct comedi_subdevice *s,
				   struct comedi_insn *insn,
				   unsigned int *data)
{
	struct serial2002_private *devpriv = dev->private;
	int n;
	int chan;

	chan = devpriv->analog_in_mapping[CR_CHAN(insn->chanspec)];
	for (n = 0; n < insn->n; n++) {
		struct serial_data read;

		serial2002_poll_channel(devpriv->tty, chan);
		while (1) {
			read = serial2002_read(devpriv->tty, 1000);
			if (read.kind != is_channel || read.index == chan)
				break;
		}
		data[n] = read.value;
	}
	return n;
}

static int serial2002_ao_insn_write(struct comedi_device *dev,
				    struct comedi_subdevice *s,
				    struct comedi_insn *insn,
				    unsigned int *data)
{
	struct serial2002_private *devpriv = dev->private;
	int n;
	int chan;

	chan = devpriv->analog_out_mapping[CR_CHAN(insn->chanspec)];
	for (n = 0; n < insn->n; n++) {
		struct serial_data write;

		write.kind = is_channel;
		write.index = chan;
		write.value = data[n];
		serial2002_write(devpriv->tty, write);
		devpriv->ao_readback[chan] = data[n];
	}
	return n;
}

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

	for (n = 0; n < insn->n; n++)
		data[n] = devpriv->ao_readback[chan];

	return n;
}

static int serial2002_encoder_insn_read(struct comedi_device *dev,
					struct comedi_subdevice *s,
					struct comedi_insn *insn,
					unsigned int *data)
{
	struct serial2002_private *devpriv = dev->private;
	int n;
	int chan;

	chan = devpriv->encoder_in_mapping[CR_CHAN(insn->chanspec)];
	for (n = 0; n < insn->n; n++) {
		struct serial_data read;

		serial2002_poll_channel(devpriv->tty, chan);
		while (1) {
			read = serial2002_read(devpriv->tty, 1000);
			if (read.kind != is_channel || read.index == chan)
				break;
		}
		data[n] = read.value;
	}
	return n;
}

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

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

	devpriv->port = it->options[0];
	devpriv->speed = it->options[1];

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

	/* digital input subdevice */
	s = &dev->subdevices[0];
	s->type		= COMEDI_SUBD_DI;
	s->subdev_flags	= SDF_READABLE;
	s->n_chan	= 0;
	s->maxdata	= 1;
	s->range_table	= &range_digital;
	s->insn_read	= serial2002_di_insn_read;

	/* digital output subdevice */
	s = &dev->subdevices[1];
	s->type		= COMEDI_SUBD_DO;
	s->subdev_flags	= SDF_WRITABLE;
	s->n_chan	= 0;
	s->maxdata	= 1;
	s->range_table	= &range_digital;
	s->insn_write	= serial2002_do_insn_write;

	/* analog input subdevice */
	s = &dev->subdevices[2];
	s->type		= COMEDI_SUBD_AI;
	s->subdev_flags	= SDF_READABLE | SDF_GROUND;
	s->n_chan	= 0;
	s->maxdata	= 1;
	s->range_table	= NULL;
	s->insn_read	= serial2002_ai_insn_read;

	/* analog output subdevice */
	s = &dev->subdevices[3];
	s->type		= COMEDI_SUBD_AO;
	s->subdev_flags	= SDF_WRITABLE;
	s->n_chan	= 0;
	s->maxdata	= 1;
	s->range_table	= NULL;
	s->insn_write	= serial2002_ao_insn_write;
	s->insn_read	= serial2002_ao_insn_read;

	/* encoder input subdevice */
	s = &dev->subdevices[4];
	s->type		= COMEDI_SUBD_COUNTER;
	s->subdev_flags	= SDF_READABLE | SDF_LSAMPL;
	s->n_chan	= 0;
	s->maxdata	= 1;
	s->range_table	= NULL;
	s->insn_read	= serial2002_encoder_insn_read;

	dev->open	= serial2002_open;
	dev->close	= serial2002_close;

	return 0;
}

static void serial2002_detach(struct comedi_device *dev)
{
	struct comedi_subdevice *s;
	int i;

	for (i = 0; i < dev->n_subdevices; i++) {
		s = &dev->subdevices[i];
		kfree(s->maxdata_list);
		kfree(s->range_table_list);
	}
}

static struct comedi_driver serial2002_driver = {
	.driver_name	= "serial2002",
	.module		= THIS_MODULE,
	.attach		= serial2002_attach,
	.detach		= serial2002_detach,
};
module_comedi_driver(serial2002_driver);

MODULE_AUTHOR("Comedi http://www.comedi.org");
MODULE_DESCRIPTION("Comedi low-level driver");
MODULE_LICENSE("GPL");
