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 51 PC218E PC212E PC215E/PCI215 52 ------------- ------------- ------------- 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 62 PC214E PC272E/PCI272 63 ------------- ------------- 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 99 connector. (N.B. for other values, the counter channel's CLKn 100 pin on the SK1 connector is an output!) 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 108 the SK1 connector. This pin is shared by all three counter 109 channels on the chip. 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 123 connector. (N.B. for other values, the counter channel's GATn 124 pin on the SK1 connector is an output!) 125 3. /OUT n-2, the inverted output of counter channel n-2 (see note 126 2 below). 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 156 PC218E PC212E PC215E/PCI215 157 ------------- ------------- ------------- 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 166 PC214E PC272E/PCI272 167 ------------- ------------- 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 204is packed into a short value, one bit per requested channel, in the 205order they appear in the channel list. 206*/ 207 208#include <linux/interrupt.h> 209#include <linux/slab.h> 210 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 */ 221#define PCI_VENDOR_ID_AMPLICON 0x14dc 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 284struct dio200_board { 285 const char *name; 286 unsigned short devid; 287 enum dio200_bustype bustype; 288 enum dio200_model model; 289 enum dio200_layout layout; 290}; 291 292static const struct dio200_board dio200_boards[] = { 293 { 294 .name = "pc212e", 295 .bustype = isa_bustype, 296 .model = pc212e_model, 297 .layout = pc212_layout, 298 }, 299 { 300 .name = "pc214e", 301 .bustype = isa_bustype, 302 .model = pc214e_model, 303 .layout = pc214_layout, 304 }, 305 { 306 .name = "pc215e", 307 .bustype = isa_bustype, 308 .model = pc215e_model, 309 .layout = pc215_layout, 310 }, 311#ifdef CONFIG_COMEDI_PCI 312 { 313 .name = "pci215", 314 .devid = PCI_DEVICE_ID_AMPLICON_PCI215, 315 .bustype = pci_bustype, 316 .model = pci215_model, 317 .layout = pc215_layout, 318 }, 319#endif 320 { 321 .name = "pc218e", 322 .bustype = isa_bustype, 323 .model = pc218e_model, 324 .layout = pc218_layout, 325 }, 326 { 327 .name = "pc272e", 328 .bustype = isa_bustype, 329 .model = pc272e_model, 330 .layout = pc272_layout, 331 }, 332#ifdef CONFIG_COMEDI_PCI 333 { 334 .name = "pci272", 335 .devid = PCI_DEVICE_ID_AMPLICON_PCI272, 336 .bustype = pci_bustype, 337 .model = pci272_model, 338 .layout = pc272_layout, 339 }, 340#endif 341#ifdef CONFIG_COMEDI_PCI 342 { 343 .name = DIO200_DRIVER_NAME, 344 .devid = PCI_DEVICE_ID_INVALID, 345 .bustype = pci_bustype, 346 .model = anypci_model, /* wildcard */ 347 }, 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 361struct dio200_layout_struct { 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 */ 367}; 368 369static const struct dio200_layout_struct dio200_layouts[] = { 370 [pc212_layout] = { 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 }, 380 [pc214_layout] = { 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 }, 388 [pc215_layout] = { 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 }, 397 [pc218_layout] = { 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 }, 408 [pc272_layout] = { 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 }, 416}; 417 418/* 419 * PCI driver table. 420 */ 421 422#ifdef CONFIG_COMEDI_PCI 423static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = { 424 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215) }, 425 { PCI_DEVICE(PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272) }, 426 {0} 427}; 428 429MODULE_DEVICE_TABLE(pci, dio200_pci_table); 430#endif /* CONFIG_COMEDI_PCI */ 431 432/* 433 * Useful for shorthand access to the particular board structure 434 */ 435#define thisboard ((const struct dio200_board *)dev->board_ptr) 436#define thislayout (&dio200_layouts[((struct dio200_board *) \ 437 dev->board_ptr)->layout]) 438 439/* this structure is for data unique to this hardware driver. If 440 several hardware drivers keep similar information in this structure, 441 feel free to suggest moving the variable to the struct comedi_device struct. 442 */ 443struct dio200_private { 444#ifdef CONFIG_COMEDI_PCI 445 struct pci_dev *pci_dev; /* PCI device */ 446#endif 447 int intr_sd; 448}; 449 450#define devpriv ((struct dio200_private *)dev->private) 451 452struct dio200_subdev_8254 { 453 unsigned long iobase; /* Counter base address */ 454 unsigned long clk_sce_iobase; /* CLK_SCE base address */ 455 unsigned long gat_sce_iobase; /* GAT_SCE base address */ 456 int which; /* Bit 5 of CLK_SCE or GAT_SCE */ 457 int has_clk_gat_sce; 458 unsigned clock_src[3]; /* Current clock sources */ 459 unsigned gate_src[3]; /* Current gate sources */ 460 spinlock_t spinlock; 461}; 462 463struct dio200_subdev_intr { 464 unsigned long iobase; 465 spinlock_t spinlock; 466 int active; 467 int has_int_sce; 468 unsigned int valid_isns; 469 unsigned int enabled_isns; 470 unsigned int stopcount; 471 int continuous; 472}; 473 474/* 475 * The struct comedi_driver structure tells the Comedi core module 476 * which functions to call to configure/deconfigure (attach/detach) 477 * the board, and also about the kernel module that contains 478 * the device code. 479 */ 480static int dio200_attach(struct comedi_device *dev, 481 struct comedi_devconfig *it); 482static int dio200_detach(struct comedi_device *dev); 483static struct comedi_driver driver_amplc_dio200 = { 484 .driver_name = DIO200_DRIVER_NAME, 485 .module = THIS_MODULE, 486 .attach = dio200_attach, 487 .detach = dio200_detach, 488 .board_name = &dio200_boards[0].name, 489 .offset = sizeof(struct dio200_board), 490 .num_names = ARRAY_SIZE(dio200_boards), 491}; 492 493#ifdef CONFIG_COMEDI_PCI 494static int __devinit driver_amplc_dio200_pci_probe(struct pci_dev *dev, 495 const struct pci_device_id 496 *ent) 497{ 498 return comedi_pci_auto_config(dev, driver_amplc_dio200.driver_name); 499} 500 501static void __devexit driver_amplc_dio200_pci_remove(struct pci_dev *dev) 502{ 503 comedi_pci_auto_unconfig(dev); 504} 505 506static struct pci_driver driver_amplc_dio200_pci_driver = { 507 .id_table = dio200_pci_table, 508 .probe = &driver_amplc_dio200_pci_probe, 509 .remove = __devexit_p(&driver_amplc_dio200_pci_remove) 510}; 511 512static int __init driver_amplc_dio200_init_module(void) 513{ 514 int retval; 515 516 retval = comedi_driver_register(&driver_amplc_dio200); 517 if (retval < 0) 518 return retval; 519 520 driver_amplc_dio200_pci_driver.name = 521 (char *)driver_amplc_dio200.driver_name; 522 return pci_register_driver(&driver_amplc_dio200_pci_driver); 523} 524 525static void __exit driver_amplc_dio200_cleanup_module(void) 526{ 527 pci_unregister_driver(&driver_amplc_dio200_pci_driver); 528 comedi_driver_unregister(&driver_amplc_dio200); 529} 530 531module_init(driver_amplc_dio200_init_module); 532module_exit(driver_amplc_dio200_cleanup_module); 533#else 534static int __init driver_amplc_dio200_init_module(void) 535{ 536 return comedi_driver_register(&driver_amplc_dio200); 537} 538 539static void __exit driver_amplc_dio200_cleanup_module(void) 540{ 541 comedi_driver_unregister(&driver_amplc_dio200); 542} 543 544module_init(driver_amplc_dio200_init_module); 545module_exit(driver_amplc_dio200_cleanup_module); 546#endif 547 548/* 549 * This function looks for a PCI device matching the requested board name, 550 * bus and slot. 551 */ 552#ifdef CONFIG_COMEDI_PCI 553static int 554dio200_find_pci(struct comedi_device *dev, int bus, int slot, 555 struct pci_dev **pci_dev_p) 556{ 557 struct pci_dev *pci_dev = NULL; 558 559 *pci_dev_p = NULL; 560 561 /* Look for matching PCI device. */ 562 for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL); 563 pci_dev != NULL; 564 pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, 565 PCI_ANY_ID, pci_dev)) { 566 /* If bus/slot specified, check them. */ 567 if (bus || slot) { 568 if (bus != pci_dev->bus->number 569 || slot != PCI_SLOT(pci_dev->devfn)) 570 continue; 571 } 572 if (thisboard->model == anypci_model) { 573 /* Match any supported model. */ 574 int i; 575 576 for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) { 577 if (dio200_boards[i].bustype != pci_bustype) 578 continue; 579 if (pci_dev->device == dio200_boards[i].devid) { 580 /* Change board_ptr to matched board. */ 581 dev->board_ptr = &dio200_boards[i]; 582 break; 583 } 584 } 585 if (i == ARRAY_SIZE(dio200_boards)) 586 continue; 587 } else { 588 /* Match specific model name. */ 589 if (pci_dev->device != thisboard->devid) 590 continue; 591 } 592 593 /* Found a match. */ 594 *pci_dev_p = pci_dev; 595 return 0; 596 } 597 /* No match found. */ 598 if (bus || slot) { 599 printk(KERN_ERR 600 "comedi%d: error! no %s found at pci %02x:%02x!\n", 601 dev->minor, thisboard->name, bus, slot); 602 } else { 603 printk(KERN_ERR "comedi%d: error! no %s found!\n", 604 dev->minor, thisboard->name); 605 } 606 return -EIO; 607} 608#endif 609 610/* 611 * This function checks and requests an I/O region, reporting an error 612 * if there is a conflict. 613 */ 614static int 615dio200_request_region(unsigned minor, unsigned long from, unsigned long extent) 616{ 617 if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) { 618 printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n", 619 minor, from, extent); 620 return -EIO; 621 } 622 return 0; 623} 624 625/* 626 * 'insn_bits' function for an 'INTERRUPT' subdevice. 627 */ 628static int 629dio200_subdev_intr_insn_bits(struct comedi_device *dev, 630 struct comedi_subdevice *s, 631 struct comedi_insn *insn, unsigned int *data) 632{ 633 struct dio200_subdev_intr *subpriv = s->private; 634 635 if (subpriv->has_int_sce) { 636 /* Just read the interrupt status register. */ 637 data[1] = inb(subpriv->iobase) & subpriv->valid_isns; 638 } else { 639 /* No interrupt status register. */ 640 data[0] = 0; 641 } 642 643 return 2; 644} 645 646/* 647 * Called to stop acquisition for an 'INTERRUPT' subdevice. 648 */ 649static void dio200_stop_intr(struct comedi_device *dev, 650 struct comedi_subdevice *s) 651{ 652 struct dio200_subdev_intr *subpriv = s->private; 653 654 subpriv->active = 0; 655 subpriv->enabled_isns = 0; 656 if (subpriv->has_int_sce) 657 outb(0, subpriv->iobase); 658} 659 660/* 661 * Called to start acquisition for an 'INTERRUPT' subdevice. 662 */ 663static int dio200_start_intr(struct comedi_device *dev, 664 struct comedi_subdevice *s) 665{ 666 unsigned int n; 667 unsigned isn_bits; 668 struct dio200_subdev_intr *subpriv = s->private; 669 struct comedi_cmd *cmd = &s->async->cmd; 670 int retval = 0; 671 672 if (!subpriv->continuous && subpriv->stopcount == 0) { 673 /* An empty acquisition! */ 674 s->async->events |= COMEDI_CB_EOA; 675 subpriv->active = 0; 676 retval = 1; 677 } else { 678 /* Determine interrupt sources to enable. */ 679 isn_bits = 0; 680 if (cmd->chanlist) { 681 for (n = 0; n < cmd->chanlist_len; n++) 682 isn_bits |= (1U << CR_CHAN(cmd->chanlist[n])); 683 } 684 isn_bits &= subpriv->valid_isns; 685 /* Enable interrupt sources. */ 686 subpriv->enabled_isns = isn_bits; 687 if (subpriv->has_int_sce) 688 outb(isn_bits, subpriv->iobase); 689 } 690 691 return retval; 692} 693 694/* 695 * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice. 696 */ 697static int 698dio200_inttrig_start_intr(struct comedi_device *dev, struct comedi_subdevice *s, 699 unsigned int trignum) 700{ 701 struct dio200_subdev_intr *subpriv; 702 unsigned long flags; 703 int event = 0; 704 705 if (trignum != 0) 706 return -EINVAL; 707 708 subpriv = s->private; 709 710 spin_lock_irqsave(&subpriv->spinlock, flags); 711 s->async->inttrig = NULL; 712 if (subpriv->active) 713 event = dio200_start_intr(dev, s); 714 715 spin_unlock_irqrestore(&subpriv->spinlock, flags); 716 717 if (event) 718 comedi_event(dev, s); 719 720 return 1; 721} 722 723/* 724 * This is called from the interrupt service routine to handle a read 725 * scan on an 'INTERRUPT' subdevice. 726 */ 727static int dio200_handle_read_intr(struct comedi_device *dev, 728 struct comedi_subdevice *s) 729{ 730 struct dio200_subdev_intr *subpriv = s->private; 731 unsigned triggered; 732 unsigned intstat; 733 unsigned cur_enabled; 734 unsigned int oldevents; 735 unsigned long flags; 736 737 triggered = 0; 738 739 spin_lock_irqsave(&subpriv->spinlock, flags); 740 oldevents = s->async->events; 741 if (subpriv->has_int_sce) { 742 /* 743 * Collect interrupt sources that have triggered and disable 744 * them temporarily. Loop around until no extra interrupt 745 * sources have triggered, at which point, the valid part of 746 * the interrupt status register will read zero, clearing the 747 * cause of the interrupt. 748 * 749 * Mask off interrupt sources already seen to avoid infinite 750 * loop in case of misconfiguration. 751 */ 752 cur_enabled = subpriv->enabled_isns; 753 while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns 754 & ~triggered)) != 0) { 755 triggered |= intstat; 756 cur_enabled &= ~triggered; 757 outb(cur_enabled, subpriv->iobase); 758 } 759 } else { 760 /* 761 * No interrupt status register. Assume the single interrupt 762 * source has triggered. 763 */ 764 triggered = subpriv->enabled_isns; 765 } 766 767 if (triggered) { 768 /* 769 * Some interrupt sources have triggered and have been 770 * temporarily disabled to clear the cause of the interrupt. 771 * 772 * Reenable them NOW to minimize the time they are disabled. 773 */ 774 cur_enabled = subpriv->enabled_isns; 775 if (subpriv->has_int_sce) 776 outb(cur_enabled, subpriv->iobase); 777 778 if (subpriv->active) { 779 /* 780 * The command is still active. 781 * 782 * Ignore interrupt sources that the command isn't 783 * interested in (just in case there's a race 784 * condition). 785 */ 786 if (triggered & subpriv->enabled_isns) { 787 /* Collect scan data. */ 788 short val; 789 unsigned int n, ch, len; 790 791 val = 0; 792 len = s->async->cmd.chanlist_len; 793 for (n = 0; n < len; n++) { 794 ch = CR_CHAN(s->async->cmd.chanlist[n]); 795 if (triggered & (1U << ch)) 796 val |= (1U << n); 797 } 798 /* Write the scan to the buffer. */ 799 if (comedi_buf_put(s->async, val)) { 800 s->async->events |= (COMEDI_CB_BLOCK | 801 COMEDI_CB_EOS); 802 } else { 803 /* Error! Stop acquisition. */ 804 dio200_stop_intr(dev, s); 805 s->async->events |= COMEDI_CB_ERROR 806 | COMEDI_CB_OVERFLOW; 807 comedi_error(dev, "buffer overflow"); 808 } 809 810 /* Check for end of acquisition. */ 811 if (!subpriv->continuous) { 812 /* stop_src == TRIG_COUNT */ 813 if (subpriv->stopcount > 0) { 814 subpriv->stopcount--; 815 if (subpriv->stopcount == 0) { 816 s->async->events |= 817 COMEDI_CB_EOA; 818 dio200_stop_intr(dev, 819 s); 820 } 821 } 822 } 823 } 824 } 825 } 826 spin_unlock_irqrestore(&subpriv->spinlock, flags); 827 828 if (oldevents != s->async->events) 829 comedi_event(dev, s); 830 831 return (triggered != 0); 832} 833 834/* 835 * 'cancel' function for an 'INTERRUPT' subdevice. 836 */ 837static int dio200_subdev_intr_cancel(struct comedi_device *dev, 838 struct comedi_subdevice *s) 839{ 840 struct dio200_subdev_intr *subpriv = s->private; 841 unsigned long flags; 842 843 spin_lock_irqsave(&subpriv->spinlock, flags); 844 if (subpriv->active) 845 dio200_stop_intr(dev, s); 846 847 spin_unlock_irqrestore(&subpriv->spinlock, flags); 848 849 return 0; 850} 851 852/* 853 * 'do_cmdtest' function for an 'INTERRUPT' subdevice. 854 */ 855static int 856dio200_subdev_intr_cmdtest(struct comedi_device *dev, 857 struct comedi_subdevice *s, struct comedi_cmd *cmd) 858{ 859 int err = 0; 860 unsigned int tmp; 861 862 /* step 1: make sure trigger sources are trivially valid */ 863 864 tmp = cmd->start_src; 865 cmd->start_src &= (TRIG_NOW | TRIG_INT); 866 if (!cmd->start_src || tmp != cmd->start_src) 867 err++; 868 869 tmp = cmd->scan_begin_src; 870 cmd->scan_begin_src &= TRIG_EXT; 871 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 872 err++; 873 874 tmp = cmd->convert_src; 875 cmd->convert_src &= TRIG_NOW; 876 if (!cmd->convert_src || tmp != cmd->convert_src) 877 err++; 878 879 tmp = cmd->scan_end_src; 880 cmd->scan_end_src &= TRIG_COUNT; 881 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 882 err++; 883 884 tmp = cmd->stop_src; 885 cmd->stop_src &= (TRIG_COUNT | TRIG_NONE); 886 if (!cmd->stop_src || tmp != cmd->stop_src) 887 err++; 888 889 if (err) 890 return 1; 891 892 /* step 2: make sure trigger sources are unique and mutually 893 compatible */ 894 895 /* these tests are true if more than one _src bit is set */ 896 if ((cmd->start_src & (cmd->start_src - 1)) != 0) 897 err++; 898 if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0) 899 err++; 900 if ((cmd->convert_src & (cmd->convert_src - 1)) != 0) 901 err++; 902 if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0) 903 err++; 904 if ((cmd->stop_src & (cmd->stop_src - 1)) != 0) 905 err++; 906 907 if (err) 908 return 2; 909 910 /* step 3: make sure arguments are trivially compatible */ 911 912 /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */ 913 if (cmd->start_arg != 0) { 914 cmd->start_arg = 0; 915 err++; 916 } 917 918 /* cmd->scan_begin_src == TRIG_EXT */ 919 if (cmd->scan_begin_arg != 0) { 920 cmd->scan_begin_arg = 0; 921 err++; 922 } 923 924 /* cmd->convert_src == TRIG_NOW */ 925 if (cmd->convert_arg != 0) { 926 cmd->convert_arg = 0; 927 err++; 928 } 929 930 /* cmd->scan_end_src == TRIG_COUNT */ 931 if (cmd->scan_end_arg != cmd->chanlist_len) { 932 cmd->scan_end_arg = cmd->chanlist_len; 933 err++; 934 } 935 936 switch (cmd->stop_src) { 937 case TRIG_COUNT: 938 /* any count allowed */ 939 break; 940 case TRIG_NONE: 941 if (cmd->stop_arg != 0) { 942 cmd->stop_arg = 0; 943 err++; 944 } 945 break; 946 default: 947 break; 948 } 949 950 if (err) 951 return 3; 952 953 /* step 4: fix up any arguments */ 954 955 /* if (err) return 4; */ 956 957 return 0; 958} 959 960/* 961 * 'do_cmd' function for an 'INTERRUPT' subdevice. 962 */ 963static int dio200_subdev_intr_cmd(struct comedi_device *dev, 964 struct comedi_subdevice *s) 965{ 966 struct comedi_cmd *cmd = &s->async->cmd; 967 struct dio200_subdev_intr *subpriv = s->private; 968 unsigned long flags; 969 int event = 0; 970 971 spin_lock_irqsave(&subpriv->spinlock, flags); 972 subpriv->active = 1; 973 974 /* Set up end of acquisition. */ 975 switch (cmd->stop_src) { 976 case TRIG_COUNT: 977 subpriv->continuous = 0; 978 subpriv->stopcount = cmd->stop_arg; 979 break; 980 default: 981 /* TRIG_NONE */ 982 subpriv->continuous = 1; 983 subpriv->stopcount = 0; 984 break; 985 } 986 987 /* Set up start of acquisition. */ 988 switch (cmd->start_src) { 989 case TRIG_INT: 990 s->async->inttrig = dio200_inttrig_start_intr; 991 break; 992 default: 993 /* TRIG_NOW */ 994 event = dio200_start_intr(dev, s); 995 break; 996 } 997 spin_unlock_irqrestore(&subpriv->spinlock, flags); 998 999 if (event) 1000 comedi_event(dev, s); 1001 1002 return 0; 1003} 1004 1005/* 1006 * This function initializes an 'INTERRUPT' subdevice. 1007 */ 1008static int 1009dio200_subdev_intr_init(struct comedi_device *dev, struct comedi_subdevice *s, 1010 unsigned long iobase, unsigned valid_isns, 1011 int has_int_sce) 1012{ 1013 struct dio200_subdev_intr *subpriv; 1014 1015 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); 1016 if (!subpriv) { 1017 printk(KERN_ERR "comedi%d: error! out of memory!\n", 1018 dev->minor); 1019 return -ENOMEM; 1020 } 1021 subpriv->iobase = iobase; 1022 subpriv->has_int_sce = has_int_sce; 1023 subpriv->valid_isns = valid_isns; 1024 spin_lock_init(&subpriv->spinlock); 1025 1026 if (has_int_sce) 1027 outb(0, subpriv->iobase); /* Disable interrupt sources. */ 1028 1029 s->private = subpriv; 1030 s->type = COMEDI_SUBD_DI; 1031 s->subdev_flags = SDF_READABLE | SDF_CMD_READ; 1032 if (has_int_sce) { 1033 s->n_chan = DIO200_MAX_ISNS; 1034 s->len_chanlist = DIO200_MAX_ISNS; 1035 } else { 1036 /* No interrupt source register. Support single channel. */ 1037 s->n_chan = 1; 1038 s->len_chanlist = 1; 1039 } 1040 s->range_table = &range_digital; 1041 s->maxdata = 1; 1042 s->insn_bits = dio200_subdev_intr_insn_bits; 1043 s->do_cmdtest = dio200_subdev_intr_cmdtest; 1044 s->do_cmd = dio200_subdev_intr_cmd; 1045 s->cancel = dio200_subdev_intr_cancel; 1046 1047 return 0; 1048} 1049 1050/* 1051 * This function cleans up an 'INTERRUPT' subdevice. 1052 */ 1053static void 1054dio200_subdev_intr_cleanup(struct comedi_device *dev, 1055 struct comedi_subdevice *s) 1056{ 1057 struct dio200_subdev_intr *subpriv = s->private; 1058 kfree(subpriv); 1059} 1060 1061/* 1062 * Interrupt service routine. 1063 */ 1064static irqreturn_t dio200_interrupt(int irq, void *d) 1065{ 1066 struct comedi_device *dev = d; 1067 int handled; 1068 1069 if (!dev->attached) 1070 return IRQ_NONE; 1071 1072 if (devpriv->intr_sd >= 0) { 1073 handled = dio200_handle_read_intr(dev, 1074 dev->subdevices + 1075 devpriv->intr_sd); 1076 } else { 1077 handled = 0; 1078 } 1079 1080 return IRQ_RETVAL(handled); 1081} 1082 1083/* 1084 * Handle 'insn_read' for an '8254' counter subdevice. 1085 */ 1086static int 1087dio200_subdev_8254_read(struct comedi_device *dev, struct comedi_subdevice *s, 1088 struct comedi_insn *insn, unsigned int *data) 1089{ 1090 struct dio200_subdev_8254 *subpriv = s->private; 1091 int chan = CR_CHAN(insn->chanspec); 1092 unsigned long flags; 1093 1094 spin_lock_irqsave(&subpriv->spinlock, flags); 1095 data[0] = i8254_read(subpriv->iobase, 0, chan); 1096 spin_unlock_irqrestore(&subpriv->spinlock, flags); 1097 1098 return 1; 1099} 1100 1101/* 1102 * Handle 'insn_write' for an '8254' counter subdevice. 1103 */ 1104static int 1105dio200_subdev_8254_write(struct comedi_device *dev, struct comedi_subdevice *s, 1106 struct comedi_insn *insn, unsigned int *data) 1107{ 1108 struct dio200_subdev_8254 *subpriv = s->private; 1109 int chan = CR_CHAN(insn->chanspec); 1110 unsigned long flags; 1111 1112 spin_lock_irqsave(&subpriv->spinlock, flags); 1113 i8254_write(subpriv->iobase, 0, chan, data[0]); 1114 spin_unlock_irqrestore(&subpriv->spinlock, flags); 1115 1116 return 1; 1117} 1118 1119/* 1120 * Set gate source for an '8254' counter subdevice channel. 1121 */ 1122static int 1123dio200_set_gate_src(struct dio200_subdev_8254 *subpriv, 1124 unsigned int counter_number, unsigned int gate_src) 1125{ 1126 unsigned char byte; 1127 1128 if (!subpriv->has_clk_gat_sce) 1129 return -1; 1130 if (counter_number > 2) 1131 return -1; 1132 if (gate_src > 7) 1133 return -1; 1134 1135 subpriv->gate_src[counter_number] = gate_src; 1136 byte = GAT_SCE(subpriv->which, counter_number, gate_src); 1137 outb(byte, subpriv->gat_sce_iobase); 1138 1139 return 0; 1140} 1141 1142/* 1143 * Get gate source for an '8254' counter subdevice channel. 1144 */ 1145static int 1146dio200_get_gate_src(struct dio200_subdev_8254 *subpriv, 1147 unsigned int counter_number) 1148{ 1149 if (!subpriv->has_clk_gat_sce) 1150 return -1; 1151 if (counter_number > 2) 1152 return -1; 1153 1154 return subpriv->gate_src[counter_number]; 1155} 1156 1157/* 1158 * Set clock source for an '8254' counter subdevice channel. 1159 */ 1160static int 1161dio200_set_clock_src(struct dio200_subdev_8254 *subpriv, 1162 unsigned int counter_number, unsigned int clock_src) 1163{ 1164 unsigned char byte; 1165 1166 if (!subpriv->has_clk_gat_sce) 1167 return -1; 1168 if (counter_number > 2) 1169 return -1; 1170 if (clock_src > 7) 1171 return -1; 1172 1173 subpriv->clock_src[counter_number] = clock_src; 1174 byte = CLK_SCE(subpriv->which, counter_number, clock_src); 1175 outb(byte, subpriv->clk_sce_iobase); 1176 1177 return 0; 1178} 1179 1180/* 1181 * Get clock source for an '8254' counter subdevice channel. 1182 */ 1183static int 1184dio200_get_clock_src(struct dio200_subdev_8254 *subpriv, 1185 unsigned int counter_number, unsigned int *period_ns) 1186{ 1187 unsigned clock_src; 1188 1189 if (!subpriv->has_clk_gat_sce) 1190 return -1; 1191 if (counter_number > 2) 1192 return -1; 1193 1194 clock_src = subpriv->clock_src[counter_number]; 1195 *period_ns = clock_period[clock_src]; 1196 return clock_src; 1197} 1198 1199/* 1200 * Handle 'insn_config' for an '8254' counter subdevice. 1201 */ 1202static int 1203dio200_subdev_8254_config(struct comedi_device *dev, struct comedi_subdevice *s, 1204 struct comedi_insn *insn, unsigned int *data) 1205{ 1206 struct dio200_subdev_8254 *subpriv = s->private; 1207 int ret = 0; 1208 int chan = CR_CHAN(insn->chanspec); 1209 unsigned long flags; 1210 1211 spin_lock_irqsave(&subpriv->spinlock, flags); 1212 switch (data[0]) { 1213 case INSN_CONFIG_SET_COUNTER_MODE: 1214 ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]); 1215 if (ret < 0) 1216 ret = -EINVAL; 1217 break; 1218 case INSN_CONFIG_8254_READ_STATUS: 1219 data[1] = i8254_status(subpriv->iobase, 0, chan); 1220 break; 1221 case INSN_CONFIG_SET_GATE_SRC: 1222 ret = dio200_set_gate_src(subpriv, chan, data[2]); 1223 if (ret < 0) 1224 ret = -EINVAL; 1225 break; 1226 case INSN_CONFIG_GET_GATE_SRC: 1227 ret = dio200_get_gate_src(subpriv, chan); 1228 if (ret < 0) { 1229 ret = -EINVAL; 1230 break; 1231 } 1232 data[2] = ret; 1233 break; 1234 case INSN_CONFIG_SET_CLOCK_SRC: 1235 ret = dio200_set_clock_src(subpriv, chan, data[1]); 1236 if (ret < 0) 1237 ret = -EINVAL; 1238 break; 1239 case INSN_CONFIG_GET_CLOCK_SRC: 1240 ret = dio200_get_clock_src(subpriv, chan, &data[2]); 1241 if (ret < 0) { 1242 ret = -EINVAL; 1243 break; 1244 } 1245 data[1] = ret; 1246 break; 1247 default: 1248 ret = -EINVAL; 1249 break; 1250 } 1251 spin_unlock_irqrestore(&subpriv->spinlock, flags); 1252 return ret < 0 ? ret : insn->n; 1253} 1254 1255/* 1256 * This function initializes an '8254' counter subdevice. 1257 * 1258 * Note: iobase is the base address of the board, not the subdevice; 1259 * offset is the offset to the 8254 chip. 1260 */ 1261static int 1262dio200_subdev_8254_init(struct comedi_device *dev, struct comedi_subdevice *s, 1263 unsigned long iobase, unsigned offset, 1264 int has_clk_gat_sce) 1265{ 1266 struct dio200_subdev_8254 *subpriv; 1267 unsigned int chan; 1268 1269 subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL); 1270 if (!subpriv) { 1271 printk(KERN_ERR "comedi%d: error! out of memory!\n", 1272 dev->minor); 1273 return -ENOMEM; 1274 } 1275 1276 s->private = subpriv; 1277 s->type = COMEDI_SUBD_COUNTER; 1278 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 1279 s->n_chan = 3; 1280 s->maxdata = 0xFFFF; 1281 s->insn_read = dio200_subdev_8254_read; 1282 s->insn_write = dio200_subdev_8254_write; 1283 s->insn_config = dio200_subdev_8254_config; 1284 1285 spin_lock_init(&subpriv->spinlock); 1286 subpriv->iobase = offset + iobase; 1287 subpriv->has_clk_gat_sce = has_clk_gat_sce; 1288 if (has_clk_gat_sce) { 1289 /* Derive CLK_SCE and GAT_SCE register offsets from 1290 * 8254 offset. */ 1291 subpriv->clk_sce_iobase = 1292 DIO200_XCLK_SCE + (offset >> 3) + iobase; 1293 subpriv->gat_sce_iobase = 1294 DIO200_XGAT_SCE + (offset >> 3) + iobase; 1295 subpriv->which = (offset >> 2) & 1; 1296 } 1297 1298 /* Initialize channels. */ 1299 for (chan = 0; chan < 3; chan++) { 1300 i8254_set_mode(subpriv->iobase, 0, chan, 1301 I8254_MODE0 | I8254_BINARY); 1302 if (subpriv->has_clk_gat_sce) { 1303 /* Gate source 0 is VCC (logic 1). */ 1304 dio200_set_gate_src(subpriv, chan, 0); 1305 /* Clock source 0 is the dedicated clock input. */ 1306 dio200_set_clock_src(subpriv, chan, 0); 1307 } 1308 } 1309 1310 return 0; 1311} 1312 1313/* 1314 * This function cleans up an '8254' counter subdevice. 1315 */ 1316static void 1317dio200_subdev_8254_cleanup(struct comedi_device *dev, 1318 struct comedi_subdevice *s) 1319{ 1320 struct dio200_subdev_intr *subpriv = s->private; 1321 kfree(subpriv); 1322} 1323 1324/* 1325 * Attach is called by the Comedi core to configure the driver 1326 * for a particular board. If you specified a board_name array 1327 * in the driver structure, dev->board_ptr contains that 1328 * address. 1329 */ 1330static int dio200_attach(struct comedi_device *dev, struct comedi_devconfig *it) 1331{ 1332 struct comedi_subdevice *s; 1333 unsigned long iobase = 0; 1334 unsigned int irq = 0; 1335#ifdef CONFIG_COMEDI_PCI 1336 struct pci_dev *pci_dev = NULL; 1337 int bus = 0, slot = 0; 1338#endif 1339 const struct dio200_layout_struct *layout; 1340 int share_irq = 0; 1341 int sdx; 1342 unsigned n; 1343 int ret; 1344 1345 printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, 1346 DIO200_DRIVER_NAME); 1347 1348 ret = alloc_private(dev, sizeof(struct dio200_private)); 1349 if (ret < 0) { 1350 printk(KERN_ERR "comedi%d: error! out of memory!\n", 1351 dev->minor); 1352 return ret; 1353 } 1354 1355 /* Process options. */ 1356 switch (thisboard->bustype) { 1357 case isa_bustype: 1358 iobase = it->options[0]; 1359 irq = it->options[1]; 1360 share_irq = 0; 1361 break; 1362#ifdef CONFIG_COMEDI_PCI 1363 case pci_bustype: 1364 bus = it->options[0]; 1365 slot = it->options[1]; 1366 share_irq = 1; 1367 1368 ret = dio200_find_pci(dev, bus, slot, &pci_dev); 1369 if (ret < 0) 1370 return ret; 1371 devpriv->pci_dev = pci_dev; 1372 break; 1373#endif 1374 default: 1375 printk(KERN_ERR 1376 "comedi%d: %s: BUG! cannot determine board type!\n", 1377 dev->minor, DIO200_DRIVER_NAME); 1378 return -EINVAL; 1379 break; 1380 } 1381 1382 devpriv->intr_sd = -1; 1383 1384 /* Enable device and reserve I/O spaces. */ 1385#ifdef CONFIG_COMEDI_PCI 1386 if (pci_dev) { 1387 ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME); 1388 if (ret < 0) { 1389 printk(KERN_ERR 1390 "comedi%d: error! cannot enable PCI device and request regions!\n", 1391 dev->minor); 1392 return ret; 1393 } 1394 iobase = pci_resource_start(pci_dev, 2); 1395 irq = pci_dev->irq; 1396 } else 1397#endif 1398 { 1399 ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE); 1400 if (ret < 0) 1401 return ret; 1402 } 1403 dev->iobase = iobase; 1404 1405 layout = thislayout; 1406 1407 ret = alloc_subdevices(dev, layout->n_subdevs); 1408 if (ret < 0) { 1409 printk(KERN_ERR "comedi%d: error! out of memory!\n", 1410 dev->minor); 1411 return ret; 1412 } 1413 1414 for (n = 0; n < dev->n_subdevices; n++) { 1415 s = &dev->subdevices[n]; 1416 switch (layout->sdtype[n]) { 1417 case sd_8254: 1418 /* counter subdevice (8254) */ 1419 ret = dio200_subdev_8254_init(dev, s, iobase, 1420 layout->sdinfo[n], 1421 layout->has_clk_gat_sce); 1422 if (ret < 0) 1423 return ret; 1424 1425 break; 1426 case sd_8255: 1427 /* digital i/o subdevice (8255) */ 1428 ret = subdev_8255_init(dev, s, NULL, 1429 iobase + layout->sdinfo[n]); 1430 if (ret < 0) 1431 return ret; 1432 1433 break; 1434 case sd_intr: 1435 /* 'INTERRUPT' subdevice */ 1436 if (irq) { 1437 ret = dio200_subdev_intr_init(dev, s, 1438 iobase + 1439 DIO200_INT_SCE, 1440 layout->sdinfo[n], 1441 layout-> 1442 has_int_sce); 1443 if (ret < 0) 1444 return ret; 1445 1446 devpriv->intr_sd = n; 1447 } else { 1448 s->type = COMEDI_SUBD_UNUSED; 1449 } 1450 break; 1451 default: 1452 s->type = COMEDI_SUBD_UNUSED; 1453 break; 1454 } 1455 } 1456 1457 sdx = devpriv->intr_sd; 1458 if (sdx >= 0 && sdx < dev->n_subdevices) 1459 dev->read_subdev = &dev->subdevices[sdx]; 1460 1461 dev->board_name = thisboard->name; 1462 1463 if (irq) { 1464 unsigned long flags = share_irq ? IRQF_SHARED : 0; 1465 1466 if (request_irq(irq, dio200_interrupt, flags, 1467 DIO200_DRIVER_NAME, dev) >= 0) { 1468 dev->irq = irq; 1469 } else { 1470 printk(KERN_WARNING 1471 "comedi%d: warning! irq %u unavailable!\n", 1472 dev->minor, irq); 1473 } 1474 } 1475 1476 printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name); 1477 if (thisboard->bustype == isa_bustype) { 1478 printk("(base %#lx) ", iobase); 1479 } else { 1480#ifdef CONFIG_COMEDI_PCI 1481 printk("(pci %s) ", pci_name(pci_dev)); 1482#endif 1483 } 1484 if (irq) 1485 printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE")); 1486 else 1487 printk("(no irq) "); 1488 1489 printk("attached\n"); 1490 1491 return 1; 1492} 1493 1494/* 1495 * _detach is called to deconfigure a device. It should deallocate 1496 * resources. 1497 * This function is also called when _attach() fails, so it should be 1498 * careful not to release resources that were not necessarily 1499 * allocated by _attach(). dev->private and dev->subdevices are 1500 * deallocated automatically by the core. 1501 */ 1502static int dio200_detach(struct comedi_device *dev) 1503{ 1504 const struct dio200_layout_struct *layout; 1505 unsigned n; 1506 1507 printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, 1508 DIO200_DRIVER_NAME); 1509 1510 if (dev->irq) 1511 free_irq(dev->irq, dev); 1512 if (dev->subdevices) { 1513 layout = thislayout; 1514 for (n = 0; n < dev->n_subdevices; n++) { 1515 struct comedi_subdevice *s = &dev->subdevices[n]; 1516 switch (layout->sdtype[n]) { 1517 case sd_8254: 1518 dio200_subdev_8254_cleanup(dev, s); 1519 break; 1520 case sd_8255: 1521 subdev_8255_cleanup(dev, s); 1522 break; 1523 case sd_intr: 1524 dio200_subdev_intr_cleanup(dev, s); 1525 break; 1526 default: 1527 break; 1528 } 1529 } 1530 } 1531 if (devpriv) { 1532#ifdef CONFIG_COMEDI_PCI 1533 if (devpriv->pci_dev) { 1534 if (dev->iobase) 1535 comedi_pci_disable(devpriv->pci_dev); 1536 pci_dev_put(devpriv->pci_dev); 1537 } else 1538#endif 1539 { 1540 if (dev->iobase) 1541 release_region(dev->iobase, DIO200_IO_SIZE); 1542 } 1543 } 1544 if (dev->board_name) 1545 printk(KERN_INFO "comedi%d: %s removed\n", 1546 dev->minor, dev->board_name); 1547 1548 return 0; 1549} 1550 1551MODULE_AUTHOR("Comedi http://www.comedi.org"); 1552MODULE_DESCRIPTION("Comedi low-level driver"); 1553MODULE_LICENSE("GPL"); 1554