]>
Commit | Line | Data |
---|---|---|
c995fe94 ADG |
1 | /** |
2 | @verbatim | |
3 | ||
4 | Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. | |
5 | ||
356cdbcb BP |
6 | ADDI-DATA GmbH |
7 | Dieselstrasse 3 | |
8 | D-77833 Ottersweier | |
9 | Tel: +19(0)7223/9493-0 | |
10 | Fax: +49(0)7223/9493-92 | |
25417922 | 11 | http://www.addi-data.com |
356cdbcb | 12 | info@addi-data.com |
c995fe94 | 13 | |
5eaf711b LA |
14 | This program is free software; you can redistribute it and/or modify it under |
15 | the terms of the GNU General Public License as published by the Free Software | |
16 | Foundation; either version 2 of the License, or (at your option) any later | |
17 | version. | |
c995fe94 | 18 | |
5eaf711b LA |
19 | This program is distributed in the hope that it will be useful, but WITHOUT ANY |
20 | WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
21 | PARTICULAR PURPOSE. See the GNU General Public License for more details. | |
c995fe94 | 22 | |
c995fe94 ADG |
23 | @endverbatim |
24 | */ | |
25 | /* | |
26 | ||
27 | +-----------------------------------------------------------------------+ | |
28 | | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier | | |
29 | +-----------------------------------------------------------------------+ | |
30 | | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | | |
31 | | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | | |
32 | +-----------------------------------------------------------------------+ | |
5eaf711b | 33 | | Project : ADDI DATA | Compiler : GCC | |
c995fe94 ADG |
34 | | Modulname : addi_common.c | Version : 2.96 | |
35 | +-------------------------------+---------------------------------------+ | |
5eaf711b | 36 | | Author : | Date : | |
c995fe94 ADG |
37 | +-----------------------------------------------------------------------+ |
38 | | Description : ADDI COMMON Main Module | | |
39 | +-----------------------------------------------------------------------+ | |
c995fe94 ADG |
40 | */ |
41 | ||
17d51852 HS |
42 | static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, |
43 | struct comedi_subdevice *s, | |
44 | struct comedi_insn *insn, | |
45 | unsigned int *data) | |
46 | { | |
47 | const struct addi_board *this_board = comedi_board(dev); | |
48 | struct addi_private *devpriv = dev->private; | |
49 | unsigned short w_Address = CR_CHAN(insn->chanspec); | |
50 | unsigned short w_Data; | |
51 | ||
66be78f6 | 52 | w_Data = addi_eeprom_readw(devpriv->i_IobaseAmcc, |
85c1dcba | 53 | this_board->pc_EepromChip, 2 * w_Address); |
17d51852 HS |
54 | data[0] = w_Data; |
55 | ||
56 | return insn->n; | |
57 | } | |
58 | ||
59 | static irqreturn_t v_ADDI_Interrupt(int irq, void *d) | |
60 | { | |
61 | struct comedi_device *dev = d; | |
62 | const struct addi_board *this_board = comedi_board(dev); | |
63 | ||
64 | this_board->interrupt(irq, d); | |
65 | return IRQ_RETVAL(1); | |
66 | } | |
67 | ||
68 | static int i_ADDI_Reset(struct comedi_device *dev) | |
69 | { | |
70 | const struct addi_board *this_board = comedi_board(dev); | |
71 | ||
72 | this_board->reset(dev); | |
73 | return 0; | |
74 | } | |
75 | ||
a690b7e5 | 76 | static int addi_auto_attach(struct comedi_device *dev, |
92cba8f3 | 77 | unsigned long context_unused) |
41be28db | 78 | { |
92cba8f3 | 79 | struct pci_dev *pcidev = comedi_to_pci_dev(dev); |
1f388811 | 80 | const struct addi_board *this_board = comedi_board(dev); |
843690b7 | 81 | struct addi_private *devpriv; |
34c43922 | 82 | struct comedi_subdevice *s; |
e50e2420 | 83 | int ret, n_subdevices; |
756e9d7c | 84 | unsigned int dw_Dummy; |
41be28db | 85 | |
41be28db | 86 | dev->board_name = this_board->pc_DriverName; |
c995fe94 | 87 | |
0bdab509 | 88 | devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); |
c34fa261 HS |
89 | if (!devpriv) |
90 | return -ENOMEM; | |
c995fe94 | 91 | |
818f569f | 92 | ret = comedi_pci_enable(dev); |
ef34724d HS |
93 | if (ret) |
94 | return ret; | |
c995fe94 | 95 | |
9d9cfa18 HS |
96 | if (this_board->i_IorangeBase1) |
97 | dev->iobase = pci_resource_start(pcidev, 1); | |
98 | else | |
99 | dev->iobase = pci_resource_start(pcidev, 0); | |
100 | ||
101 | devpriv->iobase = dev->iobase; | |
102 | devpriv->i_IobaseAmcc = pci_resource_start(pcidev, 0); | |
103 | devpriv->i_IobaseAddon = pci_resource_start(pcidev, 2); | |
0fcdafb8 | 104 | devpriv->i_IobaseReserved = pci_resource_start(pcidev, 3); |
c995fe94 | 105 | |
57517878 IA |
106 | /* Initialize parameters that can be overridden in EEPROM */ |
107 | devpriv->s_EeParameters.i_NbrAiChannel = this_board->i_NbrAiChannel; | |
108 | devpriv->s_EeParameters.i_NbrAoChannel = this_board->i_NbrAoChannel; | |
109 | devpriv->s_EeParameters.i_AiMaxdata = this_board->i_AiMaxdata; | |
110 | devpriv->s_EeParameters.i_AoMaxdata = this_board->i_AoMaxdata; | |
111 | devpriv->s_EeParameters.i_NbrDiChannel = this_board->i_NbrDiChannel; | |
112 | devpriv->s_EeParameters.i_NbrDoChannel = this_board->i_NbrDoChannel; | |
113 | devpriv->s_EeParameters.i_DoMaxdata = this_board->i_DoMaxdata; | |
57517878 IA |
114 | devpriv->s_EeParameters.i_Timer = this_board->i_Timer; |
115 | devpriv->s_EeParameters.ui_MinAcquisitiontimeNs = | |
116 | this_board->ui_MinAcquisitiontimeNs; | |
117 | devpriv->s_EeParameters.ui_MinDelaytimeNs = | |
118 | this_board->ui_MinDelaytimeNs; | |
119 | ||
2696fb57 | 120 | /* ## */ |
c995fe94 | 121 | |
ade6c03d HS |
122 | if (pcidev->irq > 0) { |
123 | ret = request_irq(pcidev->irq, v_ADDI_Interrupt, IRQF_SHARED, | |
41be28db | 124 | dev->board_name, dev); |
e6fee79e | 125 | if (ret == 0) |
ade6c03d | 126 | dev->irq = pcidev->irq; |
c995fe94 ADG |
127 | } |
128 | ||
2696fb57 | 129 | /* Read eepeom and fill addi_board Structure */ |
c995fe94 ADG |
130 | |
131 | if (this_board->i_PCIEeprom) { | |
c995fe94 | 132 | if (!(strcmp(this_board->pc_EepromChip, "S5920"))) { |
2696fb57 | 133 | /* Set 3 wait stait */ |
5eaf711b | 134 | if (!(strcmp(dev->board_name, "apci035"))) |
c995fe94 | 135 | outl(0x80808082, devpriv->i_IobaseAmcc + 0x60); |
5eaf711b | 136 | else |
c995fe94 | 137 | outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); |
5eaf711b | 138 | |
af02b584 | 139 | /* Enable the interrupt for the controller */ |
c995fe94 ADG |
140 | dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); |
141 | outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); | |
c995fe94 | 142 | } |
b0d11687 | 143 | addi_eeprom_read_info(dev, pci_resource_start(pcidev, 0)); |
c995fe94 ADG |
144 | } |
145 | ||
c9ab760d HS |
146 | n_subdevices = 7; |
147 | ret = comedi_alloc_subdevices(dev, n_subdevices); | |
148 | if (ret) | |
149 | return ret; | |
c995fe94 | 150 | |
c9ab760d HS |
151 | /* Allocate and Initialise AI Subdevice Structures */ |
152 | s = &dev->subdevices[0]; | |
153 | if ((devpriv->s_EeParameters.i_NbrAiChannel) | |
154 | || (this_board->i_NbrAiChannelDiff)) { | |
155 | dev->read_subdev = s; | |
156 | s->type = COMEDI_SUBD_AI; | |
157 | s->subdev_flags = | |
158 | SDF_READABLE | SDF_COMMON | SDF_GROUND | |
159 | | SDF_DIFF; | |
160 | if (devpriv->s_EeParameters.i_NbrAiChannel) { | |
161 | s->n_chan = | |
162 | devpriv->s_EeParameters.i_NbrAiChannel; | |
163 | devpriv->b_SingelDiff = 0; | |
164 | } else { | |
165 | s->n_chan = this_board->i_NbrAiChannelDiff; | |
166 | devpriv->b_SingelDiff = 1; | |
167 | } | |
168 | s->maxdata = devpriv->s_EeParameters.i_AiMaxdata; | |
169 | s->len_chanlist = this_board->i_AiChannelList; | |
170 | s->range_table = this_board->pr_AiRangelist; | |
c995fe94 | 171 | |
c9ab760d HS |
172 | s->insn_config = this_board->ai_config; |
173 | s->insn_read = this_board->ai_read; | |
174 | s->insn_write = this_board->ai_write; | |
175 | s->insn_bits = this_board->ai_bits; | |
176 | s->do_cmdtest = this_board->ai_cmdtest; | |
177 | s->do_cmd = this_board->ai_cmd; | |
178 | s->cancel = this_board->ai_cancel; | |
c995fe94 | 179 | |
c9ab760d HS |
180 | } else { |
181 | s->type = COMEDI_SUBD_UNUSED; | |
182 | } | |
c995fe94 | 183 | |
c9ab760d HS |
184 | /* Allocate and Initialise AO Subdevice Structures */ |
185 | s = &dev->subdevices[1]; | |
186 | if (devpriv->s_EeParameters.i_NbrAoChannel) { | |
187 | s->type = COMEDI_SUBD_AO; | |
188 | s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; | |
189 | s->n_chan = devpriv->s_EeParameters.i_NbrAoChannel; | |
190 | s->maxdata = devpriv->s_EeParameters.i_AoMaxdata; | |
191 | s->len_chanlist = | |
192 | devpriv->s_EeParameters.i_NbrAoChannel; | |
c9ab760d HS |
193 | s->insn_write = this_board->ao_write; |
194 | } else { | |
195 | s->type = COMEDI_SUBD_UNUSED; | |
196 | } | |
197 | /* Allocate and Initialise DI Subdevice Structures */ | |
198 | s = &dev->subdevices[2]; | |
199 | if (devpriv->s_EeParameters.i_NbrDiChannel) { | |
200 | s->type = COMEDI_SUBD_DI; | |
201 | s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON; | |
202 | s->n_chan = devpriv->s_EeParameters.i_NbrDiChannel; | |
203 | s->maxdata = 1; | |
204 | s->len_chanlist = | |
205 | devpriv->s_EeParameters.i_NbrDiChannel; | |
206 | s->range_table = &range_digital; | |
c9ab760d HS |
207 | s->insn_config = this_board->di_config; |
208 | s->insn_read = this_board->di_read; | |
209 | s->insn_write = this_board->di_write; | |
210 | s->insn_bits = this_board->di_bits; | |
211 | } else { | |
212 | s->type = COMEDI_SUBD_UNUSED; | |
213 | } | |
214 | /* Allocate and Initialise DO Subdevice Structures */ | |
215 | s = &dev->subdevices[3]; | |
216 | if (devpriv->s_EeParameters.i_NbrDoChannel) { | |
217 | s->type = COMEDI_SUBD_DO; | |
218 | s->subdev_flags = | |
219 | SDF_READABLE | SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; | |
220 | s->n_chan = devpriv->s_EeParameters.i_NbrDoChannel; | |
221 | s->maxdata = devpriv->s_EeParameters.i_DoMaxdata; | |
222 | s->len_chanlist = | |
223 | devpriv->s_EeParameters.i_NbrDoChannel; | |
224 | s->range_table = &range_digital; | |
c9ab760d HS |
225 | |
226 | /* insn_config - for digital output memory */ | |
227 | s->insn_config = this_board->do_config; | |
228 | s->insn_write = this_board->do_write; | |
229 | s->insn_bits = this_board->do_bits; | |
230 | s->insn_read = this_board->do_read; | |
231 | } else { | |
232 | s->type = COMEDI_SUBD_UNUSED; | |
233 | } | |
c995fe94 | 234 | |
c9ab760d HS |
235 | /* Allocate and Initialise Timer Subdevice Structures */ |
236 | s = &dev->subdevices[4]; | |
237 | if (devpriv->s_EeParameters.i_Timer) { | |
238 | s->type = COMEDI_SUBD_TIMER; | |
239 | s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON; | |
240 | s->n_chan = 1; | |
241 | s->maxdata = 0; | |
242 | s->len_chanlist = 1; | |
243 | s->range_table = &range_digital; | |
244 | ||
245 | s->insn_write = this_board->timer_write; | |
246 | s->insn_read = this_board->timer_read; | |
247 | s->insn_config = this_board->timer_config; | |
248 | s->insn_bits = this_board->timer_bits; | |
249 | } else { | |
250 | s->type = COMEDI_SUBD_UNUSED; | |
251 | } | |
c995fe94 | 252 | |
c9ab760d HS |
253 | /* Allocate and Initialise TTL */ |
254 | s = &dev->subdevices[5]; | |
2eb226dc | 255 | s->type = COMEDI_SUBD_UNUSED; |
c995fe94 | 256 | |
c9ab760d HS |
257 | /* EEPROM */ |
258 | s = &dev->subdevices[6]; | |
259 | if (this_board->i_PCIEeprom) { | |
260 | s->type = COMEDI_SUBD_MEMORY; | |
261 | s->subdev_flags = SDF_READABLE | SDF_INTERNAL; | |
262 | s->n_chan = 256; | |
263 | s->maxdata = 0xffff; | |
264 | s->insn_read = i_ADDIDATA_InsnReadEeprom; | |
265 | } else { | |
266 | s->type = COMEDI_SUBD_UNUSED; | |
c995fe94 ADG |
267 | } |
268 | ||
c995fe94 | 269 | i_ADDI_Reset(dev); |
c995fe94 ADG |
270 | return 0; |
271 | } | |
272 | ||
484ecc95 | 273 | static void i_ADDI_Detach(struct comedi_device *dev) |
c995fe94 | 274 | { |
843690b7 HS |
275 | struct addi_private *devpriv = dev->private; |
276 | ||
277 | if (devpriv) { | |
ae0e3b8b | 278 | if (dev->iobase) |
c995fe94 | 279 | i_ADDI_Reset(dev); |
484ecc95 | 280 | if (dev->irq) |
5f74ea14 | 281 | free_irq(dev->irq, dev); |
c995fe94 | 282 | } |
7f072f54 | 283 | comedi_pci_disable(dev); |
c995fe94 | 284 | } |