2 * comedi/drivers/adl_pci8164.c
4 * Hardware comedi driver for PCI-8164 Adlink card
5 * Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
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.
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.
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
26 * Configuration Options: not applicable, uses PCI auto config
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/pci.h>
33 #include "../comedidev.h"
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
41 static int adl_pci8164_insn_read(struct comedi_device *dev,
42 struct comedi_subdevice *s,
43 struct comedi_insn *insn,
46 unsigned long offset = (unsigned long)s->private;
47 unsigned int chan = CR_CHAN(insn->chanspec);
50 for (i = 0; i < insn->n; i++)
51 data[i] = inw(dev->iobase + PCI8164_AXIS(chan) + offset);
56 static int adl_pci8164_insn_write(struct comedi_device *dev,
57 struct comedi_subdevice *s,
58 struct comedi_insn *insn,
61 unsigned long offset = (unsigned long)s->private;
62 unsigned int chan = CR_CHAN(insn->chanspec);
65 for (i = 0; i < insn->n; i++)
66 outw(data[i], dev->iobase + PCI8164_AXIS(chan) + offset);
71 static int adl_pci8164_auto_attach(struct comedi_device *dev,
72 unsigned long context_unused)
74 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
75 struct comedi_subdevice *s;
78 ret = comedi_pci_enable(dev);
81 dev->iobase = pci_resource_start(pcidev, 2);
83 ret = comedi_alloc_subdevices(dev, 4);
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;
94 s->insn_read = adl_pci8164_insn_read;
95 s->insn_write = adl_pci8164_insn_write;
96 s->private = (void *)PCI8164_CMD_MSTS_REG;
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;
105 s->insn_read = adl_pci8164_insn_read;
106 s->insn_write = adl_pci8164_insn_write;
107 s->private = (void *)PCI8164_OTP_SSTS_REG;
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;
116 s->insn_read = adl_pci8164_insn_read;
117 s->insn_write = adl_pci8164_insn_write;
118 s->private = (void *)PCI8164_BUF0_REG;
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;
127 s->insn_read = adl_pci8164_insn_read;
128 s->insn_write = adl_pci8164_insn_write;
129 s->private = (void *)PCI8164_BUF1_REG;
134 static 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_disable,
141 static int adl_pci8164_pci_probe(struct pci_dev *dev,
142 const struct pci_device_id *id)
144 return comedi_pci_auto_config(dev, &adl_pci8164_driver,
148 static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = {
149 { PCI_DEVICE(PCI_VENDOR_ID_ADLINK, 0x8164) },
152 MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
154 static 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,
160 module_comedi_pci_driver(adl_pci8164_driver, adl_pci8164_pci_driver);
162 MODULE_AUTHOR("Comedi http://www.comedi.org");
163 MODULE_DESCRIPTION("Comedi low-level driver");
164 MODULE_LICENSE("GPL");