Constified ranges, board structures, and miscellaneous data.
[comedi.git] / comedi / drivers / poc.c
index 0c0daa209f1f051af5e66448022269e38398d748..bd7ad8b53ebac452e5a427f7bca9996438c0fc58 100644 (file)
@@ -1,7 +1,7 @@
 /*
     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
 /*
 Driver: poc.o
 Description: Generic driver for very simple devices
-Device names: dac02
 Author: ds
-Devices: [Keithley Metrabyte] DAC-02 (dac02)
+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
 */
-/*
-    dac02 - Keithley DAC-02 analog output board driver
-
-*/
 
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/slab.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,
@@ -82,10 +74,28 @@ static struct boarddef_struct boards[]={
        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)
 
 static comedi_driver driver_poc=
 {
@@ -93,7 +103,7 @@ static comedi_driver driver_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]),
 };
@@ -101,10 +111,11 @@ static comedi_driver driver_poc=
 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;
@@ -117,17 +128,15 @@ static int poc_attach(comedi_device *dev, comedi_devconfig *it)
 
        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;
@@ -140,8 +149,9 @@ static int poc_attach(comedi_device *dev, comedi_devconfig *it)
        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;
@@ -168,6 +178,10 @@ static int readback_insn(comedi_device *dev,comedi_subdevice *s,comedi_insn *ins
        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;
@@ -177,7 +191,7 @@ static int dac02_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *in
        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;
@@ -190,5 +204,39 @@ static int dac02_ao_winsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *in
        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);