Staging: comedi: add quatech_daqp_cs driver
[deliverable/linux.git] / drivers / staging / comedi / drivers / quatech_daqp_cs.c
1 /*======================================================================
2
3 comedi/drivers/quatech_daqp_cs.c
4
5 Quatech DAQP PCMCIA data capture cards COMEDI client driver
6 Copyright (C) 2000, 2003 Brent Baccala <baccala@freesoft.org>
7 The DAQP interface code in this file is released into the public domain.
8
9 COMEDI - Linux Control and Measurement Device Interface
10 Copyright (C) 1998 David A. Schleef <ds@schleef.org>
11 http://www.comedi.org/
12
13 quatech_daqp_cs.c 1.10
14
15 Documentation for the DAQP PCMCIA cards can be found on Quatech's site:
16
17 ftp://ftp.quatech.com/Manuals/daqp-208.pdf
18
19 This manual is for both the DAQP-208 and the DAQP-308.
20
21 What works:
22
23 - A/D conversion
24 - 8 channels
25 - 4 gain ranges
26 - ground ref or differential
27 - single-shot and timed both supported
28 - D/A conversion, single-shot
29 - digital I/O
30
31 What doesn't:
32
33 - any kind of triggering - external or D/A channel 1
34 - the card's optional expansion board
35 - the card's timer (for anything other than A/D conversion)
36 - D/A update modes other than immediate (i.e, timed)
37 - fancier timing modes
38 - setting card's FIFO buffer thresholds to anything but default
39
40 ======================================================================*/
41
42 /*
43 Driver: quatech_daqp_cs
44 Description: Quatech DAQP PCMCIA data capture cards
45 Author: Brent Baccala <baccala@freesoft.org>
46 Status: works
47 Devices: [Quatech] DAQP-208 (daqp), DAQP-308
48 */
49
50 #include "../comedidev.h"
51
52 #include <linux/version.h>
53 #include <pcmcia/cs_types.h>
54 #include <pcmcia/cs.h>
55 #include <pcmcia/cistpl.h>
56 #include <pcmcia/cisreg.h>
57 #include <pcmcia/ds.h>
58
59 /*
60 All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
61 you do not define PCMCIA_DEBUG at all, all the debug code will be
62 left out. If you compile with PCMCIA_DEBUG=0, the debug code will
63 be present but disabled -- but it can then be enabled for specific
64 modules at load time with a 'pc_debug=#' option to insmod.
65 */
66
67 #ifdef PCMCIA_DEBUG
68 static int pc_debug = PCMCIA_DEBUG;
69 module_param(pc_debug, int, 0644);
70 #define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
71 static char *version = "quatech_daqp_cs.c 1.10 2003/04/21 (Brent Baccala)";
72 #else
73 #define DEBUG(n, args...)
74 #endif
75
76 /* Maximum number of separate DAQP devices we'll allow */
77 #define MAX_DEV 4
78
79 typedef struct local_info_t {
80 struct pcmcia_device *link;
81 dev_node_t node;
82 int stop;
83 int table_index;
84 char board_name[32];
85
86 enum { semaphore, buffer } interrupt_mode;
87
88 struct semaphore eos;
89
90 comedi_device *dev;
91 comedi_subdevice *s;
92 int count;
93 } local_info_t;
94
95 /* A list of "instances" of the device. */
96
97 static local_info_t *dev_table[MAX_DEV] = { NULL, /* ... */ };
98
99 /* The DAQP communicates with the system through a 16 byte I/O window. */
100
101 #define DAQP_FIFO_SIZE 4096
102
103 #define DAQP_FIFO 0
104 #define DAQP_SCANLIST 1
105 #define DAQP_CONTROL 2
106 #define DAQP_STATUS 2
107 #define DAQP_DIGITAL_IO 3
108 #define DAQP_PACER_LOW 4
109 #define DAQP_PACER_MID 5
110 #define DAQP_PACER_HIGH 6
111 #define DAQP_COMMAND 7
112 #define DAQP_DA 8
113 #define DAQP_TIMER 10
114 #define DAQP_AUX 15
115
116 #define DAQP_SCANLIST_DIFFERENTIAL 0x4000
117 #define DAQP_SCANLIST_GAIN(x) ((x)<<12)
118 #define DAQP_SCANLIST_CHANNEL(x) ((x)<<8)
119 #define DAQP_SCANLIST_START 0x0080
120 #define DAQP_SCANLIST_EXT_GAIN(x) ((x)<<4)
121 #define DAQP_SCANLIST_EXT_CHANNEL(x) (x)
122
123 #define DAQP_CONTROL_PACER_100kHz 0xc0
124 #define DAQP_CONTROL_PACER_1MHz 0x80
125 #define DAQP_CONTROL_PACER_5MHz 0x40
126 #define DAQP_CONTROL_PACER_EXTERNAL 0x00
127 #define DAQP_CONTORL_EXPANSION 0x20
128 #define DAQP_CONTROL_EOS_INT_ENABLE 0x10
129 #define DAQP_CONTROL_FIFO_INT_ENABLE 0x08
130 #define DAQP_CONTROL_TRIGGER_ONESHOT 0x00
131 #define DAQP_CONTROL_TRIGGER_CONTINUOUS 0x04
132 #define DAQP_CONTROL_TRIGGER_INTERNAL 0x00
133 #define DAQP_CONTROL_TRIGGER_EXTERNAL 0x02
134 #define DAQP_CONTROL_TRIGGER_RISING 0x00
135 #define DAQP_CONTROL_TRIGGER_FALLING 0x01
136
137 #define DAQP_STATUS_IDLE 0x80
138 #define DAQP_STATUS_RUNNING 0x40
139 #define DAQP_STATUS_EVENTS 0x38
140 #define DAQP_STATUS_DATA_LOST 0x20
141 #define DAQP_STATUS_END_OF_SCAN 0x10
142 #define DAQP_STATUS_FIFO_THRESHOLD 0x08
143 #define DAQP_STATUS_FIFO_FULL 0x04
144 #define DAQP_STATUS_FIFO_NEARFULL 0x02
145 #define DAQP_STATUS_FIFO_EMPTY 0x01
146
147 #define DAQP_COMMAND_ARM 0x80
148 #define DAQP_COMMAND_RSTF 0x40
149 #define DAQP_COMMAND_RSTQ 0x20
150 #define DAQP_COMMAND_STOP 0x10
151 #define DAQP_COMMAND_LATCH 0x08
152 #define DAQP_COMMAND_100kHz 0x00
153 #define DAQP_COMMAND_50kHz 0x02
154 #define DAQP_COMMAND_25kHz 0x04
155 #define DAQP_COMMAND_FIFO_DATA 0x01
156 #define DAQP_COMMAND_FIFO_PROGRAM 0x00
157
158 #define DAQP_AUX_TRIGGER_TTL 0x00
159 #define DAQP_AUX_TRIGGER_ANALOG 0x80
160 #define DAQP_AUX_TRIGGER_PRETRIGGER 0x40
161 #define DAQP_AUX_TIMER_INT_ENABLE 0x20
162 #define DAQP_AUX_TIMER_RELOAD 0x00
163 #define DAQP_AUX_TIMER_PAUSE 0x08
164 #define DAQP_AUX_TIMER_GO 0x10
165 #define DAQP_AUX_TIMER_GO_EXTERNAL 0x18
166 #define DAQP_AUX_TIMER_EXTERNAL_SRC 0x04
167 #define DAQP_AUX_TIMER_INTERNAL_SRC 0x00
168 #define DAQP_AUX_DA_DIRECT 0x00
169 #define DAQP_AUX_DA_OVERFLOW 0x01
170 #define DAQP_AUX_DA_EXTERNAL 0x02
171 #define DAQP_AUX_DA_PACER 0x03
172
173 #define DAQP_AUX_RUNNING 0x80
174 #define DAQP_AUX_TRIGGERED 0x40
175 #define DAQP_AUX_DA_BUFFER 0x20
176 #define DAQP_AUX_TIMER_OVERFLOW 0x10
177 #define DAQP_AUX_CONVERSION 0x08
178 #define DAQP_AUX_DATA_LOST 0x04
179 #define DAQP_AUX_FIFO_NEARFULL 0x02
180 #define DAQP_AUX_FIFO_EMPTY 0x01
181
182 /* These range structures tell COMEDI how the sample values map to
183 * voltages. The A/D converter has four ranges: +/- 10V through
184 * +/- 1.25V, and the D/A converter has only one: +/- 5V.
185 */
186
187 static const comedi_lrange range_daqp_ai = { 4, {
188 BIP_RANGE(10),
189 BIP_RANGE(5),
190 BIP_RANGE(2.5),
191 BIP_RANGE(1.25)
192 }
193 };
194
195 static const comedi_lrange range_daqp_ao = { 1, {BIP_RANGE(5)} };
196
197 /*====================================================================*/
198
199 /* comedi interface code */
200
201 static int daqp_attach(comedi_device * dev, comedi_devconfig * it);
202 static int daqp_detach(comedi_device * dev);
203 static comedi_driver driver_daqp = {
204 driver_name:"quatech_daqp_cs",
205 module:THIS_MODULE,
206 attach:daqp_attach,
207 detach:daqp_detach,
208 };
209
210 #ifdef DAQP_DEBUG
211
212 static void daqp_dump(comedi_device * dev)
213 {
214 printk("DAQP: status %02x; aux status %02x\n",
215 inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX));
216 }
217
218 static void hex_dump(char *str, void *ptr, int len)
219 {
220 unsigned char *cptr = ptr;
221 int i;
222
223 printk(str);
224
225 for (i = 0; i < len; i++) {
226 if (i % 16 == 0) {
227 printk("\n0x%08x:", (unsigned int)cptr);
228 }
229 printk(" %02x", *(cptr++));
230 }
231 printk("\n");
232 }
233
234 #endif
235
236 /* Cancel a running acquisition */
237
238 static int daqp_ai_cancel(comedi_device * dev, comedi_subdevice * s)
239 {
240 local_info_t *local = (local_info_t *) s->private;
241
242 if (local->stop) {
243 return -EIO;
244 }
245
246 outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND);
247
248 /* flush any linguring data in FIFO - superfluous here */
249 /* outb(DAQP_COMMAND_RSTF, dev->iobase+DAQP_COMMAND); */
250
251 local->interrupt_mode = semaphore;
252
253 return 0;
254 }
255
256 /* Interrupt handler
257 *
258 * Operates in one of two modes. If local->interrupt_mode is
259 * 'semaphore', just signal the local->eos semaphore and return
260 * (one-shot mode). Otherwise (continuous mode), read data in from
261 * the card, transfer it to the buffer provided by the higher-level
262 * comedi kernel module, and signal various comedi callback routines,
263 * which run pretty quick.
264 */
265
266 static void daqp_interrupt(int irq, void *dev_id PT_REGS_ARG)
267 {
268 local_info_t *local = (local_info_t *) dev_id;
269 comedi_device *dev;
270 comedi_subdevice *s;
271 int loop_limit = 10000;
272 int status;
273
274 if (local == NULL) {
275 printk(KERN_WARNING
276 "daqp_interrupt(): irq %d for unknown device.\n", irq);
277 return;
278 }
279
280 dev = local->dev;
281 if (dev == NULL) {
282 printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n");
283 return;
284 }
285
286 if (!dev->attached) {
287 printk(KERN_WARNING
288 "daqp_interrupt(): comedi_device not yet attached.\n");
289 return;
290 }
291
292 s = local->s;
293 if (s == NULL) {
294 printk(KERN_WARNING
295 "daqp_interrupt(): NULL comedi_subdevice.\n");
296 return;
297 }
298
299 if ((local_info_t *) s->private != local) {
300 printk(KERN_WARNING
301 "daqp_interrupt(): invalid comedi_subdevice.\n");
302 return;
303 }
304
305 switch (local->interrupt_mode) {
306
307 case semaphore:
308
309 up(&local->eos);
310 break;
311
312 case buffer:
313
314 while (!((status = inb(dev->iobase + DAQP_STATUS))
315 & DAQP_STATUS_FIFO_EMPTY)) {
316
317 sampl_t data;
318
319 if (status & DAQP_STATUS_DATA_LOST) {
320 s->async->events |=
321 COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
322 printk("daqp: data lost\n");
323 daqp_ai_cancel(dev, s);
324 break;
325 }
326
327 data = inb(dev->iobase + DAQP_FIFO);
328 data |= inb(dev->iobase + DAQP_FIFO) << 8;
329 data ^= 0x8000;
330
331 comedi_buf_put(s->async, data);
332
333 /* If there's a limit, decrement it
334 * and stop conversion if zero
335 */
336
337 if (local->count > 0) {
338 local->count--;
339 if (local->count == 0) {
340 daqp_ai_cancel(dev, s);
341 s->async->events |= COMEDI_CB_EOA;
342 break;
343 }
344 }
345
346 if ((loop_limit--) <= 0)
347 break;
348 }
349
350 if (loop_limit <= 0) {
351 printk(KERN_WARNING
352 "loop_limit reached in daqp_interrupt()\n");
353 daqp_ai_cancel(dev, s);
354 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
355 }
356
357 s->async->events |= COMEDI_CB_BLOCK;
358
359 comedi_event(dev, s);
360 }
361 }
362
363 /* One-shot analog data acquisition routine */
364
365 static int daqp_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
366 comedi_insn * insn, lsampl_t * data)
367 {
368 local_info_t *local = (local_info_t *) s->private;
369 int i;
370 int v;
371 int counter = 10000;
372
373 if (local->stop) {
374 return -EIO;
375 }
376
377 /* Stop any running conversion */
378 daqp_ai_cancel(dev, s);
379
380 outb(0, dev->iobase + DAQP_AUX);
381
382 /* Reset scan list queue */
383 outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
384
385 /* Program one scan list entry */
386
387 v = DAQP_SCANLIST_CHANNEL(CR_CHAN(insn->chanspec))
388 | DAQP_SCANLIST_GAIN(CR_RANGE(insn->chanspec));
389
390 if (CR_AREF(insn->chanspec) == AREF_DIFF) {
391 v |= DAQP_SCANLIST_DIFFERENTIAL;
392 }
393
394 v |= DAQP_SCANLIST_START;
395
396 outb(v & 0xff, dev->iobase + DAQP_SCANLIST);
397 outb(v >> 8, dev->iobase + DAQP_SCANLIST);
398
399 /* Reset data FIFO (see page 28 of DAQP User's Manual) */
400
401 outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
402
403 /* Set trigger */
404
405 v = DAQP_CONTROL_TRIGGER_ONESHOT | DAQP_CONTROL_TRIGGER_INTERNAL
406 | DAQP_CONTROL_PACER_100kHz | DAQP_CONTROL_EOS_INT_ENABLE;
407
408 outb(v, dev->iobase + DAQP_CONTROL);
409
410 /* Reset any pending interrupts (my card has a tendancy to require
411 * require multiple reads on the status register to achieve this)
412 */
413
414 while (--counter
415 && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
416 if (!counter) {
417 printk("daqp: couldn't clear interrupts in status register\n");
418 return -1;
419 }
420
421 /* Make sure semaphore is blocked */
422 sema_init(&local->eos, 0);
423 local->interrupt_mode = semaphore;
424 local->dev = dev;
425 local->s = s;
426
427 for (i = 0; i < insn->n; i++) {
428
429 /* Start conversion */
430 outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
431 dev->iobase + DAQP_COMMAND);
432
433 /* Wait for interrupt service routine to unblock semaphore */
434 /* Maybe could use a timeout here, but it's interruptible */
435 if (down_interruptible(&local->eos))
436 return -EINTR;
437
438 data[i] = inb(dev->iobase + DAQP_FIFO);
439 data[i] |= inb(dev->iobase + DAQP_FIFO) << 8;
440 data[i] ^= 0x8000;
441 }
442
443 return insn->n;
444 }
445
446 /* This function converts ns nanoseconds to a counter value suitable
447 * for programming the device. We always use the DAQP's 5 MHz clock,
448 * which with its 24-bit counter, allows values up to 84 seconds.
449 * Also, the function adjusts ns so that it cooresponds to the actual
450 * time that the device will use.
451 */
452
453 static int daqp_ns_to_timer(unsigned int *ns, int round)
454 {
455 int timer;
456
457 timer = *ns / 200;
458 *ns = timer * 200;
459
460 return timer;
461 }
462
463 /* cmdtest tests a particular command to see if it is valid.
464 * Using the cmdtest ioctl, a user can create a valid cmd
465 * and then have it executed by the cmd ioctl.
466 *
467 * cmdtest returns 1,2,3,4 or 0, depending on which tests
468 * the command passes.
469 */
470
471 static int daqp_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
472 comedi_cmd * cmd)
473 {
474 int err = 0;
475 int tmp;
476
477 /* step 1: make sure trigger sources are trivially valid */
478
479 tmp = cmd->start_src;
480 cmd->start_src &= TRIG_NOW;
481 if (!cmd->start_src || tmp != cmd->start_src)
482 err++;
483
484 tmp = cmd->scan_begin_src;
485 cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
486 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
487 err++;
488
489 tmp = cmd->convert_src;
490 cmd->convert_src &= TRIG_TIMER | TRIG_NOW;
491 if (!cmd->convert_src || tmp != cmd->convert_src)
492 err++;
493
494 tmp = cmd->scan_end_src;
495 cmd->scan_end_src &= TRIG_COUNT;
496 if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
497 err++;
498
499 tmp = cmd->stop_src;
500 cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
501 if (!cmd->stop_src || tmp != cmd->stop_src)
502 err++;
503
504 if (err)
505 return 1;
506
507 /* step 2: make sure trigger sources are unique and mutually compatible */
508
509 /* note that mutual compatiblity is not an issue here */
510 if (cmd->scan_begin_src != TRIG_TIMER &&
511 cmd->scan_begin_src != TRIG_FOLLOW)
512 err++;
513 if (cmd->convert_src != TRIG_NOW && cmd->convert_src != TRIG_TIMER)
514 err++;
515 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
516 err++;
517 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
518 err++;
519
520 if (err)
521 return 2;
522
523 /* step 3: make sure arguments are trivially compatible */
524
525 if (cmd->start_arg != 0) {
526 cmd->start_arg = 0;
527 err++;
528 }
529 #define MAX_SPEED 10000 /* 100 kHz - in nanoseconds */
530
531 if (cmd->scan_begin_src == TRIG_TIMER
532 && cmd->scan_begin_arg < MAX_SPEED) {
533 cmd->scan_begin_arg = MAX_SPEED;
534 err++;
535 }
536
537 /* If both scan_begin and convert are both timer values, the only
538 * way that can make sense is if the scan time is the number of
539 * conversions times the convert time
540 */
541
542 if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER
543 && cmd->scan_begin_arg !=
544 cmd->convert_arg * cmd->scan_end_arg) {
545 err++;
546 }
547
548 if (cmd->convert_src == TRIG_TIMER && cmd->convert_arg < MAX_SPEED) {
549 cmd->convert_arg = MAX_SPEED;
550 err++;
551 }
552
553 if (cmd->scan_end_arg != cmd->chanlist_len) {
554 cmd->scan_end_arg = cmd->chanlist_len;
555 err++;
556 }
557 if (cmd->stop_src == TRIG_COUNT) {
558 if (cmd->stop_arg > 0x00ffffff) {
559 cmd->stop_arg = 0x00ffffff;
560 err++;
561 }
562 } else {
563 /* TRIG_NONE */
564 if (cmd->stop_arg != 0) {
565 cmd->stop_arg = 0;
566 err++;
567 }
568 }
569
570 if (err)
571 return 3;
572
573 /* step 4: fix up any arguments */
574
575 if (cmd->scan_begin_src == TRIG_TIMER) {
576 tmp = cmd->scan_begin_arg;
577 daqp_ns_to_timer(&cmd->scan_begin_arg,
578 cmd->flags & TRIG_ROUND_MASK);
579 if (tmp != cmd->scan_begin_arg)
580 err++;
581 }
582
583 if (cmd->convert_src == TRIG_TIMER) {
584 tmp = cmd->convert_arg;
585 daqp_ns_to_timer(&cmd->convert_arg,
586 cmd->flags & TRIG_ROUND_MASK);
587 if (tmp != cmd->convert_arg)
588 err++;
589 }
590
591 if (err)
592 return 4;
593
594 return 0;
595 }
596
597 static int daqp_ai_cmd(comedi_device * dev, comedi_subdevice * s)
598 {
599 local_info_t *local = (local_info_t *) s->private;
600 comedi_cmd *cmd = &s->async->cmd;
601 int counter = 100;
602 int scanlist_start_on_every_entry;
603 int threshold;
604
605 int i;
606 int v;
607
608 if (local->stop) {
609 return -EIO;
610 }
611
612 /* Stop any running conversion */
613 daqp_ai_cancel(dev, s);
614
615 outb(0, dev->iobase + DAQP_AUX);
616
617 /* Reset scan list queue */
618 outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
619
620 /* Program pacer clock
621 *
622 * There's two modes we can operate in. If convert_src is
623 * TRIG_TIMER, then convert_arg specifies the time between
624 * each conversion, so we program the pacer clock to that
625 * frequency and set the SCANLIST_START bit on every scanlist
626 * entry. Otherwise, convert_src is TRIG_NOW, which means
627 * we want the fastest possible conversions, scan_begin_src
628 * is TRIG_TIMER, and scan_begin_arg specifies the time between
629 * each scan, so we program the pacer clock to this frequency
630 * and only set the SCANLIST_START bit on the first entry.
631 */
632
633 if (cmd->convert_src == TRIG_TIMER) {
634 int counter = daqp_ns_to_timer(&cmd->convert_arg,
635 cmd->flags & TRIG_ROUND_MASK);
636 outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
637 outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
638 outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
639 scanlist_start_on_every_entry = 1;
640 } else {
641 int counter = daqp_ns_to_timer(&cmd->scan_begin_arg,
642 cmd->flags & TRIG_ROUND_MASK);
643 outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
644 outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
645 outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
646 scanlist_start_on_every_entry = 0;
647 }
648
649 /* Program scan list */
650
651 for (i = 0; i < cmd->chanlist_len; i++) {
652
653 int chanspec = cmd->chanlist[i];
654
655 /* Program one scan list entry */
656
657 v = DAQP_SCANLIST_CHANNEL(CR_CHAN(chanspec))
658 | DAQP_SCANLIST_GAIN(CR_RANGE(chanspec));
659
660 if (CR_AREF(chanspec) == AREF_DIFF) {
661 v |= DAQP_SCANLIST_DIFFERENTIAL;
662 }
663
664 if (i == 0 || scanlist_start_on_every_entry) {
665 v |= DAQP_SCANLIST_START;
666 }
667
668 outb(v & 0xff, dev->iobase + DAQP_SCANLIST);
669 outb(v >> 8, dev->iobase + DAQP_SCANLIST);
670 }
671
672 /* Now it's time to program the FIFO threshold, basically the
673 * number of samples the card will buffer before it interrupts
674 * the CPU.
675 *
676 * If we don't have a stop count, then use half the size of
677 * the FIFO (the manufacturer's recommendation). Consider
678 * that the FIFO can hold 2K samples (4K bytes). With the
679 * threshold set at half the FIFO size, we have a margin of
680 * error of 1024 samples. At the chip's maximum sample rate
681 * of 100,000 Hz, the CPU would have to delay interrupt
682 * service for a full 10 milliseconds in order to lose data
683 * here (as opposed to higher up in the kernel). I've never
684 * seen it happen. However, for slow sample rates it may
685 * buffer too much data and introduce too much delay for the
686 * user application.
687 *
688 * If we have a stop count, then things get more interesting.
689 * If the stop count is less than the FIFO size (actually
690 * three-quarters of the FIFO size - see below), we just use
691 * the stop count itself as the threshold, the card interrupts
692 * us when that many samples have been taken, and we kill the
693 * acquisition at that point and are done. If the stop count
694 * is larger than that, then we divide it by 2 until it's less
695 * than three quarters of the FIFO size (we always leave the
696 * top quarter of the FIFO as protection against sluggish CPU
697 * interrupt response) and use that as the threshold. So, if
698 * the stop count is 4000 samples, we divide by two twice to
699 * get 1000 samples, use that as the threshold, take four
700 * interrupts to get our 4000 samples and are done.
701 *
702 * The algorithm could be more clever. For example, if 81000
703 * samples are requested, we could set the threshold to 1500
704 * samples and take 54 interrupts to get 81000. But 54 isn't
705 * a power of two, so this algorithm won't find that option.
706 * Instead, it'll set the threshold at 1266 and take 64
707 * interrupts to get 81024 samples, of which the last 24 will
708 * be discarded... but we won't get the last interrupt until
709 * they've been collected. To find the first option, the
710 * computer could look at the prime decomposition of the
711 * sample count (81000 = 3^4 * 5^3 * 2^3) and factor it into a
712 * threshold (1500 = 3 * 5^3 * 2^2) and an interrupt count (54
713 * = 3^3 * 2). Hmmm... a one-line while loop or prime
714 * decomposition of integers... I'll leave it the way it is.
715 *
716 * I'll also note a mini-race condition before ignoring it in
717 * the code. Let's say we're taking 4000 samples, as before.
718 * After 1000 samples, we get an interrupt. But before that
719 * interrupt is completely serviced, another sample is taken
720 * and loaded into the FIFO. Since the interrupt handler
721 * empties the FIFO before returning, it will read 1001 samples.
722 * If that happens four times, we'll end up taking 4004 samples,
723 * not 4000. The interrupt handler will discard the extra four
724 * samples (by halting the acquisition with four samples still
725 * in the FIFO), but we will have to wait for them.
726 *
727 * In short, this code works pretty well, but for either of
728 * the two reasons noted, might end up waiting for a few more
729 * samples than actually requested. Shouldn't make too much
730 * of a difference.
731 */
732
733 /* Save away the number of conversions we should perform, and
734 * compute the FIFO threshold (in bytes, not samples - that's
735 * why we multiple local->count by 2 = sizeof(sample))
736 */
737
738 if (cmd->stop_src == TRIG_COUNT) {
739 local->count = cmd->stop_arg * cmd->scan_end_arg;
740 threshold = 2 * local->count;
741 while (threshold > DAQP_FIFO_SIZE * 3 / 4)
742 threshold /= 2;
743 } else {
744 local->count = -1;
745 threshold = DAQP_FIFO_SIZE / 2;
746 }
747
748 /* Reset data FIFO (see page 28 of DAQP User's Manual) */
749
750 outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
751
752 /* Set FIFO threshold. First two bytes are near-empty
753 * threshold, which is unused; next two bytes are near-full
754 * threshold. We computed the number of bytes we want in the
755 * FIFO when the interrupt is generated, what the card wants
756 * is actually the number of available bytes left in the FIFO
757 * when the interrupt is to happen.
758 */
759
760 outb(0x00, dev->iobase + DAQP_FIFO);
761 outb(0x00, dev->iobase + DAQP_FIFO);
762
763 outb((DAQP_FIFO_SIZE - threshold) & 0xff, dev->iobase + DAQP_FIFO);
764 outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_FIFO);
765
766 /* Set trigger */
767
768 v = DAQP_CONTROL_TRIGGER_CONTINUOUS | DAQP_CONTROL_TRIGGER_INTERNAL
769 | DAQP_CONTROL_PACER_5MHz | DAQP_CONTROL_FIFO_INT_ENABLE;
770
771 outb(v, dev->iobase + DAQP_CONTROL);
772
773 /* Reset any pending interrupts (my card has a tendancy to require
774 * require multiple reads on the status register to achieve this)
775 */
776
777 while (--counter
778 && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
779 if (!counter) {
780 printk("daqp: couldn't clear interrupts in status register\n");
781 return -1;
782 }
783
784 local->interrupt_mode = buffer;
785 local->dev = dev;
786 local->s = s;
787
788 /* Start conversion */
789 outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
790 dev->iobase + DAQP_COMMAND);
791
792 return 0;
793 }
794
795 /* Single-shot analog output routine */
796
797 static int daqp_ao_insn_write(comedi_device * dev, comedi_subdevice * s,
798 comedi_insn * insn, lsampl_t * data)
799 {
800 local_info_t *local = (local_info_t *) s->private;
801 int d;
802 unsigned int chan;
803
804 if (local->stop) {
805 return -EIO;
806 }
807
808 chan = CR_CHAN(insn->chanspec);
809 d = data[0];
810 d &= 0x0fff;
811 d ^= 0x0800; /* Flip the sign */
812 d |= chan << 12;
813
814 /* Make sure D/A update mode is direct update */
815 outb(0, dev->iobase + DAQP_AUX);
816
817 outw(d, dev->iobase + DAQP_DA);
818
819 return 1;
820 }
821
822 /* Digital input routine */
823
824 static int daqp_di_insn_read(comedi_device * dev, comedi_subdevice * s,
825 comedi_insn * insn, lsampl_t * data)
826 {
827 local_info_t *local = (local_info_t *) s->private;
828
829 if (local->stop) {
830 return -EIO;
831 }
832
833 data[0] = inb(dev->iobase + DAQP_DIGITAL_IO);
834
835 return 1;
836 }
837
838 /* Digital output routine */
839
840 static int daqp_do_insn_write(comedi_device * dev, comedi_subdevice * s,
841 comedi_insn * insn, lsampl_t * data)
842 {
843 local_info_t *local = (local_info_t *) s->private;
844
845 if (local->stop) {
846 return -EIO;
847 }
848
849 outw(data[0] & 0xf, dev->iobase + DAQP_DIGITAL_IO);
850
851 return 1;
852 }
853
854 /* daqp_attach is called via comedi_config to attach a comedi device
855 * to a /dev/comedi*. Note that this is different from daqp_cs_attach()
856 * which is called by the pcmcia subsystem to attach the PCMCIA card
857 * when it is inserted.
858 */
859
860 static int daqp_attach(comedi_device * dev, comedi_devconfig * it)
861 {
862 int ret;
863 local_info_t *local = dev_table[it->options[0]];
864 tuple_t tuple;
865 int i;
866 comedi_subdevice *s;
867
868 if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) {
869 printk("comedi%d: No such daqp device %d\n",
870 dev->minor, it->options[0]);
871 return -EIO;
872 }
873
874 /* Typically brittle code that I don't completely understand,
875 * but "it works on my card". The intent is to pull the model
876 * number of the card out the PCMCIA CIS and stash it away as
877 * the COMEDI board_name. Looks like the third field in
878 * CISTPL_VERS_1 (offset 2) holds what we're looking for. If
879 * it doesn't work, who cares, just leave it as "DAQP".
880 */
881
882 strcpy(local->board_name, "DAQP");
883 dev->board_name = local->board_name;
884
885 tuple.DesiredTuple = CISTPL_VERS_1;
886 if (pcmcia_get_first_tuple(local->link, &tuple) == 0) {
887 u_char buf[128];
888
889 buf[0] = buf[sizeof(buf) - 1] = 0;
890 tuple.TupleData = buf;
891 tuple.TupleDataMax = sizeof(buf);
892 tuple.TupleOffset = 2;
893 if (pcmcia_get_tuple_data(local->link, &tuple) == 0) {
894
895 for (i = 0; i < tuple.TupleDataLen - 4; i++)
896 if (buf[i] == 0)
897 break;
898 for (i++; i < tuple.TupleDataLen - 4; i++)
899 if (buf[i] == 0)
900 break;
901 i++;
902 if ((i < tuple.TupleDataLen - 4)
903 && (strncmp(buf + i, "DAQP", 4) == 0)) {
904 strncpy(local->board_name, buf + i,
905 sizeof(local->board_name));
906 }
907 }
908 }
909
910 dev->iobase = local->link->io.BasePort1;
911
912 if ((ret = alloc_subdevices(dev, 4)) < 0)
913 return ret;
914
915 printk("comedi%d: attaching daqp%d (io 0x%04lx)\n",
916 dev->minor, it->options[0], dev->iobase);
917
918 s = dev->subdevices + 0;
919 dev->read_subdev = s;
920 s->private = local;
921 s->type = COMEDI_SUBD_AI;
922 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
923 s->n_chan = 8;
924 s->len_chanlist = 2048;
925 s->maxdata = 0xffff;
926 s->range_table = &range_daqp_ai;
927 s->insn_read = daqp_ai_insn_read;
928 s->do_cmdtest = daqp_ai_cmdtest;
929 s->do_cmd = daqp_ai_cmd;
930 s->cancel = daqp_ai_cancel;
931
932 s = dev->subdevices + 1;
933 dev->write_subdev = s;
934 s->private = local;
935 s->type = COMEDI_SUBD_AO;
936 s->subdev_flags = SDF_WRITEABLE;
937 s->n_chan = 2;
938 s->len_chanlist = 1;
939 s->maxdata = 0x0fff;
940 s->range_table = &range_daqp_ao;
941 s->insn_write = daqp_ao_insn_write;
942
943 s = dev->subdevices + 2;
944 s->private = local;
945 s->type = COMEDI_SUBD_DI;
946 s->subdev_flags = SDF_READABLE;
947 s->n_chan = 1;
948 s->len_chanlist = 1;
949 s->insn_read = daqp_di_insn_read;
950
951 s = dev->subdevices + 3;
952 s->private = local;
953 s->type = COMEDI_SUBD_DO;
954 s->subdev_flags = SDF_WRITEABLE;
955 s->n_chan = 1;
956 s->len_chanlist = 1;
957 s->insn_write = daqp_do_insn_write;
958
959 return 1;
960 }
961
962 /* daqp_detach (called from comedi_comdig) does nothing. If the PCMCIA
963 * card is removed, daqp_cs_detach() is called by the pcmcia subsystem.
964 */
965
966 static int daqp_detach(comedi_device * dev)
967 {
968 printk("comedi%d: detaching daqp\n", dev->minor);
969
970 return 0;
971 }
972
973 /*====================================================================
974
975 PCMCIA interface code
976
977 The rest of the code in this file is based on dummy_cs.c v1.24
978 from the Linux pcmcia_cs distribution v3.1.8 and is subject
979 to the following license agreement.
980
981 The remaining contents of this file are subject to the Mozilla Public
982 License Version 1.1 (the "License"); you may not use this file
983 except in compliance with the License. You may obtain a copy of
984 the License at http://www.mozilla.org/MPL/
985
986 Software distributed under the License is distributed on an "AS
987 IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
988 implied. See the License for the specific language governing
989 rights and limitations under the License.
990
991 The initial developer of the original code is David A. Hinds
992 <dhinds@pcmcia.sourceforge.org>. Portions created by David A. Hinds
993 are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
994
995 Alternatively, the contents of this file may be used under the
996 terms of the GNU Public License version 2 (the "GPL"), in which
997 case the provisions of the GPL are applicable instead of the
998 above. If you wish to allow the use of your version of this file
999 only under the terms of the GPL and not to allow others to use
1000 your version of this file under the MPL, indicate your decision
1001 by deleting the provisions above and replace them with the notice
1002 and other provisions required by the GPL. If you do not delete
1003 the provisions above, a recipient may use your version of this
1004 file under either the MPL or the GPL.
1005
1006 ======================================================================*/
1007
1008 /*
1009 The event() function is this driver's Card Services event handler.
1010 It will be called by Card Services when an appropriate card status
1011 event is received. The config() and release() entry points are
1012 used to configure or release a socket, in response to card
1013 insertion and ejection events.
1014
1015 Kernel version 2.6.16 upwards uses suspend() and resume() functions
1016 instead of an event() function.
1017 */
1018
1019 static void daqp_cs_config(struct pcmcia_device *link);
1020 static void daqp_cs_release(struct pcmcia_device *link);
1021 static int daqp_cs_suspend(struct pcmcia_device *p_dev);
1022 static int daqp_cs_resume(struct pcmcia_device *p_dev);
1023
1024 /*
1025 The attach() and detach() entry points are used to create and destroy
1026 "instances" of the driver, where each instance represents everything
1027 needed to manage one actual PCMCIA card.
1028 */
1029
1030 static int daqp_cs_attach(struct pcmcia_device *);
1031 static void daqp_cs_detach(struct pcmcia_device *);
1032
1033 /*
1034 The dev_info variable is the "key" that is used to match up this
1035 device driver with appropriate cards, through the card configuration
1036 database.
1037 */
1038
1039 static const dev_info_t dev_info = "quatech_daqp_cs";
1040
1041 /*======================================================================
1042
1043 daqp_cs_attach() creates an "instance" of the driver, allocating
1044 local data structures for one device. The device is registered
1045 with Card Services.
1046
1047 The dev_link structure is initialized, but we don't actually
1048 configure the card at this point -- we wait until we receive a
1049 card insertion event.
1050
1051 ======================================================================*/
1052
1053 static int daqp_cs_attach(struct pcmcia_device *link)
1054 {
1055 local_info_t *local;
1056 int i;
1057
1058 DEBUG(0, "daqp_cs_attach()\n");
1059
1060 for (i = 0; i < MAX_DEV; i++)
1061 if (dev_table[i] == NULL)
1062 break;
1063 if (i == MAX_DEV) {
1064 printk(KERN_NOTICE "daqp_cs: no devices available\n");
1065 return -ENODEV;
1066 }
1067
1068 /* Allocate space for private device-specific data */
1069 local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
1070 if (!local)
1071 return -ENOMEM;
1072
1073 local->table_index = i;
1074 dev_table[i] = local;
1075 local->link = link;
1076 link->priv = local;
1077
1078 /* Interrupt setup */
1079 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1080 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1081 link->irq.Handler = daqp_interrupt;
1082 link->irq.Instance = local;
1083
1084 /*
1085 General socket configuration defaults can go here. In this
1086 client, we assume very little, and rely on the CIS for almost
1087 everything. In most clients, many details (i.e., number, sizes,
1088 and attributes of IO windows) are fixed by the nature of the
1089 device, and can be hard-wired here.
1090 */
1091 link->conf.Attributes = 0;
1092 link->conf.IntType = INT_MEMORY_AND_IO;
1093
1094 daqp_cs_config(link);
1095
1096 return 0;
1097 } /* daqp_cs_attach */
1098
1099 /*======================================================================
1100
1101 This deletes a driver "instance". The device is de-registered
1102 with Card Services. If it has been released, all local data
1103 structures are freed. Otherwise, the structures will be freed
1104 when the device is released.
1105
1106 ======================================================================*/
1107
1108 static void daqp_cs_detach(struct pcmcia_device *link)
1109 {
1110 local_info_t *dev = link->priv;
1111
1112 DEBUG(0, "daqp_cs_detach(0x%p)\n", link);
1113
1114 if (link->dev_node) {
1115 dev->stop = 1;
1116 daqp_cs_release(link);
1117 }
1118
1119 /* Unlink device structure, and free it */
1120 dev_table[dev->table_index] = NULL;
1121 if (dev)
1122 kfree(dev);
1123
1124 } /* daqp_cs_detach */
1125
1126 /*======================================================================
1127
1128 daqp_cs_config() is scheduled to run after a CARD_INSERTION event
1129 is received, to configure the PCMCIA socket, and to make the
1130 device available to the system.
1131
1132 ======================================================================*/
1133
1134 static void daqp_cs_config(struct pcmcia_device *link)
1135 {
1136 local_info_t *dev = link->priv;
1137 tuple_t tuple;
1138 cisparse_t parse;
1139 int last_ret;
1140 u_char buf[64];
1141
1142 DEBUG(0, "daqp_cs_config(0x%p)\n", link);
1143
1144 /*
1145 This reads the card's CONFIG tuple to find its configuration
1146 registers.
1147 */
1148 tuple.DesiredTuple = CISTPL_CONFIG;
1149 tuple.Attributes = 0;
1150 tuple.TupleData = buf;
1151 tuple.TupleDataMax = sizeof(buf);
1152 tuple.TupleOffset = 0;
1153 if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
1154 cs_error(link, GetFirstTuple, last_ret);
1155 goto cs_failed;
1156 }
1157 if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) {
1158 cs_error(link, GetTupleData, last_ret);
1159 goto cs_failed;
1160 }
1161 if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) {
1162 cs_error(link, ParseTuple, last_ret);
1163 goto cs_failed;
1164 }
1165 link->conf.ConfigBase = parse.config.base;
1166 link->conf.Present = parse.config.rmask[0];
1167
1168 /*
1169 In this loop, we scan the CIS for configuration table entries,
1170 each of which describes a valid card configuration, including
1171 voltage, IO window, memory window, and interrupt settings.
1172
1173 We make no assumptions about the card to be configured: we use
1174 just the information available in the CIS. In an ideal world,
1175 this would work for any PCMCIA card, but it requires a complete
1176 and accurate CIS. In practice, a driver usually "knows" most of
1177 these things without consulting the CIS, and most client drivers
1178 will only use the CIS to fill in implementation-defined details.
1179 */
1180 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1181 if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
1182 cs_error(link, GetFirstTuple, last_ret);
1183 goto cs_failed;
1184 }
1185 while (1) {
1186 cistpl_cftable_entry_t dflt = { 0 };
1187 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1188 if (pcmcia_get_tuple_data(link, &tuple))
1189 goto next_entry;
1190 if (pcmcia_parse_tuple(&tuple, &parse))
1191 goto next_entry;
1192
1193 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
1194 dflt = *cfg;
1195 if (cfg->index == 0)
1196 goto next_entry;
1197 link->conf.ConfigIndex = cfg->index;
1198
1199 /* Do we need to allocate an interrupt? */
1200 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
1201 link->conf.Attributes |= CONF_ENABLE_IRQ;
1202
1203 /* IO window settings */
1204 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1205 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1206 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1207 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1208 if (!(io->flags & CISTPL_IO_8BIT))
1209 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1210 if (!(io->flags & CISTPL_IO_16BIT))
1211 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1212 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1213 link->io.BasePort1 = io->win[0].base;
1214 link->io.NumPorts1 = io->win[0].len;
1215 if (io->nwin > 1) {
1216 link->io.Attributes2 = link->io.Attributes1;
1217 link->io.BasePort2 = io->win[1].base;
1218 link->io.NumPorts2 = io->win[1].len;
1219 }
1220 }
1221
1222 /* This reserves IO space but doesn't actually enable it */
1223 if (pcmcia_request_io(link, &link->io))
1224 goto next_entry;
1225
1226 /* If we got this far, we're cool! */
1227 break;
1228
1229 next_entry:
1230 if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) {
1231 cs_error(link, GetNextTuple, last_ret);
1232 goto cs_failed;
1233 }
1234 }
1235
1236 /*
1237 Allocate an interrupt line. Note that this does not assign a
1238 handler to the interrupt, unless the 'Handler' member of the
1239 irq structure is initialized.
1240 */
1241 if (link->conf.Attributes & CONF_ENABLE_IRQ)
1242 if ((last_ret = pcmcia_request_irq(link, &link->irq))) {
1243 cs_error(link, RequestIRQ, last_ret);
1244 goto cs_failed;
1245 }
1246
1247 /*
1248 This actually configures the PCMCIA socket -- setting up
1249 the I/O windows and the interrupt mapping, and putting the
1250 card and host interface into "Memory and IO" mode.
1251 */
1252 if ((last_ret = pcmcia_request_configuration(link, &link->conf))) {
1253 cs_error(link, RequestConfiguration, last_ret);
1254 goto cs_failed;
1255 }
1256
1257 /*
1258 At this point, the dev_node_t structure(s) need to be
1259 initialized and arranged in a linked list at link->dev.
1260 */
1261 /* Comedi's PCMCIA script uses this device name (extracted
1262 * from /var/lib/pcmcia/stab) to pass to comedi_config
1263 */
1264 /* sprintf(dev->node.dev_name, "daqp%d", dev->table_index); */
1265 sprintf(dev->node.dev_name, "quatech_daqp_cs");
1266 dev->node.major = dev->node.minor = 0;
1267 link->dev_node = &dev->node;
1268
1269 /* Finally, report what we've done */
1270 printk(KERN_INFO "%s: index 0x%02x",
1271 dev->node.dev_name, link->conf.ConfigIndex);
1272 if (link->conf.Attributes & CONF_ENABLE_IRQ)
1273 printk(", irq %u", link->irq.AssignedIRQ);
1274 if (link->io.NumPorts1)
1275 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1276 link->io.BasePort1 + link->io.NumPorts1 - 1);
1277 if (link->io.NumPorts2)
1278 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1279 link->io.BasePort2 + link->io.NumPorts2 - 1);
1280 printk("\n");
1281
1282 return;
1283
1284 cs_failed:
1285 daqp_cs_release(link);
1286
1287 } /* daqp_cs_config */
1288
1289 static void daqp_cs_release(struct pcmcia_device *link)
1290 {
1291 DEBUG(0, "daqp_cs_release(0x%p)\n", link);
1292
1293 pcmcia_disable_device(link);
1294 } /* daqp_cs_release */
1295
1296 /*======================================================================
1297
1298 The card status event handler. Mostly, this schedules other
1299 stuff to run after an event is received.
1300
1301 When a CARD_REMOVAL event is received, we immediately set a
1302 private flag to block future accesses to this device. All the
1303 functions that actually access the device should check this flag
1304 to make sure the card is still present.
1305
1306 ======================================================================*/
1307
1308 static int daqp_cs_suspend(struct pcmcia_device *link)
1309 {
1310 local_info_t *local = link->priv;
1311
1312 /* Mark the device as stopped, to block IO until later */
1313 local->stop = 1;
1314 return 0;
1315 }
1316
1317 static int daqp_cs_resume(struct pcmcia_device *link)
1318 {
1319 local_info_t *local = link->priv;
1320
1321 local->stop = 0;
1322
1323 return 0;
1324 }
1325
1326 /*====================================================================*/
1327
1328 #ifdef MODULE
1329
1330 static struct pcmcia_device_id daqp_cs_id_table[] = {
1331 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027),
1332 PCMCIA_DEVICE_NULL
1333 };
1334
1335 MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table);
1336
1337 struct pcmcia_driver daqp_cs_driver = {
1338 .probe = daqp_cs_attach,
1339 .remove = daqp_cs_detach,
1340 .suspend = daqp_cs_suspend,
1341 .resume = daqp_cs_resume,
1342 .id_table = daqp_cs_id_table,
1343 .owner = THIS_MODULE,
1344 .drv = {
1345 .name = dev_info,
1346 },
1347 };
1348
1349 int __init init_module(void)
1350 {
1351 DEBUG(0, "%s\n", version);
1352 pcmcia_register_driver(&daqp_cs_driver);
1353 comedi_driver_register(&driver_daqp);
1354 return 0;
1355 }
1356
1357 void __exit cleanup_module(void)
1358 {
1359 DEBUG(0, "daqp_cs: unloading\n");
1360 comedi_driver_unregister(&driver_daqp);
1361 pcmcia_unregister_driver(&daqp_cs_driver);
1362 }
1363
1364 #endif
This page took 0.058809 seconds and 6 git commands to generate.