Commit c1cd5623 authored by H Hartley Sweeten's avatar H Hartley Sweeten Committed by Greg Kroah-Hartman

staging: comedi: pcl816: add support for digital subdevices

The PCL-816 boards have 16 digital inputs and 16 digtial outputs. Add the
subdevice support for these channels.

Allocate additional subdevice space to the analog outputs. This code is
not currently in the driver so mark the subdevice as COMEDI_SUBD_UNUSED.
Signed-off-by: default avatarH Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: default avatarIan Abbott <abbotti@mev.co.uk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent d4507f91
...@@ -44,6 +44,8 @@ Configuration Options: ...@@ -44,6 +44,8 @@ Configuration Options:
#include "comedi_fc.h" #include "comedi_fc.h"
#include "8253.h" #include "8253.h"
#define PCL816_DO_DI_LSB_REG 0x00
#define PCL816_DO_DI_MSB_REG 0x01
#define PCL816_TIMER_BASE 0x04 #define PCL816_TIMER_BASE 0x04
/* R: A/D high byte W: A/D range control */ /* R: A/D high byte W: A/D range control */
...@@ -556,9 +558,6 @@ static void pcl816_reset(struct comedi_device *dev) ...@@ -556,9 +558,6 @@ static void pcl816_reset(struct comedi_device *dev)
/* outb (0, dev->iobase + PCL818_DA_LO); DAC=0V */ /* outb (0, dev->iobase + PCL818_DA_LO); DAC=0V */
/* outb (0, dev->iobase + PCL818_DA_HI); */ /* outb (0, dev->iobase + PCL818_DA_HI); */
/* udelay (1); */
/* outb (0, dev->iobase + PCL818_DO_HI); DO=$0000 */
/* outb (0, dev->iobase + PCL818_DO_LO); */
/* udelay (1); */ /* udelay (1); */
outb(0, dev->iobase + PCL816_CONTROL); outb(0, dev->iobase + PCL816_CONTROL);
outb(0, dev->iobase + PCL816_MUX); outb(0, dev->iobase + PCL816_MUX);
...@@ -570,6 +569,10 @@ static void pcl816_reset(struct comedi_device *dev) ...@@ -570,6 +569,10 @@ static void pcl816_reset(struct comedi_device *dev)
i8254_set_mode(timer_base, 0, 0, I8254_MODE0 | I8254_BINARY); i8254_set_mode(timer_base, 0, 0, I8254_MODE0 | I8254_BINARY);
outb(0, dev->iobase + PCL816_RANGE); outb(0, dev->iobase + PCL816_RANGE);
/* set all digital outputs low */
outb(0, dev->iobase + PCL816_DO_DI_LSB_REG);
outb(0, dev->iobase + PCL816_DO_DI_MSB_REG);
} }
static int static int
...@@ -650,6 +653,32 @@ setup_channel_list(struct comedi_device *dev, ...@@ -650,6 +653,32 @@ setup_channel_list(struct comedi_device *dev,
dev->iobase + PCL816_MUX); dev->iobase + PCL816_MUX);
} }
static int pcl816_di_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
data[1] = inb(dev->iobase + PCL816_DO_DI_LSB_REG) |
(inb(dev->iobase + PCL816_DO_DI_MSB_REG) << 8);
return insn->n;
}
static int pcl816_do_insn_bits(struct comedi_device *dev,
struct comedi_subdevice *s,
struct comedi_insn *insn,
unsigned int *data)
{
if (comedi_dio_update_state(s, data)) {
outb(s->state & 0xff, dev->iobase + PCL816_DO_DI_LSB_REG);
outb((s->state >> 8), dev->iobase + PCL816_DO_DI_MSB_REG);
}
data[1] = s->state;
return insn->n;
}
static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{ {
const struct pcl816_board *board = comedi_board(dev); const struct pcl816_board *board = comedi_board(dev);
...@@ -700,7 +729,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -700,7 +729,7 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
} }
} }
ret = comedi_alloc_subdevices(dev, 1); ret = comedi_alloc_subdevices(dev, 4);
if (ret) if (ret)
return ret; return ret;
...@@ -721,29 +750,35 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it) ...@@ -721,29 +750,35 @@ static int pcl816_attach(struct comedi_device *dev, struct comedi_devconfig *it)
s->cancel = pcl816_ai_cancel; s->cancel = pcl816_ai_cancel;
} }
/* Analog OUtput subdevice */
s = &dev->subdevices[2];
s->type = COMEDI_SUBD_UNUSED;
#if 0 #if 0
subdevs[1] = COMEDI_SUBD_AO; subdevs[1] = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITABLE | SDF_GROUND; s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
s->n_chan = 1; s->n_chan = 1;
s->maxdata = board->ao_maxdata; s->maxdata = board->ao_maxdata;
s->range_table = &range_pcl816; s->range_table = &range_pcl816;
break;
subdevs[2] = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE;
s->n_chan = 16;
s->maxdata = 1;
s->range_table = &range_digital;
break;
subdevs[3] = COMEDI_SUBD_DO;
s->subdev_flags = SDF_WRITABLE;
s->n_chan = 16;
s->maxdata = 1;
s->range_table = &range_digital;
break;
#endif #endif
/* Digital Input subdevice */
s = &dev->subdevices[2];
s->type = COMEDI_SUBD_DI;
s->subdev_flags = SDF_READABLE;
s->n_chan = 16;
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = pcl816_di_insn_bits;
/* Digital Output subdevice */
s = &dev->subdevices[3];
s->type = COMEDI_SUBD_DO;
s->subdev_flags = SDF_WRITABLE;
s->n_chan = 16;
s->maxdata = 1;
s->range_table = &range_digital;
s->insn_bits = pcl816_do_insn_bits;
pcl816_reset(dev); pcl816_reset(dev);
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment