1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35#include <linux/module.h>
36#include <linux/pci.h>
37
38#include "../comedidev.h"
39
40#define PCI263_DRIVER_NAME "amplc_pci263"
41
42
43#define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c
44
45static int pci263_do_insn_bits(struct comedi_device *dev,
46 struct comedi_subdevice *s,
47 struct comedi_insn *insn, unsigned int *data)
48{
49
50
51 if (data[0]) {
52 s->state &= ~data[0];
53 s->state |= data[0] & data[1];
54
55 outb(s->state & 0xFF, dev->iobase);
56 outb(s->state >> 8, dev->iobase + 1);
57 }
58 return insn->n;
59}
60
61static int pci263_auto_attach(struct comedi_device *dev,
62 unsigned long context_unused)
63{
64 struct pci_dev *pci_dev = comedi_to_pci_dev(dev);
65 struct comedi_subdevice *s;
66 int ret;
67
68 ret = comedi_pci_enable(dev);
69 if (ret)
70 return ret;
71
72 dev->iobase = pci_resource_start(pci_dev, 2);
73 ret = comedi_alloc_subdevices(dev, 1);
74 if (ret)
75 return ret;
76
77 s = &dev->subdevices[0];
78
79 s->type = COMEDI_SUBD_DO;
80 s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
81 s->n_chan = 16;
82 s->maxdata = 1;
83 s->range_table = &range_digital;
84 s->insn_bits = pci263_do_insn_bits;
85
86 s->state = inb(dev->iobase) | (inb(dev->iobase + 1) << 8);
87
88 dev_info(dev->class_dev, "%s (pci %s) attached\n", dev->board_name,
89 pci_name(pci_dev));
90 return 0;
91}
92
93static struct comedi_driver amplc_pci263_driver = {
94 .driver_name = PCI263_DRIVER_NAME,
95 .module = THIS_MODULE,
96 .auto_attach = pci263_auto_attach,
97 .detach = comedi_pci_disable,
98};
99
100static DEFINE_PCI_DEVICE_TABLE(pci263_pci_table) = {
101 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263) },
102 {0}
103};
104MODULE_DEVICE_TABLE(pci, pci263_pci_table);
105
106static int amplc_pci263_pci_probe(struct pci_dev *dev,
107 const struct pci_device_id *id)
108{
109 return comedi_pci_auto_config(dev, &lc_pci263_driver,
110 id->driver_data);
111}
112
113static struct pci_driver amplc_pci263_pci_driver = {
114 .name = PCI263_DRIVER_NAME,
115 .id_table = pci263_pci_table,
116 .probe = &lc_pci263_pci_probe,
117 .remove = comedi_pci_auto_unconfig,
118};
119module_comedi_pci_driver(amplc_pci263_driver, amplc_pci263_pci_driver);
120
121MODULE_AUTHOR("Comedi http://www.comedi.org");
122MODULE_DESCRIPTION("Comedi driver for Amplicon PCI263 relay board");
123MODULE_LICENSE("GPL");
124