linux/drivers/staging/comedi/drivers/adl_pci8164.c
<<
>>
Prefs
   1/*
   2 * comedi/drivers/adl_pci8164.c
   3 *
   4 * Hardware comedi driver for PCI-8164 Adlink card
   5 * Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 */
  17
  18/*
  19 * Driver: adl_pci8164
  20 * Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
  21 * Devices: (ADLink) PCI-8164 [adl_pci8164]
  22 * Author: Michel Lachaine <mike@mikelachaine.ca>
  23 * Status: experimental
  24 * Updated: Mon, 14 Apr 2008 15:10:32 +0100
  25 *
  26 * Configuration Options: not applicable, uses PCI auto config
  27 */
  28
  29#include <linux/kernel.h>
  30#include <linux/module.h>
  31#include <linux/pci.h>
  32
  33#include "../comedidev.h"
  34
  35#define PCI8164_AXIS(x)         ((x) * 0x08)
  36#define PCI8164_CMD_MSTS_REG    0x00
  37#define PCI8164_OTP_SSTS_REG    0x02
  38#define PCI8164_BUF0_REG        0x04
  39#define PCI8164_BUF1_REG        0x06
  40
  41static int adl_pci8164_insn_read(struct comedi_device *dev,
  42                                 struct comedi_subdevice *s,
  43                                 struct comedi_insn *insn,
  44                                 unsigned int *data)
  45{
  46        unsigned long offset = (unsigned long)s->private;
  47        unsigned int chan = CR_CHAN(insn->chanspec);
  48        int i;
  49
  50        for (i = 0; i < insn->n; i++)
  51                data[i] = inw(dev->iobase + PCI8164_AXIS(chan) + offset);
  52
  53        return insn->n;
  54}
  55
  56static int adl_pci8164_insn_write(struct comedi_device *dev,
  57                                  struct comedi_subdevice *s,
  58                                  struct comedi_insn *insn,
  59                                  unsigned int *data)
  60{
  61        unsigned long offset = (unsigned long)s->private;
  62        unsigned int chan = CR_CHAN(insn->chanspec);
  63        int i;
  64
  65        for (i = 0; i < insn->n; i++)
  66                outw(data[i], dev->iobase + PCI8164_AXIS(chan) + offset);
  67
  68        return insn->n;
  69}
  70
  71static int adl_pci8164_auto_attach(struct comedi_device *dev,
  72                                             unsigned long context_unused)
  73{
  74        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
  75        struct comedi_subdevice *s;
  76        int ret;
  77
  78        ret = comedi_pci_enable(dev);
  79        if (ret)
  80                return ret;
  81        dev->iobase = pci_resource_start(pcidev, 2);
  82
  83        ret = comedi_alloc_subdevices(dev, 4);
  84        if (ret)
  85                return ret;
  86
  87        /* read MSTS register / write CMD register for each axis (channel) */
  88        s = &dev->subdevices[0];
  89        s->type         = COMEDI_SUBD_PROC;
  90        s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
  91        s->n_chan       = 4;
  92        s->maxdata      = 0xffff;
  93        s->len_chanlist = 4;
  94        s->insn_read    = adl_pci8164_insn_read;
  95        s->insn_write   = adl_pci8164_insn_write;
  96        s->private      = (void *)PCI8164_CMD_MSTS_REG;
  97
  98        /* read SSTS register / write OTP register for each axis (channel) */
  99        s = &dev->subdevices[1];
 100        s->type         = COMEDI_SUBD_PROC;
 101        s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
 102        s->n_chan       = 4;
 103        s->maxdata      = 0xffff;
 104        s->len_chanlist = 4;
 105        s->insn_read    = adl_pci8164_insn_read;
 106        s->insn_write   = adl_pci8164_insn_write;
 107        s->private      = (void *)PCI8164_OTP_SSTS_REG;
 108
 109        /* read/write BUF0 register for each axis (channel) */
 110        s = &dev->subdevices[2];
 111        s->type         = COMEDI_SUBD_PROC;
 112        s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
 113        s->n_chan       = 4;
 114        s->maxdata      = 0xffff;
 115        s->len_chanlist = 4;
 116        s->insn_read    = adl_pci8164_insn_read;
 117        s->insn_write   = adl_pci8164_insn_write;
 118        s->private      = (void *)PCI8164_BUF0_REG;
 119
 120        /* read/write BUF1 register for each axis (channel) */
 121        s = &dev->subdevices[3];
 122        s->type         = COMEDI_SUBD_PROC;
 123        s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
 124        s->n_chan       = 4;
 125        s->maxdata      = 0xffff;
 126        s->len_chanlist = 4;
 127        s->insn_read    = adl_pci8164_insn_read;
 128        s->insn_write   = adl_pci8164_insn_write;
 129        s->private      = (void *)PCI8164_BUF1_REG;
 130
 131        return 0;
 132}
 133
 134static struct comedi_driver adl_pci8164_driver = {
 135        .driver_name    = "adl_pci8164",
 136        .module         = THIS_MODULE,
 137        .auto_attach    = adl_pci8164_auto_attach,
 138        .detach         = comedi_pci_detach,
 139};
 140
 141static int adl_pci8164_pci_probe(struct pci_dev *dev,
 142                                 const struct pci_device_id *id)
 143{
 144        return comedi_pci_auto_config(dev, &adl_pci8164_driver,
 145                                      id->driver_data);
 146}
 147
 148static const struct pci_device_id adl_pci8164_pci_table[] = {
 149        { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x8164) },
 150        { 0 }
 151};
 152MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
 153
 154static struct pci_driver adl_pci8164_pci_driver = {
 155        .name           = "adl_pci8164",
 156        .id_table       = adl_pci8164_pci_table,
 157        .probe          = adl_pci8164_pci_probe,
 158        .remove         = comedi_pci_auto_unconfig,
 159};
 160module_comedi_pci_driver(adl_pci8164_driver, adl_pci8164_pci_driver);
 161
 162MODULE_AUTHOR("Comedi http://www.comedi.org");
 163MODULE_DESCRIPTION("Comedi low-level driver");
 164MODULE_LICENSE("GPL");
 165
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.