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.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 * Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
25 * Devices: (ADLink) PCI-8164 [adl_pci8164]
26 * Author: Michel Lachaine <mike@mikelachaine.ca>
27 * Status: experimental
28 * Updated: Mon, 14 Apr 2008 15:10:32 +0100
30 * Configuration Options: not applicable, uses PCI auto config
33 #include <linux/kernel.h>
34 #include <linux/pci.h>
36 #include "../comedidev.h"
38 #define PCI8164_AXIS(x) ((x) * 0x08)
39 #define PCI8164_CMD_MSTS_REG 0x00
40 #define PCI8164_OTP_SSTS_REG 0x02
41 #define PCI8164_BUF0_REG 0x04
42 #define PCI8164_BUF1_REG 0x06
44 static int adl_pci8164_insn_read(struct comedi_device
*dev
,
45 struct comedi_subdevice
*s
,
46 struct comedi_insn
*insn
,
49 unsigned long offset
= (unsigned long)s
->private;
50 unsigned int chan
= CR_CHAN(insn
->chanspec
);
53 for (i
= 0; i
< insn
->n
; i
++)
54 data
[i
] = inw(dev
->iobase
+ PCI8164_AXIS(chan
) + offset
);
59 static int adl_pci8164_insn_write(struct comedi_device
*dev
,
60 struct comedi_subdevice
*s
,
61 struct comedi_insn
*insn
,
64 unsigned long offset
= (unsigned long)s
->private;
65 unsigned int chan
= CR_CHAN(insn
->chanspec
);
68 for (i
= 0; i
< insn
->n
; i
++)
69 outw(data
[i
], dev
->iobase
+ PCI8164_AXIS(chan
) + offset
);
74 static int adl_pci8164_auto_attach(struct comedi_device
*dev
,
75 unsigned long context_unused
)
77 struct pci_dev
*pcidev
= comedi_to_pci_dev(dev
);
78 struct comedi_subdevice
*s
;
81 ret
= comedi_pci_enable(dev
);
84 dev
->iobase
= pci_resource_start(pcidev
, 2);
86 ret
= comedi_alloc_subdevices(dev
, 4);
90 /* read MSTS register / write CMD register for each axis (channel) */
91 s
= &dev
->subdevices
[0];
92 s
->type
= COMEDI_SUBD_PROC
;
93 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
97 s
->insn_read
= adl_pci8164_insn_read
;
98 s
->insn_write
= adl_pci8164_insn_write
;
99 s
->private = (void *)PCI8164_CMD_MSTS_REG
;
101 /* read SSTS register / write OTP register for each axis (channel) */
102 s
= &dev
->subdevices
[1];
103 s
->type
= COMEDI_SUBD_PROC
;
104 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
108 s
->insn_read
= adl_pci8164_insn_read
;
109 s
->insn_write
= adl_pci8164_insn_write
;
110 s
->private = (void *)PCI8164_OTP_SSTS_REG
;
112 /* read/write BUF0 register for each axis (channel) */
113 s
= &dev
->subdevices
[2];
114 s
->type
= COMEDI_SUBD_PROC
;
115 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
119 s
->insn_read
= adl_pci8164_insn_read
;
120 s
->insn_write
= adl_pci8164_insn_write
;
121 s
->private = (void *)PCI8164_BUF0_REG
;
123 /* read/write BUF1 register for each axis (channel) */
124 s
= &dev
->subdevices
[3];
125 s
->type
= COMEDI_SUBD_PROC
;
126 s
->subdev_flags
= SDF_READABLE
| SDF_WRITABLE
;
130 s
->insn_read
= adl_pci8164_insn_read
;
131 s
->insn_write
= adl_pci8164_insn_write
;
132 s
->private = (void *)PCI8164_BUF1_REG
;
137 static struct comedi_driver adl_pci8164_driver
= {
138 .driver_name
= "adl_pci8164",
139 .module
= THIS_MODULE
,
140 .auto_attach
= adl_pci8164_auto_attach
,
141 .detach
= comedi_pci_disable
,
144 static int adl_pci8164_pci_probe(struct pci_dev
*dev
,
145 const struct pci_device_id
*id
)
147 return comedi_pci_auto_config(dev
, &adl_pci8164_driver
,
151 static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table
) = {
152 { PCI_DEVICE(PCI_VENDOR_ID_ADLINK
, 0x8164) },
155 MODULE_DEVICE_TABLE(pci
, adl_pci8164_pci_table
);
157 static struct pci_driver adl_pci8164_pci_driver
= {
158 .name
= "adl_pci8164",
159 .id_table
= adl_pci8164_pci_table
,
160 .probe
= adl_pci8164_pci_probe
,
161 .remove
= comedi_pci_auto_unconfig
,
163 module_comedi_pci_driver(adl_pci8164_driver
, adl_pci8164_pci_driver
);
165 MODULE_AUTHOR("Comedi http://www.comedi.org");
166 MODULE_DESCRIPTION("Comedi low-level driver");
167 MODULE_LICENSE("GPL");