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