/*
 * comedi/drivers/dt2801.c
 * Device Driver for DataTranslation DT2801
 *
 */
/*
Driver: dt2801
Description: Data Translation DT2801 series and DT01-EZ
Author: ds
Status: works
Devices: [Data Translation] DT2801 (dt2801), DT2801-A, DT2801/5716A,
  DT2805, DT2805/5716A, DT2808, DT2818, DT2809, DT01-EZ

This driver can autoprobe the type of board.

Configuration options:
  [0] - I/O port base address
  [1] - unused
  [2] - A/D reference 0=differential, 1=single-ended
  [3] - A/D range
	  0 = [-10, 10]
	  1 = [0,10]
  [4] - D/A 0 range
	  0 = [-10, 10]
	  1 = [-5,5]
	  2 = [-2.5,2.5]
	  3 = [0,10]
	  4 = [0,5]
  [5] - D/A 1 range (same choices)
*/

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

#define DT2801_TIMEOUT 1000

/* Hardware Configuration */
/* ====================== */

#define DT2801_MAX_DMA_SIZE (64 * 1024)

/* Ports */
#define DT2801_IOSIZE 2

/* define's */
/* ====================== */

/* Commands */
#define DT_C_RESET       0x0
#define DT_C_CLEAR_ERR   0x1
#define DT_C_READ_ERRREG 0x2
#define DT_C_SET_CLOCK   0x3

#define DT_C_TEST        0xb
#define DT_C_STOP        0xf

#define DT_C_SET_DIGIN   0x4
#define DT_C_SET_DIGOUT  0x5
#define DT_C_READ_DIG    0x6
#define DT_C_WRITE_DIG   0x7

#define DT_C_WRITE_DAIM  0x8
#define DT_C_SET_DA      0x9
#define DT_C_WRITE_DA    0xa

#define DT_C_READ_ADIM   0xc
#define DT_C_SET_AD      0xd
#define DT_C_READ_AD     0xe

/* Command modifiers (only used with read/write), EXTTRIG can be
   used with some other commands.
*/
#define DT_MOD_DMA     (1<<4)
#define DT_MOD_CONT    (1<<5)
#define DT_MOD_EXTCLK  (1<<6)
#define DT_MOD_EXTTRIG (1<<7)

/* Bits in status register */
#define DT_S_DATA_OUT_READY   (1<<0)
#define DT_S_DATA_IN_FULL     (1<<1)
#define DT_S_READY            (1<<2)
#define DT_S_COMMAND          (1<<3)
#define DT_S_COMPOSITE_ERROR  (1<<7)

/* registers */
#define DT2801_DATA		0
#define DT2801_STATUS		1
#define DT2801_CMD		1

#if 0
/* ignore 'defined but not used' warning */
static const struct comedi_lrange range_dt2801_ai_pgh_bipolar = {
	4, {
		BIP_RANGE(10),
		BIP_RANGE(5),
		BIP_RANGE(2.5),
		BIP_RANGE(1.25)
	}
};
#endif
static const struct comedi_lrange range_dt2801_ai_pgl_bipolar = {
	4, {
		BIP_RANGE(10),
		BIP_RANGE(1),
		BIP_RANGE(0.1),
		BIP_RANGE(0.02)
	}
};

#if 0
/* ignore 'defined but not used' warning */
static const struct comedi_lrange range_dt2801_ai_pgh_unipolar = {
	4, {
		UNI_RANGE(10),
		UNI_RANGE(5),
		UNI_RANGE(2.5),
		UNI_RANGE(1.25)
	}
};
#endif
static const struct comedi_lrange range_dt2801_ai_pgl_unipolar = {
	4, {
		UNI_RANGE(10),
		UNI_RANGE(1),
		UNI_RANGE(0.1),
		UNI_RANGE(0.02)
	}
};

struct dt2801_board {

	const char *name;
	int boardcode;
	int ad_diff;
	int ad_chan;
	int adbits;
	int adrangetype;
	int dabits;
};

/* Typeid's for the different boards of the DT2801-series
   (taken from the test-software, that comes with the board)
   */
