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