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