/*
 * 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 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)
{
	const char __user *p = (__force const char __user *)buf;
	int result;
	loff_t offset = 0;
	mm_segment_t oldfs;

	oldfs = get_fs();
	set_fs(KERNEL_DS);
	result = __vfs_write(f, p, count, &offset);
	set_fs(oldfs);
	return result;
}

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;

	result = -1;
	if (!IS_ERR(f)) {
		mm_segment_t oldfs;
		char __user *p = (__force char __user *)&ch;
		loff_t offset = 0;

		oldfs = get_fs();
		set_fs(KERNEL_DS);
		if (f->f_op->poll) {
			serial2002_tty_read_poll_wait(f, timeout);

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

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

				if (__vfs_read(f, p, 1, &offset) == 1) {
					result = ch;
					break;
				}
				usleep_range(100, 1000);
			}
		}
		set_fs(oldfs);
	}
	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];
			}
			maxdata_list[chan] = ((long long)1 << cfg[j].bits) - 1;
			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");
