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