ni_daq_700.c revision 4cab3740734fb8582fa68f899105790c05935b55
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
482typedef struct local_info_t {
483	struct pcmcia_device *link;
484	dev_node_t node;
485	int stop;
486	struct bus_operations *bus;
487} local_info_t;
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	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(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		((local_info_t *) link->priv)->stop = 1;
556		dio700_release(link);
557	}
558
559	/* This points to the parent 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	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	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
598		cs_error(link, GetFirstTuple, last_ret);
599		goto cs_failed;
600	}
601	if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
602		cs_error(link, GetTupleData, last_ret);
603		goto cs_failed;
604	}
605	if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
606		cs_error(link, ParseTuple, last_ret);
607		goto cs_failed;
608	}
609	link->conf.ConfigBase = parse.config.base;
610	link->conf.Present = parse.config.rmask[0];
611
612	/*
613	   In this loop, we scan the CIS for configuration table entries,
614	   each of which describes a valid card configuration, including
615	   voltage, IO window, memory window, and interrupt settings.
616
617	   We make no assumptions about the card to be configured: we use
618	   just the information available in the CIS.  In an ideal world,
619	   this would work for any PCMCIA card, but it requires a complete
620	   and accurate CIS.  In practice, a driver usually "knows" most of
621	   these things without consulting the CIS, and most client drivers
622	   will only use the CIS to fill in implementation-defined details.
623	 */
624	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
625	if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
626		cs_error(link, GetFirstTuple, last_ret);
627		goto cs_failed;
628	}
629	while (1) {
630		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
631		if (pcmcia_get_tuple_data(link, &tuple) != 0)
632			goto next_entry;
633		if (pcmcia_parse_tuple(&tuple, &parse) != 0)
634			goto next_entry;
635
636		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
637			dflt = *cfg;
638		if (cfg->index == 0)
639			goto next_entry;
640		link->conf.ConfigIndex = cfg->index;
641
642		/* Does this card need audio output? */
643		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
644			link->conf.Attributes |= CONF_ENABLE_SPKR;
645			link->conf.Status = CCSR_AUDIO_ENA;
646		}
647
648		/* Do we need to allocate an interrupt? */
649		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
650			link->conf.Attributes |= CONF_ENABLE_IRQ;
651
652		/* IO window settings */
653		link->io.NumPorts1 = link->io.NumPorts2 = 0;
654		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
655			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
656			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
657			if (!(io->flags & CISTPL_IO_8BIT))
658				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
659			if (!(io->flags & CISTPL_IO_16BIT))
660				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
661			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
662			link->io.BasePort1 = io->win[0].base;
663			link->io.NumPorts1 = io->win[0].len;
664			if (io->nwin > 1) {
665				link->io.Attributes2 = link->io.Attributes1;
666				link->io.BasePort2 = io->win[1].base;
667				link->io.NumPorts2 = io->win[1].len;
668			}
669			/* This reserves IO space but doesn't actually enable it */
670			if (pcmcia_request_io(link, &link->io) != 0)
671				goto next_entry;
672		}
673
674		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
675			cistpl_mem_t *mem =
676				(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
677			req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
678			req.Attributes |= WIN_ENABLE;
679			req.Base = mem->win[0].host_addr;
680			req.Size = mem->win[0].len;
681			if (req.Size < 0x1000)
682				req.Size = 0x1000;
683			req.AccessSpeed = 0;
684			if (pcmcia_request_window(&link, &req, &link->win))
685				goto next_entry;
686			map.Page = 0;
687			map.CardOffset = mem->win[0].card_addr;
688			if (pcmcia_map_mem_page(link->win, &map))
689				goto next_entry;
690		}
691		/* If we got this far, we're cool! */
692		break;
693
694	      next_entry:
695		if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
696			cs_error(link, GetNextTuple, last_ret);
697			goto cs_failed;
698		}
699	}
700
701	/*
702	   Allocate an interrupt line.  Note that this does not assign a
703	   handler to the interrupt, unless the 'Handler' member of the
704	   irq structure is initialized.
705	 */
706	if (link->conf.Attributes & CONF_ENABLE_IRQ)
707		if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
708			cs_error(link, RequestIRQ, last_ret);
709			goto cs_failed;
710		}
711
712	/*
713	   This actually configures the PCMCIA socket -- setting up
714	   the I/O windows and the interrupt mapping, and putting the
715	   card and host interface into "Memory and IO" mode.
716	 */
717	if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
718		cs_error(link, RequestConfiguration, last_ret);
719		goto cs_failed;
720	}
721
722	/*
723	   At this point, the dev_node_t structure(s) need to be
724	   initialized and arranged in a linked list at link->dev.
725	 */
726	sprintf(dev->node.dev_name, "ni_daq_700");
727	dev->node.major = dev->node.minor = 0;
728	link->dev_node = &dev->node;
729
730	/* Finally, report what we've done */
731	printk(KERN_INFO "%s: index 0x%02x",
732		dev->node.dev_name, link->conf.ConfigIndex);
733	if (link->conf.Attributes & CONF_ENABLE_IRQ)
734		printk(", irq %d", link->irq.AssignedIRQ);
735	if (link->io.NumPorts1)
736		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
737			link->io.BasePort1 + link->io.NumPorts1 - 1);
738	if (link->io.NumPorts2)
739		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
740			link->io.BasePort2 + link->io.NumPorts2 - 1);
741	if (link->win)
742		printk(", mem 0x%06lx-0x%06lx", req.Base,
743			req.Base + req.Size - 1);
744	printk("\n");
745
746	return;
747
748      cs_failed:
749	printk(KERN_INFO "ni_daq_700 cs failed");
750	dio700_release(link);
751
752}				/* dio700_config */
753
754static void dio700_release(struct pcmcia_device *link)
755{
756	DEBUG(0, "dio700_release(0x%p)\n", link);
757
758	pcmcia_disable_device(link);
759}				/* dio700_release */
760
761/*======================================================================
762
763    The card status event handler.  Mostly, this schedules other
764    stuff to run after an event is received.
765
766    When a CARD_REMOVAL event is received, we immediately set a
767    private flag to block future accesses to this device.  All the
768    functions that actually access the device should check this flag
769    to make sure the card is still present.
770
771======================================================================*/
772
773static int dio700_cs_suspend(struct pcmcia_device *link)
774{
775	local_info_t *local = link->priv;
776
777	/* Mark the device as stopped, to block IO until later */
778	local->stop = 1;
779	return 0;
780}				/* dio700_cs_suspend */
781
782static int dio700_cs_resume(struct pcmcia_device *link)
783{
784	local_info_t *local = link->priv;
785
786	local->stop = 0;
787	return 0;
788}				/* dio700_cs_resume */
789
790/*====================================================================*/
791
792static struct pcmcia_device_id dio700_cs_ids[] = {
793	/* N.B. These IDs should match those in dio700_boards */
794	PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743),	/* daqcard-700 */
795	PCMCIA_DEVICE_NULL
796};
797
798MODULE_LICENSE("GPL");
799MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids);
800
801struct pcmcia_driver dio700_cs_driver = {
802	.probe = dio700_cs_attach,
803	.remove = dio700_cs_detach,
804	.suspend = dio700_cs_suspend,
805	.resume = dio700_cs_resume,
806	.id_table = dio700_cs_ids,
807	.owner = THIS_MODULE,
808	.drv = {
809			.name = dev_info,
810		},
811};
812
813static int __init init_dio700_cs(void)
814{
815	printk("ni_daq_700:  cs-init \n");
816	DEBUG(0, "%s\n", version);
817	pcmcia_register_driver(&dio700_cs_driver);
818	return 0;
819}
820
821static void __exit exit_dio700_cs(void)
822{
823	DEBUG(0, "ni_daq_700: unloading\n");
824	pcmcia_unregister_driver(&dio700_cs_driver);
825}
826int __init init_module(void)
827{
828	int ret;
829
830	ret = init_dio700_cs();
831	if (ret < 0)
832		return ret;
833
834	return comedi_driver_register(&driver_dio700);
835}
836
837void __exit cleanup_module(void)
838{
839	exit_dio700_cs();
840	comedi_driver_unregister(&driver_dio700);
841}
842