Staging: comedi: Remove COMEDI_PCI_INITCLEANUP macro
[deliverable/linux.git] / drivers / staging / comedi / drivers / amplc_dio200.c
CommitLineData
e948cb52
IA
1/*
2 comedi/drivers/amplc_dio200.c
3 Driver for Amplicon PC272E and PCI272 DIO boards.
4 (Support for other boards in Amplicon 200 series may be added at
5 a later date, e.g. PCI215.)
6
7 Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
8
9 COMEDI - Linux Control and Measurement Device Interface
10 Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27/*
28Driver: amplc_dio200
29Description: Amplicon 200 Series Digital I/O
30Author: Ian Abbott <abbotti@mev.co.uk>
31Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
32 PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e),
33 PCI272 (pci272 or amplc_dio200)
34Updated: Wed, 22 Oct 2008 13:36:02 +0100
35Status: works
36
37Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
38 [0] - I/O port base address
39 [1] - IRQ (optional, but commands won't work without it)
40
41Configuration options - PCI215, PCI272:
42 [0] - PCI bus of device (optional)
43 [1] - PCI slot of device (optional)
44 If bus/slot is not specified, the first available PCI device will
45 be used.
46
47Passing a zero for an option is the same as leaving it unspecified.
48
49SUBDEVICES
50
669c930c
BA
51 PC218E PC212E PC215E/PCI215
52 ------------- ------------- -------------
e948cb52
IA
53 Subdevices 7 6 5
54 0 CTR-X1 PPI-X PPI-X
55 1 CTR-X2 CTR-Y1 PPI-Y
56 2 CTR-Y1 CTR-Y2 CTR-Z1
57 3 CTR-Y2 CTR-Z1 CTR-Z2
58 4 CTR-Z1 CTR-Z2 INTERRUPT
59 5 CTR-Z2 INTERRUPT
60 6 INTERRUPT
61
669c930c
BA
62 PC214E PC272E/PCI272
63 ------------- -------------
e948cb52
IA
64 Subdevices 4 4
65 0 PPI-X PPI-X
66 1 PPI-Y PPI-Y
67 2 CTR-Z1* PPI-Z
68 3 INTERRUPT* INTERRUPT
69
70Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
71are configurable as inputs or outputs in four groups:
72
73 Port A - channels 0 to 7
74 Port B - channels 8 to 15
75 Port CL - channels 16 to 19
76 Port CH - channels 20 to 23
77
78Only mode 0 of the 8255 chips is supported.
79
80Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
81channel is configured individually with INSN_CONFIG instructions. The
82specific type of configuration instruction is specified in data[0].
83Some configuration instructions expect an additional parameter in
84data[1]; others return a value in data[1]. The following configuration
85instructions are supported:
86
87 INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and
88 BCD/binary setting specified in data[1].
89
90 INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
91 counter channel into data[1].
92
93 INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
94 specified in data[1] (this is a hardware-specific value). Not
95 supported on PC214E. For the other boards, valid clock sources are
96 0 to 7 as follows:
97
98 0. CLK n, the counter channel's dedicated CLK input from the SK1
669c930c
BA
99 connector. (N.B. for other values, the counter channel's CLKn
100 pin on the SK1 connector is an output!)
e948cb52
IA
101 1. Internal 10 MHz clock.
102 2. Internal 1 MHz clock.
103 3. Internal 100 kHz clock.
104 4. Internal 10 kHz clock.
105 5. Internal 1 kHz clock.
106 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
107 7. Ext Clock, the counter chip's dedicated Ext Clock input from
669c930c
BA
108 the SK1 connector. This pin is shared by all three counter
109 channels on the chip.
e948cb52
IA
110
111 INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
112 clock source in data[1]. For internal clock sources, data[2] is set
113 to the period in ns.
114
115 INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
116 specified in data[2] (this is a hardware-specific value). Not
117 supported on PC214E. For the other boards, valid gate sources are 0
118 to 7 as follows:
119
120 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
121 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
122 2. GAT n, the counter channel's dedicated GAT input from the SK1
669c930c
BA
123 connector. (N.B. for other values, the counter channel's GATn
124 pin on the SK1 connector is an output!)
e948cb52 125 3. /OUT n-2, the inverted output of counter channel n-2 (see note
669c930c 126 2 below).
e948cb52
IA
127 4. Reserved.
128 5. Reserved.
129 6. Reserved.
130 7. Reserved.
131
132 INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
133 source in data[2].
134
135Clock and gate interconnection notes:
136
137 1. Clock source OUT n-1 is the output of the preceding channel on the
138 same counter subdevice if n > 0, or the output of channel 2 on the
139 preceding counter subdevice (see note 3) if n = 0.
140
141 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
142 same counter subdevice if n = 2, or the inverted output of channel n+1
143 on the preceding counter subdevice (see note 3) if n < 2.
144
145 3. The counter subdevices are connected in a ring, so the highest
146 counter subdevice precedes the lowest.
147
148The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
149digital inputs come from the interrupt status register. The number of
150channels matches the number of interrupt sources. The PC214E does not
151have an interrupt status register; see notes on 'INTERRUPT SOURCES'
152below.
153
154INTERRUPT SOURCES
155
669c930c
BA
156 PC218E PC212E PC215E/PCI215
157 ------------- ------------- -------------
e948cb52
IA
158 Sources 6 6 6
159 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0
160 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3
161 2 CTR-Y1-OUT CTR-Y1-OUT PPI-Y-C0
162 3 CTR-Y2-OUT CTR-Y2-OUT PPI-Y-C3
163 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
164 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
165
669c930c
BA
166 PC214E PC272E/PCI272
167 ------------- -------------
e948cb52
IA
168 Sources 1 6
169 0 JUMPER-J5 PPI-X-C0
170 1 PPI-X-C3
171 2 PPI-Y-C0
172 3 PPI-Y-C3
173 4 PPI-Z-C0
174 5 PPI-Z-C3
175
176When an interrupt source is enabled in the interrupt source enable
177register, a rising edge on the source signal latches the corresponding
178bit to 1 in the interrupt status register.
179
180When the interrupt status register value as a whole (actually, just the
1816 least significant bits) goes from zero to non-zero, the board will
182generate an interrupt. For level-triggered hardware interrupts (PCI
183card), the interrupt will remain asserted until the interrupt status
184register is cleared to zero. For edge-triggered hardware interrupts
185(ISA card), no further interrupts will occur until the interrupt status
186register is cleared to zero. To clear a bit to zero in the interrupt
187status register, the corresponding interrupt source must be disabled
188in the interrupt source enable register (there is no separate interrupt
189clear register).
190
191The PC214E does not have an interrupt source enable register or an
192interrupt status register; its 'INTERRUPT' subdevice has a single
193channel and its interrupt source is selected by the position of jumper
194J5.
195
196COMMANDS
197
198The driver supports a read streaming acquisition command on the
199'INTERRUPT' subdevice. The channel list selects the interrupt sources
200to be enabled. All channels will be sampled together (convert_src ==
201TRIG_NOW). The scan begins a short time after the hardware interrupt
202occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
203scan_begin_arg == 0). The value read from the interrupt status register
790c5541 204is packed into a short value, one bit per requested channel, in the
e948cb52
IA
205order they appear in the channel list.
206*/
207
70265d24 208#include <linux/interrupt.h>
5a0e3ad6 209#include <linux/slab.h>
70265d24 210
e948cb52
IA
211#include "../comedidev.h"
212
213#include "comedi_pci.h"
214
215#include "8255.h"
216#include "8253.h"
217
218#define DIO200_DRIVER_NAME "amplc_dio200"
219
220/* PCI IDs */
6608224c 221#define PCI_VENDOR_ID_AMPLICON 0x14dc
e948cb52
IA
222#define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
223#define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
224#define PCI_DEVICE_ID_INVALID 0xffff
225
226/* 200 series registers */
227#define DIO200_IO_SIZE 0x20
228#define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */
229#define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */
230#define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */
231#define DIO200_XGAT_SCE 0x1b /* Group X gate selection register */
232#define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */
233#define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */
234#define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */
235
236/*
237 * Macros for constructing value for DIO_200_?CLK_SCE and
238 * DIO_200_?GAT_SCE registers:
239 *
240 * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
241 * 'chan' is the channel: 0, 1 or 2.
242 * 'source' is the signal source: 0 to 7.
243 */
244#define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
245#define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
246
247/*
248 * Periods of the internal clock sources in nanoseconds.
249 */
250static const unsigned clock_period[8] = {
251 0, /* dedicated clock input/output pin */
252 100, /* 10 MHz */
253 1000, /* 1 MHz */
254 10000, /* 100 kHz */
255 100000, /* 10 kHz */
256 1000000, /* 1 kHz */
257 0, /* OUT N-1 */
258 0 /* group clock input pin */
259};
260
261/*
262 * Board descriptions.
263 */
264
265enum dio200_bustype { isa_bustype, pci_bustype };
266
267enum dio200_model {
268 pc212e_model,
269 pc214e_model,
270 pc215e_model, pci215_model,
271 pc218e_model,
272 pc272e_model, pci272_model,
273 anypci_model
274};
275
276enum dio200_layout {
277 pc212_layout,
278 pc214_layout,
279 pc215_layout,
280 pc218_layout,
281 pc272_layout
282};
283
3d7a42ef 284struct dio200_board {
e948cb52
IA
285 const char *name;
286 unsigned short devid;
287 enum dio200_bustype bustype;
288 enum dio200_model model;
289 enum dio200_layout layout;
3d7a42ef 290};
e948cb52 291
3d7a42ef 292static const struct dio200_board dio200_boards[] = {
e948cb52 293 {
0a85b6f0
MT
294 .name = "pc212e",
295 .bustype = isa_bustype,
296 .model = pc212e_model,
297 .layout = pc212_layout,
298 },
e948cb52 299 {
0a85b6f0
MT
300 .name = "pc214e",
301 .bustype = isa_bustype,
302 .model = pc214e_model,
303 .layout = pc214_layout,
304 },
e948cb52 305 {
0a85b6f0
MT
306 .name = "pc215e",
307 .bustype = isa_bustype,
308 .model = pc215e_model,
309 .layout = pc215_layout,
310 },
e948cb52
IA
311#ifdef CONFIG_COMEDI_PCI
312 {
0a85b6f0
MT
313 .name = "pci215",
314 .devid = PCI_DEVICE_ID_AMPLICON_PCI215,
315 .bustype = pci_bustype,
316 .model = pci215_model,
317 .layout = pc215_layout,
318 },
e948cb52
IA
319#endif
320 {
0a85b6f0
MT
321 .name = "pc218e",
322 .bustype = isa_bustype,
323 .model = pc218e_model,
324 .layout = pc218_layout,
325 },
e948cb52 326 {
0a85b6f0
MT
327 .name = "pc272e",
328 .bustype = isa_bustype,
329 .model = pc272e_model,
330 .layout = pc272_layout,
331 },
e948cb52
IA
332#ifdef CONFIG_COMEDI_PCI
333 {
0a85b6f0
MT
334 .name = "pci272",
335 .devid = PCI_DEVICE_ID_AMPLICON_PCI272,
336 .bustype = pci_bustype,
337 .model = pci272_model,
338 .layout = pc272_layout,
339 },
e948cb52
IA
340#endif
341#ifdef CONFIG_COMEDI_PCI
342 {
0a85b6f0
MT
343 .name = DIO200_DRIVER_NAME,
344 .devid = PCI_DEVICE_ID_INVALID,
345 .bustype = pci_bustype,
346 .model = anypci_model, /* wildcard */
347 },
e948cb52
IA
348#endif
349};
350
351/*
352 * Layout descriptions - some ISA and PCI board descriptions share the same
353 * layout.
354 */
355
356enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 };
357
358#define DIO200_MAX_SUBDEVS 7
359#define DIO200_MAX_ISNS 6
360
af105ad3 361struct dio200_layout_struct {
e948cb52
IA
362 unsigned short n_subdevs; /* number of subdevices */
363 unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
364 unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
365 char has_int_sce; /* has interrupt enable/status register */
366 char has_clk_gat_sce; /* has clock/gate selection registers */
af105ad3 367};
e948cb52 368
af105ad3 369static const struct dio200_layout_struct dio200_layouts[] = {
e948cb52 370 [pc212_layout] = {
0a85b6f0
MT
371 .n_subdevs = 6,
372 .sdtype = {sd_8255, sd_8254, sd_8254, sd_8254,
373 sd_8254,
374 sd_intr},
375 .sdinfo = {0x00, 0x08, 0x0C, 0x10, 0x14,
376 0x3F},
377 .has_int_sce = 1,
378 .has_clk_gat_sce = 1,
379 },
e948cb52 380 [pc214_layout] = {
0a85b6f0
MT
381 .n_subdevs = 4,
382 .sdtype = {sd_8255, sd_8255, sd_8254,
383 sd_intr},
384 .sdinfo = {0x00, 0x08, 0x10, 0x01},
385 .has_int_sce = 0,
386 .has_clk_gat_sce = 0,
387 },
e948cb52 388 [pc215_layout] = {
0a85b6f0
MT
389 .n_subdevs = 5,
390 .sdtype = {sd_8255, sd_8255, sd_8254,
391 sd_8254,
392 sd_intr},
393 .sdinfo = {0x00, 0x08, 0x10, 0x14, 0x3F},
394 .has_int_sce = 1,
395 .has_clk_gat_sce = 1,
396 },
e948cb52 397 [pc218_layout] = {
0a85b6f0
MT
398 .n_subdevs = 7,
399 .sdtype = {sd_8254, sd_8254, sd_8255, sd_8254,
400 sd_8254,
401 sd_intr},
402 .sdinfo = {0x00, 0x04, 0x08, 0x0C, 0x10,
403 0x14,
404 0x3F},
405 .has_int_sce = 1,
406 .has_clk_gat_sce = 1,
407 },
e948cb52 408 [pc272_layout] = {
0a85b6f0
MT
409 .n_subdevs = 4,
410 .sdtype = {sd_8255, sd_8255, sd_8255,
411 sd_intr},
412 .sdinfo = {0x00, 0x08, 0x10, 0x3F},
413 .has_int_sce = 1,
414 .has_clk_gat_sce = 0,
415 },
e948cb52
IA
416};
417
418/*
419 * PCI driver table.
420 */
421
422#ifdef CONFIG_COMEDI_PCI
423static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
0a85b6f0
MT
424 {
425 PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
426 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
427 PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
428 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {
429 0}
e948cb52
IA
430};
431
432MODULE_DEVICE_TABLE(pci, dio200_pci_table);
433#endif /* CONFIG_COMEDI_PCI */
434
435/*
436 * Useful for shorthand access to the particular board structure
437 */
3d7a42ef 438#define thisboard ((const struct dio200_board *)dev->board_ptr)
669c930c
BA
439#define thislayout (&dio200_layouts[((struct dio200_board *) \
440 dev->board_ptr)->layout])
e948cb52
IA
441
442/* this structure is for data unique to this hardware driver. If
443 several hardware drivers keep similar information in this structure,
669c930c
BA
444 feel free to suggest moving the variable to the struct comedi_device struct.
445 */
692560db 446struct dio200_private {
e948cb52
IA
447#ifdef CONFIG_COMEDI_PCI
448 struct pci_dev *pci_dev; /* PCI device */
449#endif
450 int intr_sd;
692560db 451};
e948cb52 452
692560db 453#define devpriv ((struct dio200_private *)dev->private)
e948cb52 454
93ba42e9 455struct dio200_subdev_8254 {
e948cb52
IA
456 unsigned long iobase; /* Counter base address */
457 unsigned long clk_sce_iobase; /* CLK_SCE base address */
458 unsigned long gat_sce_iobase; /* GAT_SCE base address */
459 int which; /* Bit 5 of CLK_SCE or GAT_SCE */
460 int has_clk_gat_sce;
461 unsigned clock_src[3]; /* Current clock sources */
462 unsigned gate_src[3]; /* Current gate sources */
ee4063fa 463 spinlock_t spinlock;
93ba42e9 464};
e948cb52 465
d9752ee0 466struct dio200_subdev_intr {
e948cb52
IA
467 unsigned long iobase;
468 spinlock_t spinlock;
469 int active;
470 int has_int_sce;
471 unsigned int valid_isns;
472 unsigned int enabled_isns;
473 unsigned int stopcount;
474 int continuous;
d9752ee0 475};
e948cb52
IA
476
477/*
139dfbdf 478 * The struct comedi_driver structure tells the Comedi core module
e948cb52
IA
479 * which functions to call to configure/deconfigure (attach/detach)
480 * the board, and also about the kernel module that contains
481 * the device code.
482 */
0a85b6f0
MT
483static int dio200_attach(struct comedi_device *dev,
484 struct comedi_devconfig *it);
da91b269 485static int dio200_detach(struct comedi_device *dev);
139dfbdf 486static struct comedi_driver driver_amplc_dio200 = {
68c3dbff
BP
487 .driver_name = DIO200_DRIVER_NAME,
488 .module = THIS_MODULE,
489 .attach = dio200_attach,
490 .detach = dio200_detach,
491 .board_name = &dio200_boards[0].name,
492 .offset = sizeof(struct dio200_board),
8629efa4 493 .num_names = ARRAY_SIZE(dio200_boards),
e948cb52
IA
494};
495
496#ifdef CONFIG_COMEDI_PCI
727b286b
AT
497static int __devinit driver_amplc_dio200_pci_probe(struct pci_dev *dev,
498 const struct pci_device_id
499 *ent)
500{
501 return comedi_pci_auto_config(dev, driver_amplc_dio200.driver_name);
502}
503
504static void __devexit driver_amplc_dio200_pci_remove(struct pci_dev *dev)
505{
506 comedi_pci_auto_unconfig(dev);
507}
508
509static struct pci_driver driver_amplc_dio200_pci_driver = {
510 .id_table = dio200_pci_table,
511 .probe = &driver_amplc_dio200_pci_probe,
512 .remove = __devexit_p(&driver_amplc_dio200_pci_remove)
513};
514
515static int __init driver_amplc_dio200_init_module(void)
516{
517 int retval;
518
519 retval = comedi_driver_register(&driver_amplc_dio200);
520 if (retval < 0)
521 return retval;
522
523 driver_amplc_dio200_pci_driver.name =
524 (char *)driver_amplc_dio200.driver_name;
525 return pci_register_driver(&driver_amplc_dio200_pci_driver);
526}
527
528static void __exit driver_amplc_dio200_cleanup_module(void)
529{
530 pci_unregister_driver(&driver_amplc_dio200_pci_driver);
531 comedi_driver_unregister(&driver_amplc_dio200);
532}
533
534module_init(driver_amplc_dio200_init_module);
535module_exit(driver_amplc_dio200_cleanup_module);
e948cb52 536#else
7114a280
AT
537static int __init driver_amplc_dio200_init_module(void)
538{
539 return comedi_driver_register(&driver_amplc_dio200);
540}
541
542static void __exit driver_amplc_dio200_cleanup_module(void)
543{
544 comedi_driver_unregister(&driver_amplc_dio200);
545}
546
547module_init(driver_amplc_dio200_init_module);
548module_exit(driver_amplc_dio200_cleanup_module);
e948cb52
IA
549#endif
550
551/*
552 * This function looks for a PCI device matching the requested board name,
553 * bus and slot.
554 */
555#ifdef CONFIG_COMEDI_PCI
556static int
da91b269 557dio200_find_pci(struct comedi_device *dev, int bus, int slot,
0a85b6f0 558 struct pci_dev **pci_dev_p)
e948cb52
IA
559{
560 struct pci_dev *pci_dev = NULL;
561
562 *pci_dev_p = NULL;
563
564 /* Look for matching PCI device. */
565 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
0a85b6f0
MT
566 pci_dev != NULL;
567 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
568 PCI_ANY_ID, pci_dev)) {
e948cb52
IA
569 /* If bus/slot specified, check them. */
570 if (bus || slot) {
571 if (bus != pci_dev->bus->number
0a85b6f0 572 || slot != PCI_SLOT(pci_dev->devfn))
e948cb52
IA
573 continue;
574 }
575 if (thisboard->model == anypci_model) {
576 /* Match any supported model. */
577 int i;
578
579 for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
580 if (dio200_boards[i].bustype != pci_bustype)
581 continue;
582 if (pci_dev->device == dio200_boards[i].devid) {
583 /* Change board_ptr to matched board. */
584 dev->board_ptr = &dio200_boards[i];
585 break;
586 }
587 }
588 if (i == ARRAY_SIZE(dio200_boards))
589 continue;
590 } else {
591 /* Match specific model name. */
592 if (pci_dev->device != thisboard->devid)
593 continue;
594 }
595
596 /* Found a match. */
597 *pci_dev_p = pci_dev;
598 return 0;
599 }
600 /* No match found. */
601 if (bus || slot) {
602 printk(KERN_ERR
0a85b6f0
MT
603 "comedi%d: error! no %s found at pci %02x:%02x!\n",
604 dev->minor, thisboard->name, bus, slot);
e948cb52
IA
605 } else {
606 printk(KERN_ERR "comedi%d: error! no %s found!\n",
0a85b6f0 607 dev->minor, thisboard->name);
e948cb52
IA
608 }
609 return -EIO;
610}
611#endif
612
613/*
614 * This function checks and requests an I/O region, reporting an error
615 * if there is a conflict.
616 */
617static int
618dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
619{
620 if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
621 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
0a85b6f0 622 minor, from, extent);
e948cb52
IA
623 return -EIO;
624 }
625 return 0;
626}
627
628/*
629 * 'insn_bits' function for an 'INTERRUPT' subdevice.
630 */
631static int
0a85b6f0
MT
632dio200_subdev_intr_insn_bits(struct comedi_device *dev,
633 struct comedi_subdevice *s,
634 struct comedi_insn *insn, unsigned int *data)
e948cb52 635{
d9752ee0 636 struct dio200_subdev_intr *subpriv = s->private;
e948cb52
IA
637
638 if (subpriv->has_int_sce) {
639 /* Just read the interrupt status register. */
640 data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
641 } else {
642 /* No interrupt status register. */
643 data[0] = 0;
644 }
645
646 return 2;
647}
648
649/*
650 * Called to stop acquisition for an 'INTERRUPT' subdevice.
651 */
0a85b6f0
MT
652static void dio200_stop_intr(struct comedi_device *dev,
653 struct comedi_subdevice *s)
e948cb52 654{
d9752ee0 655 struct dio200_subdev_intr *subpriv = s->private;
e948cb52
IA
656
657 subpriv->active = 0;
658 subpriv->enabled_isns = 0;
669c930c 659 if (subpriv->has_int_sce)
e948cb52 660 outb(0, subpriv->iobase);
e948cb52
IA
661}
662
663/*
664 * Called to start acquisition for an 'INTERRUPT' subdevice.
665 */
0a85b6f0
MT
666static int dio200_start_intr(struct comedi_device *dev,
667 struct comedi_subdevice *s)
e948cb52
IA
668{
669 unsigned int n;
670 unsigned isn_bits;
d9752ee0 671 struct dio200_subdev_intr *subpriv = s->private;
ea6d0d4c 672 struct comedi_cmd *cmd = &s->async->cmd;
e948cb52
IA
673 int retval = 0;
674
675 if (!subpriv->continuous && subpriv->stopcount == 0) {
676 /* An empty acquisition! */
677 s->async->events |= COMEDI_CB_EOA;
678 subpriv->active = 0;
679 retval = 1;
680 } else {
681 /* Determine interrupt sources to enable. */
682 isn_bits = 0;
683 if (cmd->chanlist) {
669c930c 684 for (n = 0; n < cmd->chanlist_len; n++)
e948cb52 685 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
e948cb52
IA
686 }
687 isn_bits &= subpriv->valid_isns;
688 /* Enable interrupt sources. */
689 subpriv->enabled_isns = isn_bits;
669c930c 690 if (subpriv->has_int_sce)
e948cb52 691 outb(isn_bits, subpriv->iobase);
e948cb52
IA
692 }
693
694 return retval;
695}
696
697/*
698 * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
699 */
700static int
da91b269 701dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 702 unsigned int trignum)
e948cb52 703{
d9752ee0 704 struct dio200_subdev_intr *subpriv;
e948cb52
IA
705 unsigned long flags;
706 int event = 0;
707
708 if (trignum != 0)
709 return -EINVAL;
710
711 subpriv = s->private;
712
5f74ea14 713 spin_lock_irqsave(&subpriv->spinlock, flags);
a7f22a84 714 s->async->inttrig = NULL;
669c930c 715 if (subpriv->active)
e948cb52 716 event = dio200_start_intr(dev, s);
669c930c 717
5f74ea14 718 spin_unlock_irqrestore(&subpriv->spinlock, flags);
e948cb52 719
669c930c 720 if (event)
e948cb52 721 comedi_event(dev, s);
e948cb52
IA
722
723 return 1;
724}
725
726/*
727 * This is called from the interrupt service routine to handle a read
728 * scan on an 'INTERRUPT' subdevice.
729 */
0a85b6f0
MT
730static int dio200_handle_read_intr(struct comedi_device *dev,
731 struct comedi_subdevice *s)
e948cb52 732{
d9752ee0 733 struct dio200_subdev_intr *subpriv = s->private;
e948cb52
IA
734 unsigned triggered;
735 unsigned intstat;
736 unsigned cur_enabled;
737 unsigned int oldevents;
738 unsigned long flags;
739
740 triggered = 0;
741
5f74ea14 742 spin_lock_irqsave(&subpriv->spinlock, flags);
e948cb52
IA
743 oldevents = s->async->events;
744 if (subpriv->has_int_sce) {
745 /*
746 * Collect interrupt sources that have triggered and disable
747 * them temporarily. Loop around until no extra interrupt
748 * sources have triggered, at which point, the valid part of
749 * the interrupt status register will read zero, clearing the
750 * cause of the interrupt.
751 *
752 * Mask off interrupt sources already seen to avoid infinite
753 * loop in case of misconfiguration.
754 */
755 cur_enabled = subpriv->enabled_isns;
756 while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
0a85b6f0 757 & ~triggered)) != 0) {
e948cb52
IA
758 triggered |= intstat;
759 cur_enabled &= ~triggered;
760 outb(cur_enabled, subpriv->iobase);
761 }
762 } else {
763 /*
764 * No interrupt status register. Assume the single interrupt
765 * source has triggered.
766 */
767 triggered = subpriv->enabled_isns;
768 }
769
770 if (triggered) {
771 /*
772 * Some interrupt sources have triggered and have been
773 * temporarily disabled to clear the cause of the interrupt.
774 *
775 * Reenable them NOW to minimize the time they are disabled.
776 */
777 cur_enabled = subpriv->enabled_isns;
669c930c 778 if (subpriv->has_int_sce)
e948cb52 779 outb(cur_enabled, subpriv->iobase);
e948cb52
IA
780
781 if (subpriv->active) {
782 /*
783 * The command is still active.
784 *
785 * Ignore interrupt sources that the command isn't
786 * interested in (just in case there's a race
787 * condition).
788 */
789 if (triggered & subpriv->enabled_isns) {
790 /* Collect scan data. */
790c5541 791 short val;
e948cb52
IA
792 unsigned int n, ch, len;
793
794 val = 0;
795 len = s->async->cmd.chanlist_len;
796 for (n = 0; n < len; n++) {
797 ch = CR_CHAN(s->async->cmd.chanlist[n]);
669c930c 798 if (triggered & (1U << ch))
e948cb52 799 val |= (1U << n);
e948cb52
IA
800 }
801 /* Write the scan to the buffer. */
802 if (comedi_buf_put(s->async, val)) {
803 s->async->events |= (COMEDI_CB_BLOCK |
0a85b6f0 804 COMEDI_CB_EOS);
e948cb52
IA
805 } else {
806 /* Error! Stop acquisition. */
807 dio200_stop_intr(dev, s);
808 s->async->events |= COMEDI_CB_ERROR
0a85b6f0 809 | COMEDI_CB_OVERFLOW;
e948cb52
IA
810 comedi_error(dev, "buffer overflow");
811 }
812
813 /* Check for end of acquisition. */
814 if (!subpriv->continuous) {
815 /* stop_src == TRIG_COUNT */
816 if (subpriv->stopcount > 0) {
817 subpriv->stopcount--;
818 if (subpriv->stopcount == 0) {
819 s->async->events |=
0a85b6f0 820 COMEDI_CB_EOA;
e948cb52 821 dio200_stop_intr(dev,
0a85b6f0 822 s);
e948cb52
IA
823 }
824 }
825 }
826 }
827 }
828 }
5f74ea14 829 spin_unlock_irqrestore(&subpriv->spinlock, flags);
e948cb52 830
669c930c 831 if (oldevents != s->async->events)
e948cb52 832 comedi_event(dev, s);
e948cb52
IA
833
834 return (triggered != 0);
835}
836
837/*
838 * 'cancel' function for an 'INTERRUPT' subdevice.
839 */
0a85b6f0
MT
840static int dio200_subdev_intr_cancel(struct comedi_device *dev,
841 struct comedi_subdevice *s)
e948cb52 842{
d9752ee0 843 struct dio200_subdev_intr *subpriv = s->private;
e948cb52
IA
844 unsigned long flags;
845
5f74ea14 846 spin_lock_irqsave(&subpriv->spinlock, flags);
669c930c 847 if (subpriv->active)
e948cb52 848 dio200_stop_intr(dev, s);
669c930c 849
5f74ea14 850 spin_unlock_irqrestore(&subpriv->spinlock, flags);
e948cb52
IA
851
852 return 0;
853}
854
855/*
856 * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
857 */
858static int
0a85b6f0
MT
859dio200_subdev_intr_cmdtest(struct comedi_device *dev,
860 struct comedi_subdevice *s, struct comedi_cmd *cmd)
e948cb52
IA
861{
862 int err = 0;
863 unsigned int tmp;
864
865 /* step 1: make sure trigger sources are trivially valid */
866
867 tmp = cmd->start_src;
868 cmd->start_src &= (TRIG_NOW | TRIG_INT);
869 if (!cmd->start_src || tmp != cmd->start_src)
870 err++;
871
872 tmp = cmd->scan_begin_src;
873 cmd->scan_begin_src &= TRIG_EXT;
874 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
875 err++;
876
877 tmp = cmd->convert_src;
878 cmd->convert_src &= TRIG_NOW;
879 if (!cmd->convert_src || tmp != cmd->convert_src)
880 err++;
881
882 tmp = cmd->scan_end_src;
883 cmd->scan_end_src &= TRIG_COUNT;
884 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
885 err++;
886
887 tmp = cmd->stop_src;
888 cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
889 if (!cmd->stop_src || tmp != cmd->stop_src)
890 err++;
891
892 if (err)
893 return 1;
894
669c930c
BA
895 /* step 2: make sure trigger sources are unique and mutually
896 compatible */
e948cb52
IA
897
898 /* these tests are true if more than one _src bit is set */
899 if ((cmd->start_src & (cmd->start_src - 1)) != 0)
900 err++;
901 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
902 err++;
903 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
904 err++;
905 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
906 err++;
907 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
908 err++;
909
910 if (err)
911 return 2;
912
913 /* step 3: make sure arguments are trivially compatible */
914
915 /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
916 if (cmd->start_arg != 0) {
917 cmd->start_arg = 0;
918 err++;
919 }
920
921 /* cmd->scan_begin_src == TRIG_EXT */
922 if (cmd->scan_begin_arg != 0) {
923 cmd->scan_begin_arg = 0;
924 err++;
925 }
926
927 /* cmd->convert_src == TRIG_NOW */
928 if (cmd->convert_arg != 0) {
929 cmd->convert_arg = 0;
930 err++;
931 }
932
933 /* cmd->scan_end_src == TRIG_COUNT */
934 if (cmd->scan_end_arg != cmd->chanlist_len) {
935 cmd->scan_end_arg = cmd->chanlist_len;
936 err++;
937 }
938
939 switch (cmd->stop_src) {
940 case TRIG_COUNT:
941 /* any count allowed */
942 break;
943 case TRIG_NONE:
944 if (cmd->stop_arg != 0) {
945 cmd->stop_arg = 0;
946 err++;
947 }
948 break;
949 default:
950 break;
951 }
952
953 if (err)
954 return 3;
955
956 /* step 4: fix up any arguments */
957
958 /* if (err) return 4; */
959
960 return 0;
961}
962
963/*
964 * 'do_cmd' function for an 'INTERRUPT' subdevice.
965 */
0a85b6f0
MT
966static int dio200_subdev_intr_cmd(struct comedi_device *dev,
967 struct comedi_subdevice *s)
e948cb52 968{
ea6d0d4c 969 struct comedi_cmd *cmd = &s->async->cmd;
d9752ee0 970 struct dio200_subdev_intr *subpriv = s->private;
e948cb52
IA
971 unsigned long flags;
972 int event = 0;
973
5f74ea14 974 spin_lock_irqsave(&subpriv->spinlock, flags);
e948cb52
IA
975 subpriv->active = 1;
976
977 /* Set up end of acquisition. */
978 switch (cmd->stop_src) {
979 case TRIG_COUNT:
980 subpriv->continuous = 0;
981 subpriv->stopcount = cmd->stop_arg;
982 break;
983 default:
984 /* TRIG_NONE */
985 subpriv->continuous = 1;
986 subpriv->stopcount = 0;
987 break;
988 }
989
990 /* Set up start of acquisition. */
991 switch (cmd->start_src) {
992 case TRIG_INT:
993 s->async->inttrig = dio200_inttrig_start_intr;
994 break;
995 default:
996 /* TRIG_NOW */
997 event = dio200_start_intr(dev, s);
998 break;
999 }
5f74ea14 1000 spin_unlock_irqrestore(&subpriv->spinlock, flags);
e948cb52 1001
669c930c 1002 if (event)
e948cb52 1003 comedi_event(dev, s);
e948cb52
IA
1004
1005 return 0;
1006}
1007
1008/*
1009 * This function initializes an 'INTERRUPT' subdevice.
1010 */
1011static int
da91b269 1012dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0
MT
1013 unsigned long iobase, unsigned valid_isns,
1014 int has_int_sce)
e948cb52 1015{
d9752ee0 1016 struct dio200_subdev_intr *subpriv;
e948cb52
IA
1017
1018 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1019 if (!subpriv) {
1020 printk(KERN_ERR "comedi%d: error! out of memory!\n",
0a85b6f0 1021 dev->minor);
e948cb52
IA
1022 return -ENOMEM;
1023 }
1024 subpriv->iobase = iobase;
1025 subpriv->has_int_sce = has_int_sce;
1026 subpriv->valid_isns = valid_isns;
1027 spin_lock_init(&subpriv->spinlock);
1028
669c930c 1029 if (has_int_sce)
e948cb52 1030 outb(0, subpriv->iobase); /* Disable interrupt sources. */
e948cb52
IA
1031
1032 s->private = subpriv;
1033 s->type = COMEDI_SUBD_DI;
1034 s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
1035 if (has_int_sce) {
1036 s->n_chan = DIO200_MAX_ISNS;
1037 s->len_chanlist = DIO200_MAX_ISNS;
1038 } else {
1039 /* No interrupt source register. Support single channel. */
1040 s->n_chan = 1;
1041 s->len_chanlist = 1;
1042 }
1043 s->range_table = &range_digital;
1044 s->maxdata = 1;
1045 s->insn_bits = dio200_subdev_intr_insn_bits;
1046 s->do_cmdtest = dio200_subdev_intr_cmdtest;
1047 s->do_cmd = dio200_subdev_intr_cmd;
1048 s->cancel = dio200_subdev_intr_cancel;
1049
1050 return 0;
1051}
1052
1053/*
1054 * This function cleans up an 'INTERRUPT' subdevice.
1055 */
1056static void
0a85b6f0
MT
1057dio200_subdev_intr_cleanup(struct comedi_device *dev,
1058 struct comedi_subdevice *s)
e948cb52 1059{
d9752ee0 1060 struct dio200_subdev_intr *subpriv = s->private;
669c930c 1061 kfree(subpriv);
e948cb52
IA
1062}
1063
1064/*
1065 * Interrupt service routine.
1066 */
70265d24 1067static irqreturn_t dio200_interrupt(int irq, void *d)
e948cb52 1068{
71b5f4f1 1069 struct comedi_device *dev = d;
e948cb52
IA
1070 int handled;
1071
669c930c 1072 if (!dev->attached)
e948cb52 1073 return IRQ_NONE;
e948cb52
IA
1074
1075 if (devpriv->intr_sd >= 0) {
1076 handled = dio200_handle_read_intr(dev,
0a85b6f0
MT
1077 dev->subdevices +
1078 devpriv->intr_sd);
e948cb52
IA
1079 } else {
1080 handled = 0;
1081 }
1082
1083 return IRQ_RETVAL(handled);
1084}
1085
1086/*
1087 * Handle 'insn_read' for an '8254' counter subdevice.
1088 */
1089static int
da91b269 1090dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 1091 struct comedi_insn *insn, unsigned int *data)
e948cb52 1092{
93ba42e9 1093 struct dio200_subdev_8254 *subpriv = s->private;
e948cb52 1094 int chan = CR_CHAN(insn->chanspec);
ee4063fa 1095 unsigned long flags;
e948cb52 1096
ee4063fa 1097 spin_lock_irqsave(&subpriv->spinlock, flags);
e948cb52 1098 data[0] = i8254_read(subpriv->iobase, 0, chan);
ee4063fa 1099 spin_unlock_irqrestore(&subpriv->spinlock, flags);
e948cb52
IA
1100
1101 return 1;
1102}
1103
1104/*
1105 * Handle 'insn_write' for an '8254' counter subdevice.
1106 */
1107static int
da91b269 1108dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 1109 struct comedi_insn *insn, unsigned int *data)
e948cb52 1110{
93ba42e9 1111 struct dio200_subdev_8254 *subpriv = s->private;
e948cb52 1112 int chan = CR_CHAN(insn->chanspec);
ee4063fa 1113 unsigned long flags;
e948cb52 1114
ee4063fa 1115 spin_lock_irqsave(&subpriv->spinlock, flags);
e948cb52 1116 i8254_write(subpriv->iobase, 0, chan, data[0]);
ee4063fa 1117 spin_unlock_irqrestore(&subpriv->spinlock, flags);
e948cb52
IA
1118
1119 return 1;
1120}
1121
1122/*
1123 * Set gate source for an '8254' counter subdevice channel.
1124 */
1125static int
0a85b6f0
MT
1126dio200_set_gate_src(struct dio200_subdev_8254 *subpriv,
1127 unsigned int counter_number, unsigned int gate_src)
e948cb52
IA
1128{
1129 unsigned char byte;
1130
1131 if (!subpriv->has_clk_gat_sce)
1132 return -1;
1133 if (counter_number > 2)
1134 return -1;
1135 if (gate_src > 7)
1136 return -1;
1137
1138 subpriv->gate_src[counter_number] = gate_src;
1139 byte = GAT_SCE(subpriv->which, counter_number, gate_src);
1140 outb(byte, subpriv->gat_sce_iobase);
1141
1142 return 0;
1143}
1144
1145/*
1146 * Get gate source for an '8254' counter subdevice channel.
1147 */
1148static int
0a85b6f0
MT
1149dio200_get_gate_src(struct dio200_subdev_8254 *subpriv,
1150 unsigned int counter_number)
e948cb52
IA
1151{
1152 if (!subpriv->has_clk_gat_sce)
1153 return -1;
1154 if (counter_number > 2)
1155 return -1;
1156
1157 return subpriv->gate_src[counter_number];
1158}
1159
1160/*
1161 * Set clock source for an '8254' counter subdevice channel.
1162 */
1163static int
0a85b6f0
MT
1164dio200_set_clock_src(struct dio200_subdev_8254 *subpriv,
1165 unsigned int counter_number, unsigned int clock_src)
e948cb52
IA
1166{
1167 unsigned char byte;
1168
1169 if (!subpriv->has_clk_gat_sce)
1170 return -1;
1171 if (counter_number > 2)
1172 return -1;
1173 if (clock_src > 7)
1174 return -1;
1175
1176 subpriv->clock_src[counter_number] = clock_src;
1177 byte = CLK_SCE(subpriv->which, counter_number, clock_src);
1178 outb(byte, subpriv->clk_sce_iobase);
1179
1180 return 0;
1181}
1182
1183/*
1184 * Get clock source for an '8254' counter subdevice channel.
1185 */
1186static int
0a85b6f0
MT
1187dio200_get_clock_src(struct dio200_subdev_8254 *subpriv,
1188 unsigned int counter_number, unsigned int *period_ns)
e948cb52
IA
1189{
1190 unsigned clock_src;
1191
1192 if (!subpriv->has_clk_gat_sce)
1193 return -1;
1194 if (counter_number > 2)
1195 return -1;
1196
1197 clock_src = subpriv->clock_src[counter_number];
1198 *period_ns = clock_period[clock_src];
1199 return clock_src;
1200}
1201
1202/*
1203 * Handle 'insn_config' for an '8254' counter subdevice.
1204 */
1205static int
da91b269 1206dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0 1207 struct comedi_insn *insn, unsigned int *data)
e948cb52 1208{
93ba42e9 1209 struct dio200_subdev_8254 *subpriv = s->private;
ee4063fa 1210 int ret = 0;
e948cb52 1211 int chan = CR_CHAN(insn->chanspec);
ee4063fa 1212 unsigned long flags;
e948cb52 1213
ee4063fa 1214 spin_lock_irqsave(&subpriv->spinlock, flags);
e948cb52
IA
1215 switch (data[0]) {
1216 case INSN_CONFIG_SET_COUNTER_MODE:
1217 ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
1218 if (ret < 0)
ee4063fa 1219 ret = -EINVAL;
e948cb52
IA
1220 break;
1221 case INSN_CONFIG_8254_READ_STATUS:
1222 data[1] = i8254_status(subpriv->iobase, 0, chan);
1223 break;
1224 case INSN_CONFIG_SET_GATE_SRC:
1225 ret = dio200_set_gate_src(subpriv, chan, data[2]);
1226 if (ret < 0)
ee4063fa 1227 ret = -EINVAL;
e948cb52
IA
1228 break;
1229 case INSN_CONFIG_GET_GATE_SRC:
1230 ret = dio200_get_gate_src(subpriv, chan);
ee4063fa
IA
1231 if (ret < 0) {
1232 ret = -EINVAL;
1233 break;
1234 }
e948cb52
IA
1235 data[2] = ret;
1236 break;
1237 case INSN_CONFIG_SET_CLOCK_SRC:
1238 ret = dio200_set_clock_src(subpriv, chan, data[1]);
1239 if (ret < 0)
ee4063fa 1240 ret = -EINVAL;
e948cb52
IA
1241 break;
1242 case INSN_CONFIG_GET_CLOCK_SRC:
1243 ret = dio200_get_clock_src(subpriv, chan, &data[2]);
ee4063fa
IA
1244 if (ret < 0) {
1245 ret = -EINVAL;
1246 break;
1247 }
e948cb52
IA
1248 data[1] = ret;
1249 break;
1250 default:
ee4063fa 1251 ret = -EINVAL;
e948cb52
IA
1252 break;
1253 }
ee4063fa
IA
1254 spin_unlock_irqrestore(&subpriv->spinlock, flags);
1255 return ret < 0 ? ret : insn->n;
e948cb52
IA
1256}
1257
1258/*
1259 * This function initializes an '8254' counter subdevice.
1260 *
1261 * Note: iobase is the base address of the board, not the subdevice;
1262 * offset is the offset to the 8254 chip.
1263 */
1264static int
da91b269 1265dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s,
0a85b6f0
MT
1266 unsigned long iobase, unsigned offset,
1267 int has_clk_gat_sce)
e948cb52 1268{
93ba42e9 1269 struct dio200_subdev_8254 *subpriv;
e948cb52
IA
1270 unsigned int chan;
1271
1272 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
1273 if (!subpriv) {
1274 printk(KERN_ERR "comedi%d: error! out of memory!\n",
0a85b6f0 1275 dev->minor);
e948cb52
IA
1276 return -ENOMEM;
1277 }
1278
1279 s->private = subpriv;
1280 s->type = COMEDI_SUBD_COUNTER;
1281 s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
1282 s->n_chan = 3;
1283 s->maxdata = 0xFFFF;
1284 s->insn_read = dio200_subdev_8254_read;
1285 s->insn_write = dio200_subdev_8254_write;
1286 s->insn_config = dio200_subdev_8254_config;
1287
ee4063fa 1288 spin_lock_init(&subpriv->spinlock);
e948cb52
IA
1289 subpriv->iobase = offset + iobase;
1290 subpriv->has_clk_gat_sce = has_clk_gat_sce;
1291 if (has_clk_gat_sce) {
1292 /* Derive CLK_SCE and GAT_SCE register offsets from
1293 * 8254 offset. */
1294 subpriv->clk_sce_iobase =
0a85b6f0 1295 DIO200_XCLK_SCE + (offset >> 3) + iobase;
e948cb52 1296 subpriv->gat_sce_iobase =
0a85b6f0 1297 DIO200_XGAT_SCE + (offset >> 3) + iobase;
e948cb52
IA
1298 subpriv->which = (offset >> 2) & 1;
1299 }
1300
1301 /* Initialize channels. */
1302 for (chan = 0; chan < 3; chan++) {
1303 i8254_set_mode(subpriv->iobase, 0, chan,
0a85b6f0 1304 I8254_MODE0 | I8254_BINARY);
e948cb52
IA
1305 if (subpriv->has_clk_gat_sce) {
1306 /* Gate source 0 is VCC (logic 1). */
1307 dio200_set_gate_src(subpriv, chan, 0);
1308 /* Clock source 0 is the dedicated clock input. */
1309 dio200_set_clock_src(subpriv, chan, 0);
1310 }
1311 }
1312
1313 return 0;
1314}
1315
1316/*
1317 * This function cleans up an '8254' counter subdevice.
1318 */
1319static void
0a85b6f0
MT
1320dio200_subdev_8254_cleanup(struct comedi_device *dev,
1321 struct comedi_subdevice *s)
e948cb52 1322{
d9752ee0 1323 struct dio200_subdev_intr *subpriv = s->private;
669c930c 1324 kfree(subpriv);
e948cb52
IA
1325}
1326
1327/*
1328 * Attach is called by the Comedi core to configure the driver
1329 * for a particular board. If you specified a board_name array
1330 * in the driver structure, dev->board_ptr contains that
1331 * address.
1332 */
da91b269 1333static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it)
e948cb52 1334{
34c43922 1335 struct comedi_subdevice *s;
e948cb52
IA
1336 unsigned long iobase = 0;
1337 unsigned int irq = 0;
1338#ifdef CONFIG_COMEDI_PCI
1339 struct pci_dev *pci_dev = NULL;
1340 int bus = 0, slot = 0;
1341#endif
af105ad3 1342 const struct dio200_layout_struct *layout;
e948cb52
IA
1343 int share_irq = 0;
1344 int sdx;
1345 unsigned n;
1346 int ret;
1347
1348 printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
0a85b6f0 1349 DIO200_DRIVER_NAME);
e948cb52 1350
c3744138
BP
1351 ret = alloc_private(dev, sizeof(struct dio200_private));
1352 if (ret < 0) {
e948cb52 1353 printk(KERN_ERR "comedi%d: error! out of memory!\n",
0a85b6f0 1354 dev->minor);
e948cb52
IA
1355 return ret;
1356 }
1357
1358 /* Process options. */
1359 switch (thisboard->bustype) {
1360 case isa_bustype:
1361 iobase = it->options[0];
1362 irq = it->options[1];
1363 share_irq = 0;
1364 break;
1365#ifdef CONFIG_COMEDI_PCI
1366 case pci_bustype:
1367 bus = it->options[0];
1368 slot = it->options[1];
1369 share_irq = 1;
1370
c3744138
BP
1371 ret = dio200_find_pci(dev, bus, slot, &pci_dev);
1372 if (ret < 0)
e948cb52
IA
1373 return ret;
1374 devpriv->pci_dev = pci_dev;
1375 break;
1376#endif
1377 default:
1378 printk(KERN_ERR
0a85b6f0
MT
1379 "comedi%d: %s: BUG! cannot determine board type!\n",
1380 dev->minor, DIO200_DRIVER_NAME);
e948cb52
IA
1381 return -EINVAL;
1382 break;
1383 }
1384
1385 devpriv->intr_sd = -1;
1386
1387 /* Enable device and reserve I/O spaces. */
1388#ifdef CONFIG_COMEDI_PCI
1389 if (pci_dev) {
1390 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
1391 if (ret < 0) {
1392 printk(KERN_ERR
0a85b6f0
MT
1393 "comedi%d: error! cannot enable PCI device and request regions!\n",
1394 dev->minor);
e948cb52
IA
1395 return ret;
1396 }
1397 iobase = pci_resource_start(pci_dev, 2);
1398 irq = pci_dev->irq;
1399 } else
1400#endif
1401 {
1402 ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
669c930c 1403 if (ret < 0)
e948cb52 1404 return ret;
e948cb52
IA
1405 }
1406 dev->iobase = iobase;
1407
1408 layout = thislayout;
c3744138
BP
1409
1410 ret = alloc_subdevices(dev, layout->n_subdevs);
1411 if (ret < 0) {
e948cb52 1412 printk(KERN_ERR "comedi%d: error! out of memory!\n",
0a85b6f0 1413 dev->minor);
e948cb52
IA
1414 return ret;
1415 }
1416
1417 for (n = 0; n < dev->n_subdevices; n++) {
1418 s = &dev->subdevices[n];
1419 switch (layout->sdtype[n]) {
1420 case sd_8254:
1421 /* counter subdevice (8254) */
1422 ret = dio200_subdev_8254_init(dev, s, iobase,
0a85b6f0
MT
1423 layout->sdinfo[n],
1424 layout->has_clk_gat_sce);
669c930c 1425 if (ret < 0)
e948cb52 1426 return ret;
669c930c 1427
e948cb52
IA
1428 break;
1429 case sd_8255:
1430 /* digital i/o subdevice (8255) */
a7f22a84 1431 ret = subdev_8255_init(dev, s, NULL,
0a85b6f0 1432 iobase + layout->sdinfo[n]);
669c930c 1433 if (ret < 0)
e948cb52 1434 return ret;
669c930c 1435
e948cb52
IA
1436 break;
1437 case sd_intr:
1438 /* 'INTERRUPT' subdevice */
1439 if (irq) {
1440 ret = dio200_subdev_intr_init(dev, s,
0a85b6f0
MT
1441 iobase +
1442 DIO200_INT_SCE,
1443 layout->sdinfo[n],
1444 layout->
1445 has_int_sce);
669c930c 1446 if (ret < 0)
e948cb52 1447 return ret;
669c930c 1448
e948cb52
IA
1449 devpriv->intr_sd = n;
1450 } else {
1451 s->type = COMEDI_SUBD_UNUSED;
1452 }
1453 break;
1454 default:
1455 s->type = COMEDI_SUBD_UNUSED;
1456 break;
1457 }
1458 }
1459
1460 sdx = devpriv->intr_sd;
669c930c 1461 if (sdx >= 0 && sdx < dev->n_subdevices)
e948cb52 1462 dev->read_subdev = &dev->subdevices[sdx];
e948cb52
IA
1463
1464 dev->board_name = thisboard->name;
1465
1466 if (irq) {
1467 unsigned long flags = share_irq ? IRQF_SHARED : 0;
1468
5f74ea14 1469 if (request_irq(irq, dio200_interrupt, flags,
e948cb52
IA
1470 DIO200_DRIVER_NAME, dev) >= 0) {
1471 dev->irq = irq;
1472 } else {
1473 printk(KERN_WARNING
0a85b6f0
MT
1474 "comedi%d: warning! irq %u unavailable!\n",
1475 dev->minor, irq);
e948cb52
IA
1476 }
1477 }
1478
1479 printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
1480 if (thisboard->bustype == isa_bustype) {
1481 printk("(base %#lx) ", iobase);
1482 } else {
1483#ifdef CONFIG_COMEDI_PCI
1484 printk("(pci %s) ", pci_name(pci_dev));
1485#endif
1486 }
669c930c 1487 if (irq)
e948cb52 1488 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
669c930c 1489 else
e948cb52 1490 printk("(no irq) ");
e948cb52
IA
1491
1492 printk("attached\n");
1493
1494 return 1;
1495}
1496
1497/*
1498 * _detach is called to deconfigure a device. It should deallocate
1499 * resources.
1500 * This function is also called when _attach() fails, so it should be
1501 * careful not to release resources that were not necessarily
1502 * allocated by _attach(). dev->private and dev->subdevices are
1503 * deallocated automatically by the core.
1504 */
da91b269 1505static int dio200_detach(struct comedi_device *dev)
e948cb52 1506{
af105ad3 1507 const struct dio200_layout_struct *layout;
e948cb52
IA
1508 unsigned n;
1509
1510 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
0a85b6f0 1511 DIO200_DRIVER_NAME);
e948cb52 1512
669c930c 1513 if (dev->irq)
5f74ea14 1514 free_irq(dev->irq, dev);
e948cb52
IA
1515 if (dev->subdevices) {
1516 layout = thislayout;
1517 for (n = 0; n < dev->n_subdevices; n++) {
34c43922 1518 struct comedi_subdevice *s = &dev->subdevices[n];
e948cb52
IA
1519 switch (layout->sdtype[n]) {
1520 case sd_8254:
1521 dio200_subdev_8254_cleanup(dev, s);
1522 break;
1523 case sd_8255:
1524 subdev_8255_cleanup(dev, s);
1525 break;
1526 case sd_intr:
1527 dio200_subdev_intr_cleanup(dev, s);
1528 break;
1529 default:
1530 break;
1531 }
1532 }
1533 }
1534 if (devpriv) {
1535#ifdef CONFIG_COMEDI_PCI
1536 if (devpriv->pci_dev) {
669c930c 1537 if (dev->iobase)
e948cb52 1538 comedi_pci_disable(devpriv->pci_dev);
e948cb52
IA
1539 pci_dev_put(devpriv->pci_dev);
1540 } else
1541#endif
1542 {
669c930c 1543 if (dev->iobase)
e948cb52 1544 release_region(dev->iobase, DIO200_IO_SIZE);
e948cb52
IA
1545 }
1546 }
669c930c 1547 if (dev->board_name)
e948cb52 1548 printk(KERN_INFO "comedi%d: %s removed\n",
0a85b6f0 1549 dev->minor, dev->board_name);
e948cb52
IA
1550
1551 return 0;
1552}
90f703d3
AT
1553
1554MODULE_AUTHOR("Comedi http://www.comedi.org");
1555MODULE_DESCRIPTION("Comedi low-level driver");
1556MODULE_LICENSE("GPL");
This page took 0.227501 seconds and 5 git commands to generate.