linux/drivers/staging/comedi/drivers/pcm3730.c
<<
>>
Prefs
   1/*
   2 * comedi/drivers/pcm3730.c
   3 * Driver for PCM3730 and clones
   4 * Blaine Lee
   5 * from pcl725 by David S.
   6 */
   7/*
   8Driver: pcm3730
   9Description: PCM3730
  10Author: Blaine Lee
  11Devices: [Advantech] PCM-3730 (pcm3730)
  12Status: unknown
  13
  14Configuration options:
  15  [0] - I/O port base
  16*/
  17
  18#include "../comedidev.h"
  19
  20#include <linux/ioport.h>
  21
  22#define PCM3730_SIZE 4          /*  consecutive io port addresses */
  23
  24#define PCM3730_DOA 0           /*  offsets for each port */
  25#define PCM3730_DOB 2
  26#define PCM3730_DOC 3
  27#define PCM3730_DIA 0
  28#define PCM3730_DIB 2
  29#define PCM3730_DIC 3
  30
  31static int pcm3730_do_insn_bits(struct comedi_device *dev,
  32                                struct comedi_subdevice *s,
  33                                struct comedi_insn *insn, unsigned int *data)
  34{
  35        if (data[0]) {
  36                s->state &= ~data[0];
  37                s->state |= (data[0] & data[1]);
  38                outb(s->state, dev->iobase + (unsigned long)(s->private));
  39        }
  40        data[1] = s->state;
  41
  42        return insn->n;
  43}
  44
  45static int pcm3730_di_insn_bits(struct comedi_device *dev,
  46                                struct comedi_subdevice *s,
  47                                struct comedi_insn *insn, unsigned int *data)
  48{
  49        data[1] = inb(dev->iobase + (unsigned long)(s->private));
  50        return insn->n;
  51}
  52
  53static int pcm3730_attach(struct comedi_device *dev,
  54                          struct comedi_devconfig *it)
  55{
  56        struct comedi_subdevice *s;
  57        unsigned long iobase;
  58        int ret;
  59
  60        iobase = it->options[0];
  61        printk(KERN_INFO "comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
  62        if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) {
  63                printk("I/O port conflict\n");
  64                return -EIO;
  65        }
  66        dev->iobase = iobase;
  67        dev->board_name = "pcm3730";
  68        dev->iobase = dev->iobase;
  69        dev->irq = 0;
  70
  71        ret = comedi_alloc_subdevices(dev, 6);
  72        if (ret)
  73                return ret;
  74
  75        s = dev->subdevices + 0;
  76        s->type = COMEDI_SUBD_DO;
  77        s->subdev_flags = SDF_WRITABLE;
  78        s->maxdata = 1;
  79        s->n_chan = 8;
  80        s->insn_bits = pcm3730_do_insn_bits;
  81        s->range_table = &range_digital;
  82        s->private = (void *)PCM3730_DOA;
  83
  84        s = dev->subdevices + 1;
  85        s->type = COMEDI_SUBD_DO;
  86        s->subdev_flags = SDF_WRITABLE;
  87        s->maxdata = 1;
  88        s->n_chan = 8;
  89        s->insn_bits = pcm3730_do_insn_bits;
  90        s->range_table = &range_digital;
  91        s->private = (void *)PCM3730_DOB;
  92
  93        s = dev->subdevices + 2;
  94        s->type = COMEDI_SUBD_DO;
  95        s->subdev_flags = SDF_WRITABLE;
  96        s->maxdata = 1;
  97        s->n_chan = 8;
  98        s->insn_bits = pcm3730_do_insn_bits;
  99        s->range_table = &range_digital;
 100        s->private = (void *)PCM3730_DOC;
 101
 102        s = dev->subdevices + 3;
 103        s->type = COMEDI_SUBD_DI;
 104        s->subdev_flags = SDF_READABLE;
 105        s->maxdata = 1;
 106        s->n_chan = 8;
 107        s->insn_bits = pcm3730_di_insn_bits;
 108        s->range_table = &range_digital;
 109        s->private = (void *)PCM3730_DIA;
 110
 111        s = dev->subdevices + 4;
 112        s->type = COMEDI_SUBD_DI;
 113        s->subdev_flags = SDF_READABLE;
 114        s->maxdata = 1;
 115        s->n_chan = 8;
 116        s->insn_bits = pcm3730_di_insn_bits;
 117        s->range_table = &range_digital;
 118        s->private = (void *)PCM3730_DIB;
 119
 120        s = dev->subdevices + 5;
 121        s->type = COMEDI_SUBD_DI;
 122        s->subdev_flags = SDF_READABLE;
 123        s->maxdata = 1;
 124        s->n_chan = 8;
 125        s->insn_bits = pcm3730_di_insn_bits;
 126        s->range_table = &range_digital;
 127        s->private = (void *)PCM3730_DIC;
 128
 129        printk(KERN_INFO "\n");
 130
 131        return 0;
 132}
 133
 134static void pcm3730_detach(struct comedi_device *dev)
 135{
 136        if (dev->iobase)
 137                release_region(dev->iobase, PCM3730_SIZE);
 138}
 139
 140static struct comedi_driver pcm3730_driver = {
 141        .driver_name    = "pcm3730",
 142        .module         = THIS_MODULE,
 143        .attach         = pcm3730_attach,
 144        .detach         = pcm3730_detach,
 145};
 146module_comedi_driver(pcm3730_driver);
 147
 148MODULE_AUTHOR("Comedi http://www.comedi.org");
 149MODULE_DESCRIPTION("Comedi low-level driver");
 150MODULE_LICENSE("GPL");
 151