/*
    comedi/drivers/pcmda12.c
    Driver for Winsystems PC-104 based PCM-D/A-12 8-channel AO board.

    COMEDI - Linux Control and Measurement Device Interface
    Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>

    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.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
Driver: pcmda12
Description: A driver for the Winsystems PCM-D/A-12
Devices: [Winsystems] PCM-D/A-12 (pcmda12)
Author: Calin Culianu <calin@ajvar.org>
Updated: Fri, 13 Jan 2006 12:01:01 -0500
Status: works

A driver for the relatively straightforward-to-program PCM-D/A-12.
This board doesn't support commands, and the only way to set its
analog output range is to jumper the board.  As such,
comedi_data_write() ignores the range value specified.

The board uses 16 consecutive I/O addresses starting at the I/O port
base address.  Each address corresponds to the LSB then MSB of a
particular channel from 0-7.

Note that the board is not ISA-PNP capable and thus
needs the I/O port comedi_config parameter.

Note that passing a nonzero value as the second config option will
enable "simultaneous xfer" mode for this board, in which AO writes
will not take effect until a subsequent read of any AO channel.  This
is so that one can speed up programming by preloading all AO registers
with values before simultaneously setting them to take effect with one
read command.

Configuration Options:
  [0] - I/O port base address
  [1] - Do Simultaneous Xfer (see description)
*/

#include "../comedidev.h"

#define CHANS 8
#define IOSIZE 16
#define LSB(x) ((unsigned char)((x) & 0xff))
#define MSB(x) ((unsigned char)((((unsigned short)(x))>>8) & 0xff))
#define LSB_PORT(chan) (dev->iobase + (chan)*2)
#define MSB_PORT(chan) (LSB_PORT(chan)+1)
#define BITS 12

/* note these have no effect and are merely here for reference..
   these are configured by jumpering the board! */
static const struct comedi_lrange pcmda12_ranges = {
	3,
	{
	 UNI_RANGE(5), UNI_RANGE(10), BIP_RANGE(5)
	 }
};

struct pcmda12_private {

	unsigned int ao_readback[CHANS];
	int simultaneous_xfer_mode;
};

static void zero_chans(struct comedi_device *dev)
{				/* sets up an
				   ASIC chip to defaults */
	int i;
	for (i = 0; i < CHANS; ++i) {
/*      /\* do this as one instruction?? *\/ */
/*      outw(0, LSB_PORT(chan)); */
		outb(0, LSB_PORT(i));
		outb(0, MSB_PORT(i));
	}
	inb(LSB_PORT(0));	/* update chans. */
}

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

	/* Writing a list of values to an AO channel is probably not
	 * very useful, but that's how the interface is defined. */
	for (i = 0; i < insn->n; ++i) {

/*      /\* do this as one instruction?? *\/ */
/*      outw(data[i], LSB_PORT(chan)); */

		/* Need to do this as two instructions due to 8-bit bus?? */
		/*  first, load the low byte */
		outb(LSB(data[i]), LSB_PORT(chan));
		/*  next, write the high byte */
		outb(MSB(data[i]), MSB_PORT(chan));

		/* save shadow register */
		devpriv->ao_readback[chan] = data[i];

		if (!devpriv->simultaneous_xfer_mode)
			inb(LSB_PORT(chan));
	}

	/* return the number of samples written */
	return i;
}

/* AO subdevices should have a read insn as well as a write insn.

   Usually this means copying a value stored in devpriv->ao_readback.
   However, since this driver supports simultaneous xfer then sometimes
   this function actually accomplishes work.

   Simultaneaous xfer mode is accomplished by loading ALL the values
   you want for AO in all the channels, then READing off one of the AO
   registers to initiate the instantaneous simultaneous update of all
   DAC outputs, which makes all AO channels update simultaneously.
   This is useful for some control applications, I would imagine.
*/
static int ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
		    struct comedi_insn *insn, unsigned int *data)
{
	struct pcmda12_private *devpriv = dev->private;
	int i;
	int chan = CR_CHAN(insn->chanspec);

	for (i = 0; i < insn->n; i++) {
		if (devpriv->simultaneous_xfer_mode)
			inb(LSB_PORT(chan));
		/* read back shadow register */
		data[i] = devpriv->ao_readback[chan];
	}

	return i;
}

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

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

	devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
	if (!devpriv)
		return -ENOMEM;
	dev->private = devpriv;

	devpriv->simultaneous_xfer_mode = it->options[1];

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

	s = &dev->subdevices[0];
	s->private = NULL;
	s->maxdata = (0x1 << BITS) - 1;
	s->range_table = &pcmda12_ranges;
	s->type = COMEDI_SUBD_AO;
	s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
	s->n_chan = CHANS;
	s->insn_write = &ao_winsn;
	s->insn_read = &ao_rinsn;

	zero_chans(dev);	/* clear out all the registers, basically */

	return 1;
}

static struct comedi_driver pcmda12_driver = {
	.driver_name	= "pcmda12",
	.module		= THIS_MODULE,
	.attach		= pcmda12_attach,
	.detach		= comedi_legacy_detach,
};
module_comedi_driver(pcmda12_driver);

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