ni_daq_700.c revision 68c3dbff9fc9f25872408d0e95980d41733d48d0
1/* 2 * comedi/drivers/ni_daq_700.c 3 * Driver for DAQCard-700 DIO only 4 * copied from 8255 5 * 6 * COMEDI - Linux Control and Measurement Device Interface 7 * Copyright (C) 1998 David A. Schleef <ds@schleef.org> 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 22 * 23 */ 24 25/* 26Driver: ni_daq_700 27Description: National Instruments PCMCIA DAQCard-700 DIO only 28Author: Fred Brooks <nsaspook@nsaspook.com>, 29 based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es> 30Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700) 31Status: works 32Updated: Thu, 21 Feb 2008 12:07:20 +0000 33 34The daqcard-700 appears in Comedi as a single digital I/O subdevice with 3516 channels. The channel 0 corresponds to the daqcard-700's output 36port, bit 0; channel 8 corresponds to the input port, bit 0. 37 38Direction configuration: channels 0-7 output, 8-15 input (8225 device 39emu as port A output, port B input, port C N/A). 40 41IRQ is assigned but not used. 42*/ 43 44#include "../comedidev.h" 45 46#include <linux/ioport.h> 47 48#include <pcmcia/cs_types.h> 49#include <pcmcia/cs.h> 50#include <pcmcia/cistpl.h> 51#include <pcmcia/cisreg.h> 52#include <pcmcia/ds.h> 53 54static struct pcmcia_device *pcmcia_cur_dev = NULL; 55 56#define DIO700_SIZE 8 /* size of io region used by board */ 57 58static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it); 59static int dio700_detach(struct comedi_device *dev); 60 61enum dio700_bustype { pcmcia_bustype }; 62 63struct dio700_board { 64 const char *name; 65 int device_id; /* device id for pcmcia board */ 66 enum dio700_bustype bustype; /* PCMCIA */ 67 int have_dio; /* have daqcard-700 dio */ 68 /* function pointers so we can use inb/outb or readb/writeb */ 69 /* as appropriate */ 70 unsigned int (*read_byte) (unsigned int address); 71 void (*write_byte) (unsigned int byte, unsigned int address); 72}; 73 74static const struct dio700_board dio700_boards[] = { 75 { 76 .name = "daqcard-700", 77 .device_id = 0x4743,/* 0x10b is manufacturer id, 0x4743 is device id */ 78 .bustype = pcmcia_bustype, 79 .have_dio = 1, 80 }, 81 { 82 .name = "ni_daq_700", 83 .device_id = 0x4743,/* 0x10b is manufacturer id, 0x4743 is device id */ 84 .bustype = pcmcia_bustype, 85 .have_dio = 1, 86 }, 87}; 88 89/* 90 * Useful for shorthand access to the particular board structure 91 */ 92#define thisboard ((const struct dio700_board *)dev->board_ptr) 93 94struct dio700_private { 95 96 int data; /* number of data points left to be taken */ 97}; 98 99 100#define devpriv ((struct dio700_private *)dev->private) 101 102static struct comedi_driver driver_dio700 = { 103 .driver_name = "ni_daq_700", 104 .module = THIS_MODULE, 105 .attach = dio700_attach, 106 .detach = dio700_detach, 107 .num_names = sizeof(dio700_boards) / sizeof(struct dio700_board), 108 .board_name = &dio700_boards[0].name, 109 .offset = sizeof(struct dio700_board), 110}; 111 112/* the real driver routines */ 113 114#define _700_SIZE 8 115 116#define _700_DATA 0 117 118#define DIO_W 0x04 119#define DIO_R 0x05 120 121struct subdev_700_struct { 122 unsigned long cb_arg; 123 int (*cb_func) (int, int, int, unsigned long); 124 int have_irq; 125}; 126 127#define CALLBACK_ARG (((struct subdev_700_struct *)s->private)->cb_arg) 128#define CALLBACK_FUNC (((struct subdev_700_struct *)s->private)->cb_func) 129#define subdevpriv ((struct subdev_700_struct *)s->private) 130 131static void do_config(struct comedi_device *dev, struct comedi_subdevice *s); 132 133void subdev_700_interrupt(struct comedi_device *dev, struct comedi_subdevice *s) 134{ 135 short d; 136 137 d = CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG); 138 139 comedi_buf_put(s->async, d); 140 s->async->events |= COMEDI_CB_EOS; 141 142 comedi_event(dev, s); 143} 144 145static int subdev_700_cb(int dir, int port, int data, unsigned long arg) 146{ 147 /* port is always A for output and B for input (8255 emu) */ 148 unsigned long iobase = arg; 149 150 if (dir) { 151 outb(data, iobase + DIO_W); 152 return 0; 153 } else { 154 return inb(iobase + DIO_R); 155 } 156} 157 158static int subdev_700_insn(struct comedi_device *dev, struct comedi_subdevice *s, 159 struct comedi_insn *insn, unsigned int *data) 160{ 161 if (data[0]) { 162 s->state &= ~data[0]; 163 s->state |= (data[0] & data[1]); 164 165 if (data[0] & 0xff) 166 CALLBACK_FUNC(1, _700_DATA, s->state & 0xff, 167 CALLBACK_ARG); 168 } 169 170 data[1] = s->state & 0xff; 171 data[1] |= CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG) << 8; 172 173 return 2; 174} 175 176static int subdev_700_insn_config(struct comedi_device *dev, struct comedi_subdevice *s, 177 struct comedi_insn *insn, unsigned int *data) 178{ 179 180 switch (data[0]) { 181 case INSN_CONFIG_DIO_INPUT: 182 break; 183 case INSN_CONFIG_DIO_OUTPUT: 184 break; 185 case INSN_CONFIG_DIO_QUERY: 186 data[1] = 187 (s->io_bits & (1 << CR_CHAN(insn-> 188 chanspec))) ? COMEDI_OUTPUT : 189 COMEDI_INPUT; 190 return insn->n; 191 break; 192 default: 193 return -EINVAL; 194 } 195 196 return 1; 197} 198 199static void do_config(struct comedi_device *dev, struct comedi_subdevice *s) 200{ /* use powerup defaults */ 201 return; 202} 203 204static int subdev_700_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s, 205 struct comedi_cmd *cmd) 206{ 207 int err = 0; 208 unsigned int tmp; 209 210 /* step 1 */ 211 212 tmp = cmd->start_src; 213 cmd->start_src &= TRIG_NOW; 214 if (!cmd->start_src || tmp != cmd->start_src) 215 err++; 216 217 tmp = cmd->scan_begin_src; 218 cmd->scan_begin_src &= TRIG_EXT; 219 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 220 err++; 221 222 tmp = cmd->convert_src; 223 cmd->convert_src &= TRIG_FOLLOW; 224 if (!cmd->convert_src || tmp != cmd->convert_src) 225 err++; 226 227 tmp = cmd->scan_end_src; 228 cmd->scan_end_src &= TRIG_COUNT; 229 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 230 err++; 231 232 tmp = cmd->stop_src; 233 cmd->stop_src &= TRIG_NONE; 234 if (!cmd->stop_src || tmp != cmd->stop_src) 235 err++; 236 237 if (err) 238 return 1; 239 240 /* step 2 */ 241 242 if (err) 243 return 2; 244 245 /* step 3 */ 246 247 if (cmd->start_arg != 0) { 248 cmd->start_arg = 0; 249 err++; 250 } 251 if (cmd->scan_begin_arg != 0) { 252 cmd->scan_begin_arg = 0; 253 err++; 254 } 255 if (cmd->convert_arg != 0) { 256 cmd->convert_arg = 0; 257 err++; 258 } 259 if (cmd->scan_end_arg != 1) { 260 cmd->scan_end_arg = 1; 261 err++; 262 } 263 if (cmd->stop_arg != 0) { 264 cmd->stop_arg = 0; 265 err++; 266 } 267 268 if (err) 269 return 3; 270 271 /* step 4 */ 272 273 if (err) 274 return 4; 275 276 return 0; 277} 278 279static int subdev_700_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 280{ 281 /* FIXME */ 282 283 return 0; 284} 285 286static int subdev_700_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 287{ 288 /* FIXME */ 289 290 return 0; 291} 292 293int subdev_700_init(struct comedi_device *dev, struct comedi_subdevice *s, int (*cb) (int, 294 int, int, unsigned long), unsigned long arg) 295{ 296 s->type = COMEDI_SUBD_DIO; 297 s->subdev_flags = SDF_READABLE | SDF_WRITABLE; 298 s->n_chan = 16; 299 s->range_table = &range_digital; 300 s->maxdata = 1; 301 302 s->private = kmalloc(sizeof(struct subdev_700_struct), GFP_KERNEL); 303 if (!s->private) 304 return -ENOMEM; 305 306 CALLBACK_ARG = arg; 307 if (cb == NULL) { 308 CALLBACK_FUNC = subdev_700_cb; 309 } else { 310 CALLBACK_FUNC = cb; 311 } 312 s->insn_bits = subdev_700_insn; 313 s->insn_config = subdev_700_insn_config; 314 315 s->state = 0; 316 s->io_bits = 0x00ff; 317 do_config(dev, s); 318 319 return 0; 320} 321 322int subdev_700_init_irq(struct comedi_device *dev, struct comedi_subdevice *s, 323 int (*cb) (int, int, int, unsigned long), unsigned long arg) 324{ 325 int ret; 326 327 ret = subdev_700_init(dev, s, cb, arg); 328 if (ret < 0) 329 return ret; 330 331 s->do_cmdtest = subdev_700_cmdtest; 332 s->do_cmd = subdev_700_cmd; 333 s->cancel = subdev_700_cancel; 334 335 subdevpriv->have_irq = 1; 336 337 return 0; 338} 339 340void subdev_700_cleanup(struct comedi_device *dev, struct comedi_subdevice *s) 341{ 342 if (s->private) { 343 if (subdevpriv->have_irq) { 344 } 345 346 kfree(s->private); 347 } 348} 349 350EXPORT_SYMBOL(subdev_700_init); 351EXPORT_SYMBOL(subdev_700_init_irq); 352EXPORT_SYMBOL(subdev_700_cleanup); 353EXPORT_SYMBOL(subdev_700_interrupt); 354 355static int dio700_attach(struct comedi_device *dev, struct comedi_devconfig *it) 356{ 357 struct comedi_subdevice *s; 358 unsigned long iobase = 0; 359#ifdef incomplete 360 unsigned int irq = 0; 361#endif 362 struct pcmcia_device *link; 363 364 /* allocate and initialize dev->private */ 365 if (alloc_private(dev, sizeof(struct dio700_private)) < 0) 366 return -ENOMEM; 367 368 /* get base address, irq etc. based on bustype */ 369 switch (thisboard->bustype) { 370 case pcmcia_bustype: 371 link = pcmcia_cur_dev; /* XXX hack */ 372 if (!link) 373 return -EIO; 374 iobase = link->io.BasePort1; 375#ifdef incomplete 376 irq = link->irq.AssignedIRQ; 377#endif 378 break; 379 default: 380 printk("bug! couldn't determine board type\n"); 381 return -EINVAL; 382 break; 383 } 384 printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor, 385 thisboard->name, iobase); 386#ifdef incomplete 387 if (irq) { 388 printk(", irq %u", irq); 389 } 390#endif 391 392 printk("\n"); 393 394 if (iobase == 0) { 395 printk("io base address is zero!\n"); 396 return -EINVAL; 397 } 398 399 dev->iobase = iobase; 400 401#ifdef incomplete 402 /* grab our IRQ */ 403 dev->irq = irq; 404#endif 405 406 dev->board_name = thisboard->name; 407 408 if (alloc_subdevices(dev, 1) < 0) 409 return -ENOMEM; 410 411 /* DAQCard-700 dio */ 412 s = dev->subdevices + 0; 413 subdev_700_init(dev, s, NULL, dev->iobase); 414 415 return 0; 416}; 417 418static int dio700_detach(struct comedi_device *dev) 419{ 420 printk("comedi%d: ni_daq_700: cs-remove\n", dev->minor); 421 422 if (dev->subdevices) 423 subdev_700_cleanup(dev, dev->subdevices + 0); 424 425 if (thisboard->bustype != pcmcia_bustype && dev->iobase) 426 release_region(dev->iobase, DIO700_SIZE); 427 if (dev->irq) 428 comedi_free_irq(dev->irq, dev); 429 430 return 0; 431}; 432 433/* PCMCIA crap */ 434 435/* 436 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If 437 you do not define PCMCIA_DEBUG at all, all the debug code will be 438 left out. If you compile with PCMCIA_DEBUG=0, the debug code will 439 be present but disabled -- but it can then be enabled for specific 440 modules at load time with a 'pc_debug=#' option to insmod. 441*/ 442#ifdef PCMCIA_DEBUG 443static int pc_debug = PCMCIA_DEBUG; 444module_param(pc_debug, int, 0644); 445#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args) 446static char *version = "ni_daq_700.c, based on dummy_cs.c"; 447#else 448#define DEBUG(n, args...) 449#endif 450 451/*====================================================================*/ 452 453static void dio700_config(struct pcmcia_device *link); 454static void dio700_release(struct pcmcia_device *link); 455static int dio700_cs_suspend(struct pcmcia_device *p_dev); 456static int dio700_cs_resume(struct pcmcia_device *p_dev); 457 458/* 459 The attach() and detach() entry points are used to create and destroy 460 "instances" of the driver, where each instance represents everything 461 needed to manage one actual PCMCIA card. 462*/ 463 464static int dio700_cs_attach(struct pcmcia_device *); 465static void dio700_cs_detach(struct pcmcia_device *); 466 467/* 468 You'll also need to prototype all the functions that will actually 469 be used to talk to your device. See 'memory_cs' for a good example 470 of a fully self-sufficient driver; the other drivers rely more or 471 less on other parts of the kernel. 472*/ 473 474/* 475 The dev_info variable is the "key" that is used to match up this 476 device driver with appropriate cards, through the card configuration 477 database. 478*/ 479 480static const dev_info_t dev_info = "ni_daq_700"; 481 482struct local_info_t { 483 struct pcmcia_device *link; 484 dev_node_t node; 485 int stop; 486 struct bus_operations *bus; 487}; 488 489/*====================================================================== 490 491 dio700_cs_attach() creates an "instance" of the driver, allocating 492 local data structures for one device. The device is registered 493 with Card Services. 494 495 The dev_link structure is initialized, but we don't actually 496 configure the card at this point -- we wait until we receive a 497 card insertion event. 498 499======================================================================*/ 500 501static int dio700_cs_attach(struct pcmcia_device *link) 502{ 503 struct local_info_t *local; 504 505 printk(KERN_INFO "ni_daq_700: cs-attach\n"); 506 507 DEBUG(0, "dio700_cs_attach()\n"); 508 509 /* Allocate space for private device-specific data */ 510 local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL); 511 if (!local) 512 return -ENOMEM; 513 local->link = link; 514 link->priv = local; 515 516 /* Interrupt setup */ 517 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; 518 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 519 link->irq.Handler = NULL; 520 521 /* 522 General socket configuration defaults can go here. In this 523 client, we assume very little, and rely on the CIS for almost 524 everything. In most clients, many details (i.e., number, sizes, 525 and attributes of IO windows) are fixed by the nature of the 526 device, and can be hard-wired here. 527 */ 528 link->conf.Attributes = 0; 529 link->conf.IntType = INT_MEMORY_AND_IO; 530 531 pcmcia_cur_dev = link; 532 533 dio700_config(link); 534 535 return 0; 536} /* dio700_cs_attach */ 537 538/*====================================================================== 539 540 This deletes a driver "instance". The device is de-registered 541 with Card Services. If it has been released, all local data 542 structures are freed. Otherwise, the structures will be freed 543 when the device is released. 544 545======================================================================*/ 546 547static void dio700_cs_detach(struct pcmcia_device *link) 548{ 549 550 printk(KERN_INFO "ni_daq_700: cs-detach!\n"); 551 552 DEBUG(0, "dio700_cs_detach(0x%p)\n", link); 553 554 if (link->dev_node) { 555 ((struct local_info_t *) link->priv)->stop = 1; 556 dio700_release(link); 557 } 558 559 /* This points to the parent struct local_info_t struct */ 560 if (link->priv) 561 kfree(link->priv); 562 563} /* dio700_cs_detach */ 564 565/*====================================================================== 566 567 dio700_config() is scheduled to run after a CARD_INSERTION event 568 is received, to configure the PCMCIA socket, and to make the 569 device available to the system. 570 571======================================================================*/ 572 573static void dio700_config(struct pcmcia_device *link) 574{ 575 struct local_info_t *dev = link->priv; 576 tuple_t tuple; 577 cisparse_t parse; 578 int last_ret; 579 u_char buf[64]; 580 win_req_t req; 581 memreq_t map; 582 cistpl_cftable_entry_t dflt = { 0 }; 583 584 printk(KERN_INFO "ni_daq_700: cs-config\n"); 585 586 DEBUG(0, "dio700_config(0x%p)\n", link); 587 588 /* 589 This reads the card's CONFIG tuple to find its configuration 590 registers. 591 */ 592 tuple.DesiredTuple = CISTPL_CONFIG; 593 tuple.Attributes = 0; 594 tuple.TupleData = buf; 595 tuple.TupleDataMax = sizeof(buf); 596 tuple.TupleOffset = 0; 597 598 last_ret = pcmcia_get_first_tuple(link, &tuple); 599 if (last_ret) { 600 cs_error(link, GetFirstTuple, last_ret); 601 goto cs_failed; 602 } 603 604 last_ret = pcmcia_get_tuple_data(link, &tuple); 605 if (last_ret) { 606 cs_error(link, GetTupleData, last_ret); 607 goto cs_failed; 608 } 609 610 last_ret = pcmcia_parse_tuple(&tuple, &parse); 611 if (last_ret) { 612 cs_error(link, ParseTuple, last_ret); 613 goto cs_failed; 614 } 615 link->conf.ConfigBase = parse.config.base; 616 link->conf.Present = parse.config.rmask[0]; 617 618 /* 619 In this loop, we scan the CIS for configuration table entries, 620 each of which describes a valid card configuration, including 621 voltage, IO window, memory window, and interrupt settings. 622 623 We make no assumptions about the card to be configured: we use 624 just the information available in the CIS. In an ideal world, 625 this would work for any PCMCIA card, but it requires a complete 626 and accurate CIS. In practice, a driver usually "knows" most of 627 these things without consulting the CIS, and most client drivers 628 will only use the CIS to fill in implementation-defined details. 629 */ 630 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 631 last_ret = pcmcia_get_first_tuple(link, &tuple); 632 if (last_ret != 0) { 633 cs_error(link, GetFirstTuple, last_ret); 634 goto cs_failed; 635 } 636 while (1) { 637 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 638 if (pcmcia_get_tuple_data(link, &tuple) != 0) 639 goto next_entry; 640 if (pcmcia_parse_tuple(&tuple, &parse) != 0) 641 goto next_entry; 642 643 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 644 dflt = *cfg; 645 if (cfg->index == 0) 646 goto next_entry; 647 link->conf.ConfigIndex = cfg->index; 648 649 /* Does this card need audio output? */ 650 if (cfg->flags & CISTPL_CFTABLE_AUDIO) { 651 link->conf.Attributes |= CONF_ENABLE_SPKR; 652 link->conf.Status = CCSR_AUDIO_ENA; 653 } 654 655 /* Do we need to allocate an interrupt? */ 656 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) 657 link->conf.Attributes |= CONF_ENABLE_IRQ; 658 659 /* IO window settings */ 660 link->io.NumPorts1 = link->io.NumPorts2 = 0; 661 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { 662 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; 663 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 664 if (!(io->flags & CISTPL_IO_8BIT)) 665 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16; 666 if (!(io->flags & CISTPL_IO_16BIT)) 667 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 668 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; 669 link->io.BasePort1 = io->win[0].base; 670 link->io.NumPorts1 = io->win[0].len; 671 if (io->nwin > 1) { 672 link->io.Attributes2 = link->io.Attributes1; 673 link->io.BasePort2 = io->win[1].base; 674 link->io.NumPorts2 = io->win[1].len; 675 } 676 /* This reserves IO space but doesn't actually enable it */ 677 if (pcmcia_request_io(link, &link->io) != 0) 678 goto next_entry; 679 } 680 681 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) { 682 cistpl_mem_t *mem = 683 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem; 684 req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM; 685 req.Attributes |= WIN_ENABLE; 686 req.Base = mem->win[0].host_addr; 687 req.Size = mem->win[0].len; 688 if (req.Size < 0x1000) 689 req.Size = 0x1000; 690 req.AccessSpeed = 0; 691 if (pcmcia_request_window(&link, &req, &link->win)) 692 goto next_entry; 693 map.Page = 0; 694 map.CardOffset = mem->win[0].card_addr; 695 if (pcmcia_map_mem_page(link->win, &map)) 696 goto next_entry; 697 } 698 /* If we got this far, we're cool! */ 699 break; 700 701 next_entry: 702 703 last_ret = pcmcia_get_next_tuple(link, &tuple); 704 if (last_ret) { 705 cs_error(link, GetNextTuple, last_ret); 706 goto cs_failed; 707 } 708 } 709 710 /* 711 Allocate an interrupt line. Note that this does not assign a 712 handler to the interrupt, unless the 'Handler' member of the 713 irq structure is initialized. 714 */ 715 if (link->conf.Attributes & CONF_ENABLE_IRQ) { 716 last_ret = pcmcia_request_irq(link, &link->irq); 717 if (last_ret) { 718 cs_error(link, RequestIRQ, last_ret); 719 goto cs_failed; 720 } 721 } 722 723 /* 724 This actually configures the PCMCIA socket -- setting up 725 the I/O windows and the interrupt mapping, and putting the 726 card and host interface into "Memory and IO" mode. 727 */ 728 last_ret = pcmcia_request_configuration(link, &link->conf); 729 if (last_ret != 0) { 730 cs_error(link, RequestConfiguration, last_ret); 731 goto cs_failed; 732 } 733 734 /* 735 At this point, the dev_node_t structure(s) need to be 736 initialized and arranged in a linked list at link->dev. 737 */ 738 sprintf(dev->node.dev_name, "ni_daq_700"); 739 dev->node.major = dev->node.minor = 0; 740 link->dev_node = &dev->node; 741 742 /* Finally, report what we've done */ 743 printk(KERN_INFO "%s: index 0x%02x", 744 dev->node.dev_name, link->conf.ConfigIndex); 745 if (link->conf.Attributes & CONF_ENABLE_IRQ) 746 printk(", irq %d", link->irq.AssignedIRQ); 747 if (link->io.NumPorts1) 748 printk(", io 0x%04x-0x%04x", link->io.BasePort1, 749 link->io.BasePort1 + link->io.NumPorts1 - 1); 750 if (link->io.NumPorts2) 751 printk(" & 0x%04x-0x%04x", link->io.BasePort2, 752 link->io.BasePort2 + link->io.NumPorts2 - 1); 753 if (link->win) 754 printk(", mem 0x%06lx-0x%06lx", req.Base, 755 req.Base + req.Size - 1); 756 printk("\n"); 757 758 return; 759 760 cs_failed: 761 printk(KERN_INFO "ni_daq_700 cs failed"); 762 dio700_release(link); 763 764} /* dio700_config */ 765 766static void dio700_release(struct pcmcia_device *link) 767{ 768 DEBUG(0, "dio700_release(0x%p)\n", link); 769 770 pcmcia_disable_device(link); 771} /* dio700_release */ 772 773/*====================================================================== 774 775 The card status event handler. Mostly, this schedules other 776 stuff to run after an event is received. 777 778 When a CARD_REMOVAL event is received, we immediately set a 779 private flag to block future accesses to this device. All the 780 functions that actually access the device should check this flag 781 to make sure the card is still present. 782 783======================================================================*/ 784 785static int dio700_cs_suspend(struct pcmcia_device *link) 786{ 787 struct local_info_t *local = link->priv; 788 789 /* Mark the device as stopped, to block IO until later */ 790 local->stop = 1; 791 return 0; 792} /* dio700_cs_suspend */ 793 794static int dio700_cs_resume(struct pcmcia_device *link) 795{ 796 struct local_info_t *local = link->priv; 797 798 local->stop = 0; 799 return 0; 800} /* dio700_cs_resume */ 801 802/*====================================================================*/ 803 804static struct pcmcia_device_id dio700_cs_ids[] = { 805 /* N.B. These IDs should match those in dio700_boards */ 806 PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743), /* daqcard-700 */ 807 PCMCIA_DEVICE_NULL 808}; 809 810MODULE_LICENSE("GPL"); 811MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids); 812 813struct pcmcia_driver dio700_cs_driver = { 814 .probe = dio700_cs_attach, 815 .remove = dio700_cs_detach, 816 .suspend = dio700_cs_suspend, 817 .resume = dio700_cs_resume, 818 .id_table = dio700_cs_ids, 819 .owner = THIS_MODULE, 820 .drv = { 821 .name = dev_info, 822 }, 823}; 824 825static int __init init_dio700_cs(void) 826{ 827 printk("ni_daq_700: cs-init \n"); 828 DEBUG(0, "%s\n", version); 829 pcmcia_register_driver(&dio700_cs_driver); 830 return 0; 831} 832 833static void __exit exit_dio700_cs(void) 834{ 835 DEBUG(0, "ni_daq_700: unloading\n"); 836 pcmcia_unregister_driver(&dio700_cs_driver); 837} 838int __init init_module(void) 839{ 840 int ret; 841 842 ret = init_dio700_cs(); 843 if (ret < 0) 844 return ret; 845 846 return comedi_driver_register(&driver_dio700); 847} 848 849void __exit cleanup_module(void) 850{ 851 exit_dio700_cs(); 852 comedi_driver_unregister(&driver_dio700); 853} 854