diff options
author | H Hartley Sweeten <hsweeten@visionengravers.com> | 2013-01-23 14:35:51 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-01-25 14:27:58 -0500 |
commit | 8861b456b8f800208e043b2d0d65985eca538dd9 (patch) | |
tree | c2f12f94c032a176e14bbb67ba79f1e9ed158d49 | |
parent | ae59ecfd3ff45833c23913877d8c8d94eeb930d0 (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.c | 324 |
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 | ||
11 | static const struct addi_board apci3501_boardtypes[] = { | 14 | static 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 | ||
38 | static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = { | 41 | static 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) |
42 | MODULE_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 | |||
58 | static 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 | |||
67 | static 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 | |||
75 | static 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 | |||
92 | static 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 | |||
327 | static 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 | ||
44 | static struct comedi_driver apci3501_driver = { | 346 | static 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 | ||
367 | static DEFINE_PCI_DEVICE_TABLE(apci3501_pci_table) = { | ||
368 | { PCI_DEVICE(PCI_VENDOR_ID_ADDIDATA, 0x3001) }, | ||
369 | { 0 } | ||
370 | }; | ||
371 | MODULE_DEVICE_TABLE(pci, apci3501_pci_table); | ||
372 | |||
65 | static struct pci_driver apci3501_pci_driver = { | 373 | static 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, |