This source file includes following definitions.
- cb_pcimdda_ao_insn_write
- cb_pcimdda_ao_insn_read
- cb_pcimdda_auto_attach
- cb_pcimdda_pci_probe
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69 #include <linux/module.h>
70
71 #include "../comedi_pci.h"
72
73 #include "8255.h"
74
75
76 #define PCI_ID_PCIM_DDA06_16 0x0053
77
78
79
80
81 #define PCIMDDA_DA_CHAN(x) (0x00 + (x) * 2)
82 #define PCIMDDA_8255_BASE_REG 0x0c
83
84 static int cb_pcimdda_ao_insn_write(struct comedi_device *dev,
85 struct comedi_subdevice *s,
86 struct comedi_insn *insn,
87 unsigned int *data)
88 {
89 unsigned int chan = CR_CHAN(insn->chanspec);
90 unsigned long offset = dev->iobase + PCIMDDA_DA_CHAN(chan);
91 unsigned int val = s->readback[chan];
92 int i;
93
94 for (i = 0; i < insn->n; i++) {
95 val = data[i];
96
97
98
99
100
101
102
103
104
105
106 outb(val & 0x00ff, offset);
107 outb((val >> 8) & 0x00ff, offset + 1);
108 }
109 s->readback[chan] = val;
110
111 return insn->n;
112 }
113
114 static int cb_pcimdda_ao_insn_read(struct comedi_device *dev,
115 struct comedi_subdevice *s,
116 struct comedi_insn *insn,
117 unsigned int *data)
118 {
119 unsigned int chan = CR_CHAN(insn->chanspec);
120
121
122 inw(dev->iobase + PCIMDDA_DA_CHAN(chan));
123
124 return comedi_readback_insn_read(dev, s, insn, data);
125 }
126
127 static int cb_pcimdda_auto_attach(struct comedi_device *dev,
128 unsigned long context_unused)
129 {
130 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
131 struct comedi_subdevice *s;
132 int ret;
133
134 ret = comedi_pci_enable(dev);
135 if (ret)
136 return ret;
137 dev->iobase = pci_resource_start(pcidev, 3);
138
139 ret = comedi_alloc_subdevices(dev, 2);
140 if (ret)
141 return ret;
142
143 s = &dev->subdevices[0];
144
145 s->type = COMEDI_SUBD_AO;
146 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
147 s->n_chan = 6;
148 s->maxdata = 0xffff;
149 s->range_table = &range_bipolar5;
150 s->insn_write = cb_pcimdda_ao_insn_write;
151 s->insn_read = cb_pcimdda_ao_insn_read;
152
153 ret = comedi_alloc_subdev_readback(s);
154 if (ret)
155 return ret;
156
157 s = &dev->subdevices[1];
158
159 return subdev_8255_init(dev, s, NULL, PCIMDDA_8255_BASE_REG);
160 }
161
162 static struct comedi_driver cb_pcimdda_driver = {
163 .driver_name = "cb_pcimdda",
164 .module = THIS_MODULE,
165 .auto_attach = cb_pcimdda_auto_attach,
166 .detach = comedi_pci_detach,
167 };
168
169 static int cb_pcimdda_pci_probe(struct pci_dev *dev,
170 const struct pci_device_id *id)
171 {
172 return comedi_pci_auto_config(dev, &cb_pcimdda_driver,
173 id->driver_data);
174 }
175
176 static const struct pci_device_id cb_pcimdda_pci_table[] = {
177 { PCI_DEVICE(PCI_VENDOR_ID_CB, PCI_ID_PCIM_DDA06_16) },
178 { 0 }
179 };
180 MODULE_DEVICE_TABLE(pci, cb_pcimdda_pci_table);
181
182 static struct pci_driver cb_pcimdda_driver_pci_driver = {
183 .name = "cb_pcimdda",
184 .id_table = cb_pcimdda_pci_table,
185 .probe = cb_pcimdda_pci_probe,
186 .remove = comedi_pci_auto_unconfig,
187 };
188 module_comedi_pci_driver(cb_pcimdda_driver, cb_pcimdda_driver_pci_driver);
189
190 MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>");
191 MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA series. Currently only supports PCIM-DDA06-16 (which also happens to be the only board in this series. :) ) ");
192 MODULE_LICENSE("GPL");