/*
comedi/drivers/poc.c
Mini-drivers for POC (Piece of Crap) boards
- Copyright (C) 2000 Frank Mori Hess <fmhess@uiuc.edu>
+ Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
Copyright (C) 2001 David A. Schleef <ds@schleef.org>
This program is free software; you can redistribute it and/or modify
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
- * This driver is a kind of miscellaneous driver for very
- * simple ISA boards.
- */
-/*
- dac02 - Keithley DAC-02 analog output board driver
-
-The card's ranges are set by the wiring you use. The driver only
-uses the range specified to decide whether or not to take the
-complement of the data before sending it to the card (since the
-bipolar outputs of the card are inverted.)
-
+Driver: poc.o
+Description: Generic driver for very simple devices
+Author: ds
+Devices: [Keithley Metrabyte] DAC-02 (dac02), [Advantech] PCL-733 (pcl733),
+ PCL-734 (pcl734)
+Updated: Sat, 16 Mar 2002 17:34:48 -0800
+Status: unknown
+
+This driver is indended to support very simple ISA-based devices,
+including:
+ dac02 - Keithley DAC-02 analog output board
+ pcl733 - Advantech PCL-733
+ pcl734 - Advantech PCL-734
+
+Configuration options:
+ [0] - I/O port base
*/
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/malloc.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/timex.h>
-#include <linux/timer.h>
-#include <asm/io.h>
#include <linux/comedidev.h>
-/* DAC-02 registers */
-#define DAC02_LSB(a) (2 * a)
-#define DAC02_MSB(a) (2 * a + 1)
+#include <linux/ioport.h>
static int poc_attach(comedi_device *dev,comedi_devconfig *it);
static int poc_detach(comedi_device *dev);
-static int dac02_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
static int readback_insn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int dac02_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data);
+static int pcl733_insn_bits(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data);
+static int pcl734_insn_bits(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data);
+
struct boarddef_struct{
- char *name;
- int iosize;
+ const char *name;
+ unsigned int iosize;
int (*setup)(comedi_device *);
int type;
int n_chan;
int n_bits;
int (*winsn)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *);
int (*rinsn)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *);
- comedi_lrange* range;
+ int (*insnbits)(comedi_device *,comedi_subdevice *,comedi_insn *,lsampl_t *);
+ const comedi_lrange *range;
};
-static struct boarddef_struct boards[]={
+static const struct boarddef_struct boards[]={
{
name: "dac02",
iosize: 8,
winsn: dac02_ao_winsn,
rinsn: readback_insn,
range: &range_unknown,
- }
+ },
+ {
+ name: "pcl733",
+ iosize: 4,
+ type: COMEDI_SUBD_DI,
+ n_chan: 32,
+ n_bits: 1,
+ insnbits: pcl733_insn_bits,
+ range: &range_digital,
+ },
+ {
+ name: "pcl734",
+ iosize: 4,
+ type: COMEDI_SUBD_DO,
+ n_chan: 32,
+ n_bits: 1,
+ insnbits: pcl734_insn_bits,
+ range: &range_digital,
+ },
};
#define n_boards (sizeof(boards)/sizeof(boards[0]))
-#define this_board ((struct boarddef_struct *)dev->board_ptr)
+#define this_board ((const struct boarddef_struct *)dev->board_ptr)
-comedi_driver driver_poc=
+static comedi_driver driver_poc=
{
driver_name: "poc",
module: THIS_MODULE,
attach: poc_attach,
detach: poc_detach,
- board_name: boards,
+ board_name: &boards[0].name,
num_names: n_boards,
offset: sizeof(boards[0]),
};
static int poc_attach(comedi_device *dev, comedi_devconfig *it)
{
comedi_subdevice *s;
- int iosize, iobase;
+ unsigned long iobase;
+ unsigned int iosize;
iobase = it->options[0];
- printk("comedi%d: poc: using %s iobase 0x%x\n", dev->minor,
+ printk("comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
this_board->name, iobase);
dev->board_name = this_board->name;
iosize = this_board->iosize;
/* check if io addresses are available */
- if(check_region(iobase, iosize) < 0)
+ if(!request_region(iobase, iosize, "dac02"))
{
- printk("I/O port conflict: failed to allocate ports 0x%x to 0x%x\n",
+ printk("I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n",
iobase, iobase + iosize - 1);
return -EIO;
}
- request_region(iobase, iosize, "dac02");
dev->iobase = iobase;
- dev->n_subdevices = 1;
- if(alloc_subdevices(dev) < 0)
+ if(alloc_subdevices(dev, 1) < 0)
return -ENOMEM;
if(alloc_private(dev,sizeof(lsampl_t)*this_board->n_chan) < 0)
return -ENOMEM;
s->range_table = this_board->range;
s->insn_write = this_board->winsn;
s->insn_read = this_board->rinsn;
+ s->insn_bits = this_board->insnbits;
if(s->type==COMEDI_SUBD_AO || s->type==COMEDI_SUBD_DO){
- s->subdev_flags = SDF_WRITEABLE;
+ s->subdev_flags = SDF_WRITABLE;
}
return 0;
return 1;
}
+/* DAC-02 registers */
+#define DAC02_LSB(a) (2 * a)
+#define DAC02_MSB(a) (2 * a + 1)
+
static int dac02_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)
{
int temp;
chan = CR_CHAN(insn->chanspec);
((lsampl_t *)dev->private)[chan] = data[0];
output = data[0];
-#if wrong
+#ifdef wrong
// convert to complementary binary if range is bipolar
if((CR_RANGE(insn->chanspec) & 0x2) == 0)
output = ~output;
return 1;
}
+static int pcl733_insn_bits(comedi_device *dev,comedi_subdevice *s,
+ comedi_insn *insn,lsampl_t *data)
+{
+ if(insn->n!=2)return -EINVAL;
+
+ data[1] = inb(dev->iobase + 0);
+ data[1] |= (inb(dev->iobase + 1) << 8);
+ data[1] |= (inb(dev->iobase + 2) << 16);
+ data[1] |= (inb(dev->iobase + 3) << 24);
+
+ return 2;
+}
+
+static int pcl734_insn_bits(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]);
+ if((data[0]>>0)&0xff)
+ outb((s->state>>0)&0xff, dev->iobase + 0);
+ if((data[0]>>8)&0xff)
+ outb((s->state>>8)&0xff, dev->iobase + 1);
+ if((data[0]>>16)&0xff)
+ outb((s->state>>16)&0xff, dev->iobase + 2);
+ if((data[0]>>24)&0xff)
+ outb((s->state>>24)&0xff, dev->iobase + 3);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
COMEDI_INITCLEANUP(driver_poc);