#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/comedi/comedidev.h>
#include <linux/comedi/comedi_8254.h>
#define N_CHAN_AI …
#define DAS800_LSB …
#define FIFO_EMPTY …
#define FIFO_OVF …
#define DAS800_MSB …
#define DAS800_CONTROL1 …
#define CONTROL1_INTE …
#define DAS800_CONV_CONTROL …
#define ITE …
#define CASC …
#define DTEN …
#define IEOC …
#define EACS …
#define CONV_HCEN …
#define DAS800_SCAN_LIMITS …
#define DAS800_STATUS …
#define IRQ …
#define BUSY …
#define DAS800_GAIN …
#define CIO_FFOV …
#define CIO_ENHF …
#define CONTROL1 …
#define CONV_CONTROL …
#define SCAN_LIMITS …
#define ID …
#define DAS800_8254 …
#define DAS800_STATUS2 …
#define STATUS2_HCEN …
#define STATUS2_INTE …
#define DAS800_ID …
#define DAS802_16_HALF_FIFO_SZ …
struct das800_board { … };
static const struct comedi_lrange range_das801_ai = …;
static const struct comedi_lrange range_cio_das801_ai = …;
static const struct comedi_lrange range_das802_ai = …;
static const struct comedi_lrange range_das80216_ai = …;
enum das800_boardinfo { … };
static const struct das800_board das800_boards[] = …;
struct das800_private { … };
static void das800_ind_write(struct comedi_device *dev,
unsigned int val, unsigned int reg)
{ … }
static unsigned int das800_ind_read(struct comedi_device *dev, unsigned int reg)
{ … }
static void das800_enable(struct comedi_device *dev)
{ … }
static void das800_disable(struct comedi_device *dev)
{ … }
static int das800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{ … }
static int das800_ai_check_chanlist(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{ … }
static int das800_ai_do_cmdtest(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_cmd *cmd)
{ … }
static int das800_ai_do_cmd(struct comedi_device *dev,
struct comedi_subdevice *s)
{ … }
static unsigned int das800_ai_get_sample(struct comedi_device *dev)
{ … }
static irqreturn_t das800_interrupt(int irq, void *d)
{ … }
static int das800_ai_eoc(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned long context)
{ … }
static int das800_ai_insn_read(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{ … }
static int das800_di_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{ … }
static int das800_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{ … }
static const struct das800_board *das800_probe(struct comedi_device *dev)
{ … }
static int das800_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
const struct das800_board *board;
struct das800_private *devpriv;
struct comedi_subdevice *s;
unsigned int irq = it->options[1];
unsigned long irq_flags;
int ret;
devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
if (!devpriv)
return -ENOMEM;
ret = comedi_request_region(dev, it->options[0], 0x8);
if (ret)
return ret;
board = das800_probe(dev);
if (!board)
return -ENODEV;
dev->board_ptr = board;
dev->board_name = board->name;
if (irq > 1 && irq <= 7) {
ret = request_irq(irq, das800_interrupt, 0, "das800",
dev);
if (ret == 0)
dev->irq = irq;
}
dev->pacer = comedi_8254_io_alloc(dev->iobase + DAS800_8254,
I8254_OSC_BASE_1MHZ, I8254_IO8, 0);
if (IS_ERR(dev->pacer))
return PTR_ERR(dev->pacer);
ret = comedi_alloc_subdevices(dev, 3);
if (ret)
return ret;
s = &dev->subdevices[0];
dev->read_subdev = s;
s->type = COMEDI_SUBD_AI;
s->subdev_flags = SDF_READABLE | SDF_GROUND;
s->n_chan = 8;
s->maxdata = (1 << board->resolution) - 1;
s->range_table = board->ai_range;
s->insn_read = das800_ai_insn_read;
if (dev->irq) {
s->subdev_flags |= SDF_CMD_READ;
s->len_chanlist = 8;
s->do_cmdtest = das800_ai_do_cmdtest;
s->do_cmd = das800_ai_do_cmd;
s->cancel = das800_cancel;
}
s = &dev->subdevices[1];
s->type = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE;
s->n_chan = 3;
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = das800_di_insn_bits;
s = &dev->subdevices[2];
s->type = COMEDI_SUBD_DO;
s->subdev_flags = SDF_WRITABLE;
s->n_chan = 4;
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = das800_do_insn_bits;
das800_disable(dev);
spin_lock_irqsave(&dev->spinlock, irq_flags);
das800_ind_write(dev, CONTROL1_INTE | devpriv->do_bits, CONTROL1);
spin_unlock_irqrestore(&dev->spinlock, irq_flags);
return 0;
};
static struct comedi_driver driver_das800 = …;
module_comedi_driver(…);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;