blob: 1e40348430ea8f6061d914a698068d266bd4390e [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
Bill Pemberton0707bb02009-03-16 22:06:20 -040058static int dio700_attach(struct comedi_device * dev, struct comedi_devconfig * it);
Bill Pemberton71b5f4f2009-03-16 22:05:08 -040059static int dio700_detach(struct comedi_device * dev);
Fred Brooks1f9bbbe2009-02-19 10:05:01 -080060
61enum dio700_bustype { pcmcia_bustype };
62
Bill Pemberton4cab3742009-03-19 17:59:34 -040063struct dio700_board {
Fred Brooks1f9bbbe2009-02-19 10:05:01 -080064 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);
Bill Pemberton4cab3742009-03-19 17:59:34 -040072};
Fred Brooks1f9bbbe2009-02-19 10:05:01 -080073
Bill Pemberton4cab3742009-03-19 17:59:34 -040074static const struct dio700_board dio700_boards[] = {
Fred Brooks1f9bbbe2009-02-19 10:05:01 -080075 {
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 */
Bill Pemberton4cab3742009-03-19 17:59:34 -040092#define thisboard ((const struct dio700_board *)dev->board_ptr)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -080093
Bill Pembertonadf32842009-03-16 22:16:23 -040094struct dio700_private {
Fred Brooks1f9bbbe2009-02-19 10:05:01 -080095
Bill Pembertonadf32842009-03-16 22:16:23 -040096 int data; /* number of data points left to be taken */
97};
98
99
100#define devpriv ((struct dio700_private *)dev->private)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800101
Bill Pemberton139dfbd2009-03-16 22:05:25 -0400102static struct comedi_driver driver_dio700 = {
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800103 driver_name:"ni_daq_700",
104 module:THIS_MODULE,
105 attach:dio700_attach,
106 detach:dio700_detach,
Bill Pemberton4cab3742009-03-19 17:59:34 -0400107 num_names:sizeof(dio700_boards) / sizeof(struct dio700_board),
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800108 board_name:&dio700_boards[0].name,
Bill Pemberton4cab3742009-03-19 17:59:34 -0400109 offset:sizeof(struct dio700_board),
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800110};
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
Bill Pemberton34c43922009-03-16 22:05:14 -0400131static void do_config(struct comedi_device * dev, struct comedi_subdevice * s);
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800132
Bill Pemberton34c43922009-03-16 22:05:14 -0400133void subdev_700_interrupt(struct comedi_device * dev, struct comedi_subdevice * s)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800134{
Bill Pemberton790c5542009-03-16 22:05:02 -0400135 short d;
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800136
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
Bill Pemberton34c43922009-03-16 22:05:14 -0400158static int subdev_700_insn(struct comedi_device * dev, struct comedi_subdevice * s,
Bill Pemberton90035c02009-03-16 22:05:53 -0400159 struct comedi_insn * insn, unsigned int * data)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800160{
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
Bill Pemberton34c43922009-03-16 22:05:14 -0400176static int subdev_700_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
Bill Pemberton90035c02009-03-16 22:05:53 -0400177 struct comedi_insn * insn, unsigned int * data)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800178{
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
Bill Pemberton34c43922009-03-16 22:05:14 -0400199static void do_config(struct comedi_device * dev, struct comedi_subdevice * s)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800200{ /* use powerup defaults */
201 return;
202}
203
Bill Pemberton34c43922009-03-16 22:05:14 -0400204static int subdev_700_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
Bill Pembertonea6d0d42009-03-16 22:05:47 -0400205 struct comedi_cmd * cmd)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800206{
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
Bill Pemberton34c43922009-03-16 22:05:14 -0400279static int subdev_700_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800280{
281 /* FIXME */
282
283 return 0;
284}
285
Bill Pemberton34c43922009-03-16 22:05:14 -0400286static int subdev_700_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800287{
288 /* FIXME */
289
290 return 0;
291}
292
Bill Pemberton34c43922009-03-16 22:05:14 -0400293int subdev_700_init(struct comedi_device * dev, struct comedi_subdevice * s, int (*cb) (int,
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800294 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
Bill Pemberton34c43922009-03-16 22:05:14 -0400322int subdev_700_init_irq(struct comedi_device * dev, struct comedi_subdevice * s,
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800323 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
Bill Pemberton34c43922009-03-16 22:05:14 -0400340void subdev_700_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800341{
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
Bill Pemberton0707bb02009-03-16 22:06:20 -0400355static int dio700_attach(struct comedi_device * dev, struct comedi_devconfig * it)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800356{
Bill Pemberton34c43922009-03-16 22:05:14 -0400357 struct comedi_subdevice *s;
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800358 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 */
Bill Pembertonadf32842009-03-16 22:16:23 -0400365 if (alloc_private(dev, sizeof(struct dio700_private)) < 0)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800366 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
Bill Pemberton71b5f4f2009-03-16 22:05:08 -0400418static int dio700_detach(struct comedi_device * dev)
Fred Brooks1f9bbbe2009-02-19 10:05:01 -0800419{
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}