diff options
author | David Schleef <ds@schleef.org> | 2009-02-19 09:28:27 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-04-03 14:53:47 -0700 |
commit | 501d675db67e43cff47fa8138374679122baefb4 (patch) | |
tree | 504c1d8144d76393fc7460bfdba3b10551dcc93c | |
parent | 6baef150380d561a4d695a6be4fc509821c23611 (diff) |
Staging: comedi: add pcl725 driver
Driver for Advantech PCL-725 & compatibles
From: David Schleef <ds@schleef.org>
Cc: Ian Abbott <abbotti@mev.co.uk>
Cc: Frank Mori Hess <fmhess@users.sourceforge.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/staging/comedi/drivers/pcl725.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c new file mode 100644 index 00000000000..b4e37098a6c --- /dev/null +++ b/drivers/staging/comedi/drivers/pcl725.c @@ -0,0 +1,111 @@ +/* + * comedi/drivers/pcl725.c + * Driver for PCL725 and clones + * David A. Schleef + */ +/* +Driver: pcl725 +Description: Advantech PCL-725 (& compatibles) +Author: ds +Status: unknown +Devices: [Advantech] PCL-725 (pcl725) +*/ + +#include "../comedidev.h" + +#include <linux/ioport.h> + +#define PCL725_SIZE 2 + +#define PCL725_DO 0 +#define PCL725_DI 1 + +static int pcl725_attach(comedi_device * dev, comedi_devconfig * it); +static int pcl725_detach(comedi_device * dev); +static comedi_driver driver_pcl725 = { + driver_name:"pcl725", + module:THIS_MODULE, + attach:pcl725_attach, + detach:pcl725_detach, +}; + +COMEDI_INITCLEANUP(driver_pcl725); + +static int pcl725_do_insn(comedi_device * dev, comedi_subdevice * s, + comedi_insn * insn, lsampl_t * data) +{ + if (insn->n != 2) + return -EINVAL; + + if (data[0]) { + s->state &= ~data[0]; + s->state |= (data[0] & data[1]); + outb(s->state, dev->iobase + PCL725_DO); + } + + data[1] = s->state; + + return 2; +} + +static int pcl725_di_insn(comedi_device * dev, comedi_subdevice * s, + comedi_insn * insn, lsampl_t * data) +{ + if (insn->n != 2) + return -EINVAL; + + data[1] = inb(dev->iobase + PCL725_DI); + + return 2; +} + +static int pcl725_attach(comedi_device * dev, comedi_devconfig * it) +{ + comedi_subdevice *s; + unsigned long iobase; + + iobase = it->options[0]; + printk("comedi%d: pcl725: 0x%04lx ", dev->minor, iobase); + if (!request_region(iobase, PCL725_SIZE, "pcl725")) { + printk("I/O port conflict\n"); + return -EIO; + } + dev->board_name = "pcl725"; + dev->iobase = iobase; + dev->irq = 0; + + if (alloc_subdevices(dev, 2) < 0) + return -ENOMEM; + + s = dev->subdevices + 0; + /* do */ + s->type = COMEDI_SUBD_DO; + s->subdev_flags = SDF_WRITABLE; + s->maxdata = 1; + s->n_chan = 8; + s->insn_bits = pcl725_do_insn; + s->range_table = &range_digital; + + s = dev->subdevices + 1; + /* di */ + s->type = COMEDI_SUBD_DI; + s->subdev_flags = SDF_READABLE; + s->maxdata = 1; + s->n_chan = 8; + s->insn_bits = pcl725_di_insn; + s->range_table = &range_digital; + + printk("\n"); + + return 0; +} + +static int pcl725_detach(comedi_device * dev) +{ + printk("comedi%d: pcl725: remove\n", dev->minor); + + if (dev->iobase) + release_region(dev->iobase, PCL725_SIZE); + + return 0; +} |