static const struct dt2801_board boardtypes[] = {
	{
	 .name = "dt2801",
	 .boardcode = 0x09,
	 .ad_diff = 2,
	 .ad_chan = 16,
	 .adbits = 12,
	 .adrangetype = 0,
	 .dabits = 12},
	{
	 .name = "dt2801-a",
	 .boardcode = 0x52,
	 .ad_diff = 2,
	 .ad_chan = 16,
	 .adbits = 12,
	 .adrangetype = 0,
	 .dabits = 12},
	{
	 .name = "dt2801/5716a",
	 .boardcode = 0x82,
	 .ad_diff = 1,
	 .ad_chan = 16,
	 .adbits = 16,
	 .adrangetype = 1,
	 .dabits = 12},
	{
	 .name = "dt2805",
	 .boardcode = 0x12,
	 .ad_diff = 1,
	 .ad_chan = 16,
	 .adbits = 12,
	 .adrangetype = 0,
	 .dabits = 12},
	{
	 .name = "dt2805/5716a",
	 .boardcode = 0x92,
	 .ad_diff = 1,
	 .ad_chan = 16,
	 .adbits = 16,
	 .adrangetype = 1,
	 .dabits = 12},
	{
	 .name = "dt2808",
	 .boardcode = 0x20,
	 .ad_diff = 0,
	 .ad_chan = 16,
	 .adbits = 12,
	 .adrangetype = 2,
	 .dabits = 8},
	{
	 .name = "dt2818",
	 .boardcode = 0xa2,
	 .ad_diff = 0,
	 .ad_chan = 4,
	 .adbits = 12,
	 .adrangetype = 0,
	 .dabits = 12},
	{
	 .name = "dt2809",
	 .boardcode = 0xb0,
	 .ad_diff = 0,
	 .ad_chan = 8,
	 .adbits = 12,
	 .adrangetype = 1,
	 .dabits = 12},
};

struct dt2801_private {

	const struct comedi_lrange *dac_range_types[2];
	unsigned int ao_readback[2];
};

/* These are the low-level routines:
   writecommand: write a command to the board
   writedata: write data byte
   readdata: read data byte
 */

/* Only checks DataOutReady-flag, not the Ready-flag as it is done
   in the examples of the manual. I don't see why this should be
   necessary. */
static int dt2801_readdata(struct comedi_device *dev, int *data)
{
	int stat = 0;
	int timeout = DT2801_TIMEOUT;

	do {
		stat = inb_p(dev->iobase + DT2801_STATUS);
		if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY))
			return stat;
		if (stat & DT_S_DATA_OUT_READY) {
			*data = inb_p(dev->iobase + DT2801_DATA);
			return 0;
		}
	} while (--timeout > 0);

	return -ETIME;
}

static int dt2801_readdata2(struct comedi_device *dev, int *data)
{
	int lb = 0;
	int hb = 0;
	int ret;

	ret = dt2801_readdata(dev, &lb);
	if (ret)
		return ret;
	ret = dt2801_readdata(dev, &hb);
	if (ret)
		return ret;

	*data = (hb << 8) + lb;
	return 0;
}

static int dt2801_writedata(struct comedi_device *dev, unsigned int data)
{
	int stat = 0;
	int timeout = DT2801_TIMEOUT;

	do {
		stat = inb_p(dev->iobase + DT2801_STATUS);

		if (stat & DT_S_COMPOSITE_ERROR)
			return stat;
		if (!(stat & DT_S_DATA_IN_FULL)) {
			outb_p(data & 0xff, dev->iobase + DT2801_DATA);
			return 0;
		}
	} while (--timeout > 0);

	return -ETIME;
}

static int dt2801_writedata2(struct comedi_device *dev, unsigned int data)
{
	int ret;

	ret = dt2801_writedata(dev, data & 0xff);
	if (ret < 0)
		return ret;
	ret = dt2801_writedata(dev, (data >> 8));
	if (ret < 0)
		return ret;

	return 0;
}

static int dt2801_wait_for_ready(struct comedi_device *dev)
{
	int timeout = DT2801_TIMEOUT;
	int stat;

	stat = inb_p(dev->iobase + DT2801_STATUS);
	if (stat & DT_S_READY)
		return 0;
	do {
		stat = inb_p(dev->iobase + DT2801_STATUS);

		if (stat & DT_S_COMPOSITE_ERROR)
			return stat;
		if (stat & DT_S_READY)
			return 0;
	} while (--timeout > 0);

	return -ETIME;
}

static int dt2801_writecmd(struct comedi_device *dev, int command)
{
	int stat;

	dt2801_wait_for_ready(dev);

	stat = inb_p(dev->iobase + DT2801_STATUS);
	if (stat & DT_S_COMPOSITE_ERROR) {
		dev_dbg(dev->class_dev,
			"composite-error in %s, ignoring\n", __func__);
	}
	if (!(stat & DT_S_READY))
		dev_dbg(dev->class_dev, "!ready in %s, ignoring\n", __func__);
	outb_p(command, dev->iobase + DT2801_CMD);

	return 0;
}

static int dt2801_reset(struct comedi_device *dev)
{
	int board_code = 0;
	unsigned int stat;
	int timeout;

	/* pull random data from data port */
	inb_p(dev->iobase + DT2801_DATA);
	inb_p(dev->iobase + DT2801_DATA);
	inb_p(dev->iobase + DT2801_DATA);
	inb_p(dev->iobase + DT2801_DATA);

	/* dt2801_writecmd(dev,DT_C_STOP); */
	outb_p(DT_C_STOP, dev->iobase + DT2801_CMD);

	/* dt2801_wait_for_ready(dev); */
	udelay(100);
	timeout = 10000;
	do {
		stat = inb_p(dev->iobase + DT2801_STATUS);
		if (stat & DT_S_READY)
			break;
	} while (timeout--);
	if (!timeout)
		dev_dbg(dev->class_dev, "timeout 1 status=0x%02x\n", stat);

	/* dt2801_readdata(dev,&board_code); */

	outb_p(DT_C_RESET, dev->iobase + DT2801_CMD);
	/* dt2801_writecmd(dev,DT_C_RESET); */

	udelay(100);
	timeout = 10000;
	do {
		stat = inb_p(dev->iobase + DT2801_STATUS);
		if (stat & DT_S_READY)
			break;
	} while (timeout--);
	if (!timeout)
		dev_dbg(dev->class_dev, "timeout 2 status=0x%02x\n", stat);

	dt2801_readdata(dev, &board_code);

	return board_code;
}

static int probe_number_of_ai_chans(struct comedi_device *dev)
{
	int n_chans;
	int stat;
	int data;

	for (n_chans = 0; n_chans < 16; n_chans++) {
		stat = dt2801_writecmd(dev, DT_C_READ_ADIM);
		dt2801_writedata(dev, 0);
		dt2801_writedata(dev, n_chans);
		stat = dt2801_readdata2(dev, &data);

		if (stat)
			break;
	}

	dt2801_reset(dev);
	dt2801_reset(dev);

	return n_chans;
}

static const struct comedi_lrange *dac_range_table[] = {
	&range_bipolar10,
	&range_bipolar5,
	&range_bipolar2_5,
	&range_unipolar10,
	&range_unipolar5
};

static const struct comedi_lrange *dac_range_lkup(int opt)
{
	if (opt < 0 || opt >= 5)
		return &range_unknown;
	return dac_range_table[opt];
}

static const struct comedi_lrange *ai_range_lkup(int type, int opt)
{
	switch (type) {
	case 0:
		return (opt) ?
		    &range_dt2801_ai_pgl_unipolar :
		    &range_dt2801_ai_pgl_bipolar;
	case 1:
		return (opt) ? &range_unipolar10 : &range_bipolar10;
	case 2:
		return &range_unipolar5;
	}
	return &range_unknown;
}

static int dt2801_error(struct comedi_device *dev, int stat)
{
	if (stat < 0) {
		if (stat == -ETIME)
			dev_dbg(dev->class_dev, "timeout\n");
		else
			dev_dbg(dev->class_dev, "error %d\n", stat);
		return stat;
	}
	dev_dbg(dev->class_dev, "error status 0x%02x, resetting...\n", stat);

	dt2801_reset(dev);
	dt2801_reset(dev);

	return -EIO;
}

static int dt2801_ai_insn_read(struct comedi_device *dev,
			       struct comedi_subdevice *s,
			       struct comedi_insn *insn, unsigned int *data)
{
	int d;
	int stat;
	int i;

	for (i = 0; i < insn->n; i++) {
		stat = dt2801_writecmd(dev, DT_C_READ_ADIM);
		dt2801_writedata(dev, CR_RANGE(insn->chanspec));
		dt2801_writedata(dev, CR_CHAN(insn->chanspec));
		stat = dt2801_readdata2(dev, &d);

		if (stat != 0)
			return dt2801_error(dev, stat);

		data[i] = d;
	}

	return i;
}

static int dt2801_ao_insn_read(struct comedi_device *dev,
			       struct comedi_subdevice *s,
			       struct comedi_insn *insn, unsigned int *data)
{
	struct dt2801_private *devpriv = dev->private;

	data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];

	return 1;
}

static int dt2801_ao_insn_write(struct comedi_device *dev,
				struct comedi_subdevice *s,
				struct comedi_insn *insn, unsigned int *data)
{
	struct dt2801_private *devpriv = dev->private;

	dt2801_writecmd(dev, DT_C_WRITE_DAIM);
	dt2801_writedata(dev, CR_CHAN(insn->chanspec));
	dt2801_writedata2(dev, data[0]);

	devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[0];

	return 1;
}

static int dt2801_dio_insn_bits(struct comedi_device *dev,
				struct comedi_subdevice *s,
				struct comedi_insn *insn,
				unsigned int *data)
{
	int which = (s == &dev->subdevices[3]) ? 1 : 0;
	unsigned int val = 0;

	if (comedi_dio_update_state(s, data)) {
		dt2801_writecmd(dev, DT_C_WRITE_DIG);
		dt2801_writedata(dev, which);
		dt2801_writedata(dev, s->state);
	}

	dt2801_writecmd(dev, DT_C_READ_DIG);
	dt2801_writedata(dev, which);
	dt2801_readdata(dev, &val);

	data[1] = val;

	return insn->n;
}

static int dt2801_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, 0xff);
	if (ret)
		return ret;

	dt2801_writecmd(dev, s->io_bits ? DT_C_SET_DIGOUT : DT_C_SET_DIGIN);
	dt2801_writedata(dev, (s == &dev->subdevices[3]) ? 1 : 0);

	return insn->n;
}

/*
   options:
	[0] - i/o base
	[1] - unused
	[2] - a/d 0=differential, 1=single-ended
	[3] - a/d range 0=[-10,10], 1=[0,10]
	[4] - dac0 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
	[5] - dac1 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
*/
static int dt2801_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
	const struct dt2801_board *board = comedi_board(dev);
	struct dt2801_private *devpriv;
	struct comedi_subdevice *s;
	int board_code, type;
	int ret = 0;
	int n_ai_chans;

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

	/* do some checking */

	board_code = dt2801_reset(dev);

	/* heh.  if it didn't work, try it again. */
	if (!board_code)
		board_code = dt2801_reset(dev);

	for (type = 0; type < ARRAY_SIZE(boardtypes); type++) {
		if (boardtypes[type].boardcode == board_code)
			goto havetype;
	}
	dev_dbg(dev->class_dev,
		"unrecognized board code=0x%02x, contact author\n", board_code);
	type = 0;

havetype:
	dev->board_ptr = boardtypes + type;
	board = comedi_board(dev);

	n_ai_chans = probe_number_of_ai_chans(dev);

	ret = comedi_alloc_subdevices(dev, 4);
	if (ret)
		goto out;

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

	dev->board_name = board->name;

	s = &dev->subdevices[0];
	/* ai subdevice */
	s->type = COMEDI_SUBD_AI;
	s->subdev_flags = SDF_READABLE | SDF_GROUND;
#if 1
	s->n_chan = n_ai_chans;
#else
	if (it->options[2])
		s->n_chan = board->ad_chan;
	else
		s->n_chan = board->ad_chan / 2;
#endif
	s->maxdata = (1 << board->adbits) - 1;
	s->range_table = ai_range_lkup(board->adrangetype, it->options[3]);
	s->insn_read = dt2801_ai_insn_read;

	s = &dev->subdevices[1];
	/* ao subdevice */
	s->type = COMEDI_SUBD_AO;
	s->subdev_flags = SDF_WRITABLE;
	s->n_chan = 2;
	s->maxdata = (1 << board->dabits) - 1;
	s->range_table_list = devpriv->dac_range_types;
	devpriv->dac_range_types[0] = dac_range_lkup(it->options[4]);
	devpriv->dac_range_types[1] = dac_range_lkup(it->options[5]);
	s->insn_read = dt2801_ao_insn_read;
	s->insn_write = dt2801_ao_insn_write;

	s = &dev->subdevices[2];
	/* 1st digital subdevice */
	s->type = COMEDI_SUBD_DIO;
	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
	s->n_chan = 8;
	s->maxdata = 1;
	s->range_table = &range_digital;
	s->insn_bits = dt2801_dio_insn_bits;
	s->insn_config = dt2801_dio_insn_config;

	s = &dev->subdevices[3];
	/* 2nd digital subdevice */
	s->type = COMEDI_SUBD_DIO;
	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
	s->n_chan = 8;
	s->maxdata = 1;
	s->range_table = &range_digital;
	s->insn_bits = dt2801_dio_insn_bits;
	s->insn_config = dt2801_dio_insn_config;

	ret = 0;
out:
	return ret;
}

static struct comedi_driver dt2801_driver = {
	.driver_name	= "dt2801",
	.module		= THIS_MODULE,
	.attach		= dt2801_attach,
	.detach		= comedi_legacy_detach,
};
module_comedi_driver(dt2801_driver);

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