aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH Hartley Sweeten <hsweeten@visionengravers.com>2013-01-23 14:35:51 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-01-25 14:27:58 -0500
commit8861b456b8f800208e043b2d0d65985eca538dd9 (patch)
treec2f12f94c032a176e14bbb67ba79f1e9ed158d49
parentae59ecfd3ff45833c23913877d8c8d94eeb930d0 (diff)
staging: comedi: addi_apci_3501: separate from addi_common.c
This driver is for a simple analog output board with 4 or 8, 14-bit outputs. The board also has 4 digital i/o channels (2 out/2 in) as well as a watchdog or timer. Using the addi-data "common" code in this driver introduces a lot of bloat. Copy the code in addi_common.c to this driver and remove the #include that caused it to be compiled with the driver. This will allow removing the bloat. Rename the auto_attach and detach functions so they have namespace associated with this driver. Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Cc: Ian Abbott <abbotti@mev.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c324
1 files changed, 316 insertions, 8 deletions
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
index ed297deb8634..e2ea54267aab 100644
--- a/drivers/staging/comedi/drivers/addi_apci_3501.c
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -4,9 +4,12 @@
4 4
5#include "addi-data/addi_common.h" 5#include "addi-data/addi_common.h"
6 6
7#ifndef COMEDI_SUBD_TTLIO
8#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
9#endif
10
7#include "addi-data/addi_eeprom.c" 11#include "addi-data/addi_eeprom.c"
8#include "addi-data/hwdrv_apci3501.c" 12#include "addi-data/hwdrv_apci3501.c"
9#include "addi-data/addi_common.c"
10 13
11static const struct addi_board apci3501_boardtypes[] = { 14static const struct addi_board apci3501_boardtypes[] = {
12 { 15 {
@@ -35,17 +38,316 @@ static const struct addi_board apci3501_boardtypes[] = {
35 }, 38 },
36}; 39};
37 40
38static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = { 41static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,
39 { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) }, 42 struct comedi_subdevice *s,
40 { 0 } 43 struct comedi_insn *insn,
41}; 44 unsigned int *data)
42MODULE_DEVICE_TABLE(pci, apci3501_pci_table); 45{
46 const struct addi_board *this_board = comedi_board(dev);
47 struct addi_private *devpriv = dev->private;
48 unsigned short w_Address = CR_CHAN(insn->chanspec);
49 unsigned short w_Data;
50
51 w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc,
52 this_board->pc_EepromChip, 2 * w_Address);
53 data[0] = w_Data;
54
55 return insn->n;
56}
57
58static irqreturn_t v_ADDI_Interrupt(int irq, void *d)
59{
60 struct comedi_device *dev = d;
61 const struct addi_board *this_board = comedi_board(dev);
62
63 this_board->interrupt(irq, d);
64 return IRQ_RETVAL(1);
65}
66
67static int i_ADDI_Reset(struct comedi_device *dev)
68{
69 const struct addi_board *this_board = comedi_board(dev);
70
71 this_board->reset(dev);
72 return 0;
73}
74
75static const void *addi_find_boardinfo(struct comedi_device *dev,
76 struct pci_dev *pcidev)
77{
78 const void *p = dev->driver->board_name;
79 const struct addi_board *this_board;
80 int i;
81
82 for (i = 0; i < dev->driver->num_names; i++) {
83 this_board = p;
84 if (this_board->i_VendorId == pcidev->vendor &&
85 this_board->i_DeviceId == pcidev->device)
86 return this_board;
87 p += dev->driver->offset;
88 }
89 return NULL;
90}
91
92static int apci3501_auto_attach(struct comedi_device *dev,
93 unsigned long context_unused)
94{
95 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
96 const struct addi_board *this_board;
97 struct addi_private *devpriv;
98 struct comedi_subdevice *s;
99 int ret, n_subdevices;
100 unsigned int dw_Dummy;
101
102 this_board = addi_find_boardinfo(dev, pcidev);
103 if (!this_board)
104 return -ENODEV;
105 dev->board_ptr = this_board;
106 dev->board_name = this_board->pc_DriverName;
107
108 devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
109 if (!devpriv)
110 return -ENOMEM;
111 dev->private = devpriv;
112
113 ret = comedi_pci_enable(pcidev, dev->board_name);
114 if (ret)
115 return ret;
116
117 if (!this_board->pc_EepromChip ||
118 strcmp(this_board->pc_EepromChip, ADDIDATA_9054)) {
119 /* board does not have an eeprom or is not ADDIDATA_9054 */
120 if (this_board->i_IorangeBase1)
121 dev->iobase = pci_resource_start(pcidev, 1);
122 else
123 dev->iobase = pci_resource_start(pcidev, 0);
124
125 devpriv->iobase = dev->iobase;
126 devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0);
127 devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2);
128 } else {
129 /* board has an ADDIDATA_9054 eeprom */
130 dev->iobase = pci_resource_start(pcidev, 2);
131 devpriv->iobase = pci_resource_start(pcidev, 2);
132 devpriv->dw_AiBase = ioremap(pci_resource_start(pcidev, 3),
133 this_board->i_IorangeBase3);
134 }
135 devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3);
136
137 /* Initialize parameters that can be overridden in EEPROM */
138 devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel;
139 devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel;
140 devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata;
141 devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata;
142 devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel;
143 devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel;
144 devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata;
145 devpriv->s_EeParameters.i_Dma = this_board->i_Dma;
146 devpriv->s_EeParameters.i_Timer = this_board->i_Timer;
147 devpriv->s_EeParameters.ui_MinAcquisitiontimeNs =
148 this_board->ui_MinAcquisitiontimeNs;
149 devpriv->s_EeParameters.ui_MinDelaytimeNs =
150 this_board->ui_MinDelaytimeNs;
151
152 /* ## */
153
154 if (pcidev->irq > 0) {
155 ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED,
156 dev->board_name, dev);
157 if (ret == 0)
158 dev->irq = pcidev->irq;
159 }
160
161 /* Read eepeom and fill addi_board Structure */
162
163 if (this_board->i_PCIEeprom) {
164 if (!(strcmp(this_board->pc_EepromChip, "S5920"))) {
165 /* Set 3 wait stait */
166 if (!(strcmp(dev->board_name, "apci035")))
167 outl(0x80808082, devpriv->i_IobaseAmcc + 0x60);
168 else
169 outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
170
171 /* Enable the interrupt for the controller */
172 dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
173 outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
174 }
175 addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0));
176 }
177
178 n_subdevices = 7;
179 ret = comedi_alloc_subdevices(dev, n_subdevices);
180 if (ret)
181 return ret;
182
183 /* Allocate and Initialise AI Subdevice Structures */
184 s = &dev->subdevices[0];
185 if ((devpriv->s_EeParameters.i_NbrAiChannel)
186 || (this_board->i_NbrAiChannelDiff)) {
187 dev->read_subdev = s;
188 s->type = COMEDI_SUBD_AI;
189 s->subdev_flags =
190 SDF_READABLE | SDF_COMMON | SDF_GROUND
191 | SDF_DIFF;
192 if (devpriv->s_EeParameters.i_NbrAiChannel) {
193 s->n_chan =
194 devpriv->s_EeParameters.i_NbrAiChannel;
195 devpriv->b_SingelDiff = 0;
196 } else {
197 s->n_chan = this_board->i_NbrAiChannelDiff;
198 devpriv->b_SingelDiff = 1;
199 }
200 s->maxdata = devpriv->s_EeParameters.i_AiMaxdata;
201 s->len_chanlist = this_board->i_AiChannelList;
202 s->range_table = this_board->pr_AiRangelist;
203
204 /* Set the initialisation flag */
205 devpriv->b_AiInitialisation = 1;
206
207 s->insn_config = this_board->ai_config;
208 s->insn_read = this_board->ai_read;
209 s->insn_write = this_board->ai_write;
210 s->insn_bits = this_board->ai_bits;
211 s->do_cmdtest = this_board->ai_cmdtest;
212 s->do_cmd = this_board->ai_cmd;
213 s->cancel = this_board->ai_cancel;
214
215 } else {
216 s->type = COMEDI_SUBD_UNUSED;
217 }
218
219 /* Allocate and Initialise AO Subdevice Structures */
220 s = &dev->subdevices[1];
221 if (devpriv->s_EeParameters.i_NbrAoChannel) {
222 s->type = COMEDI_SUBD_AO;
223 s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
224 s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel;
225 s->maxdata = devpriv->s_EeParameters.i_AoMaxdata;
226 s->len_chanlist =
227 devpriv->s_EeParameters.i_NbrAoChannel;
228 s->range_table = this_board->pr_AoRangelist;
229 s->insn_config = this_board->ao_config;
230 s->insn_write = this_board->ao_write;
231 } else {
232 s->type = COMEDI_SUBD_UNUSED;
233 }
234 /* Allocate and Initialise DI Subdevice Structures */
235 s = &dev->subdevices[2];
236 if (devpriv->s_EeParameters.i_NbrDiChannel) {
237 s->type = COMEDI_SUBD_DI;
238 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
239 s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel;
240 s->maxdata = 1;
241 s->len_chanlist =
242 devpriv->s_EeParameters.i_NbrDiChannel;
243 s->range_table = &range_digital;
244 s->io_bits = 0; /* all bits input */
245 s->insn_config = this_board->di_config;
246 s->insn_read = this_board->di_read;
247 s->insn_write = this_board->di_write;
248 s->insn_bits = this_board->di_bits;
249 } else {
250 s->type = COMEDI_SUBD_UNUSED;
251 }
252 /* Allocate and Initialise DO Subdevice Structures */
253 s = &dev->subdevices[3];
254 if (devpriv->s_EeParameters.i_NbrDoChannel) {
255 s->type = COMEDI_SUBD_DO;
256 s->subdev_flags =
257 SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
258 s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel;
259 s->maxdata = devpriv->s_EeParameters.i_DoMaxdata;
260 s->len_chanlist =
261 devpriv->s_EeParameters.i_NbrDoChannel;
262 s->range_table = &range_digital;
263 s->io_bits = 0xf; /* all bits output */
264
265 /* insn_config - for digital output memory */
266 s->insn_config = this_board->do_config;
267 s->insn_write = this_board->do_write;
268 s->insn_bits = this_board->do_bits;
269 s->insn_read = this_board->do_read;
270 } else {
271 s->type = COMEDI_SUBD_UNUSED;
272 }
273
274 /* Allocate and Initialise Timer Subdevice Structures */
275 s = &dev->subdevices[4];
276 if (devpriv->s_EeParameters.i_Timer) {
277 s->type = COMEDI_SUBD_TIMER;
278 s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
279 s->n_chan = 1;
280 s->maxdata = 0;
281 s->len_chanlist = 1;
282 s->range_table = &range_digital;
283
284 s->insn_write = this_board->timer_write;
285 s->insn_read = this_board->timer_read;
286 s->insn_config = this_board->timer_config;
287 s->insn_bits = this_board->timer_bits;
288 } else {
289 s->type = COMEDI_SUBD_UNUSED;
290 }
291
292 /* Allocate and Initialise TTL */
293 s = &dev->subdevices[5];
294 if (this_board->i_NbrTTLChannel) {
295 s->type = COMEDI_SUBD_TTLIO;
296 s->subdev_flags =
297 SDF_WRITEABLE | SDF_READABLE | SDF_GROUND | SDF_COMMON;
298 s->n_chan = this_board->i_NbrTTLChannel;
299 s->maxdata = 1;
300 s->io_bits = 0; /* all bits input */
301 s->len_chanlist = this_board->i_NbrTTLChannel;
302 s->range_table = &range_digital;
303 s->insn_config = this_board->ttl_config;
304 s->insn_bits = this_board->ttl_bits;
305 s->insn_read = this_board->ttl_read;
306 s->insn_write = this_board->ttl_write;
307 } else {
308 s->type = COMEDI_SUBD_UNUSED;
309 }
310
311 /* EEPROM */
312 s = &dev->subdevices[6];
313 if (this_board->i_PCIEeprom) {
314 s->type = COMEDI_SUBD_MEMORY;
315 s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
316 s->n_chan = 256;
317 s->maxdata = 0xffff;
318 s->insn_read = i_ADDIDATA_InsnReadEeprom;
319 } else {
320 s->type = COMEDI_SUBD_UNUSED;
321 }
322
323 i_ADDI_Reset(dev);
324 return 0;
325}
326
327static void apci3501_detach(struct comedi_device *dev)
328{
329 struct pci_dev *pcidev = comedi_to_pci_dev(dev);
330 struct addi_private *devpriv = dev->private;
331
332 if (devpriv) {
333 if (dev->iobase)
334 i_ADDI_Reset(dev);
335 if (dev->irq)
336 free_irq(dev->irq, dev);
337 if (devpriv->dw_AiBase)
338 iounmap(devpriv->dw_AiBase);
339 }
340 if (pcidev) {
341 if (dev->iobase)
342 comedi_pci_disable(pcidev);
343 }
344}
43 345
44static struct comedi_driver apci3501_driver = { 346static struct comedi_driver apci3501_driver = {
45 .driver_name = "addi_apci_3501", 347 .driver_name = "addi_apci_3501",
46 .module = THIS_MODULE, 348 .module = THIS_MODULE,
47 .auto_attach = addi_auto_attach, 349 .auto_attach = apci3501_auto_attach,
48 .detach = i_ADDI_Detach, 350 .detach = apci3501_detach,
49 .num_names = ARRAY_SIZE(apci3501_boardtypes), 351 .num_names = ARRAY_SIZE(apci3501_boardtypes),
50 .board_name = &apci3501_boardtypes[0].pc_DriverName, 352 .board_name = &apci3501_boardtypes[0].pc_DriverName,
51 .offset = sizeof(struct addi_board), 353 .offset = sizeof(struct addi_board),
@@ -62,6 +364,12 @@ static void apci3501_pci_remove(struct pci_dev *dev)
62 comedi_pci_auto_unconfig(dev); 364 comedi_pci_auto_unconfig(dev);
63} 365}
64 366
367static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = {
368 { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) },
369 { 0 }
370};
371MODULE_DEVICE_TABLE(pci, apci3501_pci_table);
372
65static struct pci_driver apci3501_pci_driver = { 373static struct pci_driver apci3501_pci_driver = {
66 .name = "addi_apci_3501", 374 .name = "addi_apci_3501",
67 .id_table = apci3501_pci_table, 375 .id_table = apci3501_pci_table,