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/* 43Driver: quatech_daqp_cs 44Description: Quatech DAQP PCMCIA data capture cards 45Author: Brent Baccala <baccala@freesoft.org> 46Status: works 47Devices: [Quatech] DAQP-208 (daqp), DAQP-308 48*/ 49 50#include <linux/module.h> 51#include "../comedidev.h" 52#include <linux/semaphore.h> 53 54#include <pcmcia/cistpl.h> 55#include <pcmcia/cisreg.h> 56#include <pcmcia/ds.h> 57 58#include <linux/completion.h> 59 60#include "comedi_fc.h" 61 62struct daqp_private { 63 int stop; 64 65 enum { semaphore, buffer } interrupt_mode; 66 67 struct completion eos; 68 69 int count; 70}; 71 72/* The DAQP communicates with the system through a 16 byte I/O window. */ 73 74#define DAQP_FIFO_SIZE 4096 75 76#define DAQP_FIFO 0 77#define DAQP_SCANLIST 1 78#define DAQP_CONTROL 2 79#define DAQP_STATUS 2 80#define DAQP_DIGITAL_IO 3 81#define DAQP_PACER_LOW 4 82#define DAQP_PACER_MID 5 83#define DAQP_PACER_HIGH 6 84#define DAQP_COMMAND 7 85#define DAQP_DA 8 86#define DAQP_TIMER 10 87#define DAQP_AUX 15 88 89#define DAQP_SCANLIST_DIFFERENTIAL 0x4000 90#define DAQP_SCANLIST_GAIN(x) ((x)<<12) 91#define DAQP_SCANLIST_CHANNEL(x) ((x)<<8) 92#define DAQP_SCANLIST_START 0x0080 93#define DAQP_SCANLIST_EXT_GAIN(x) ((x)<<4) 94#define DAQP_SCANLIST_EXT_CHANNEL(x) (x) 95 96#define DAQP_CONTROL_PACER_100kHz 0xc0 97#define DAQP_CONTROL_PACER_1MHz 0x80 98#define DAQP_CONTROL_PACER_5MHz 0x40 99#define DAQP_CONTROL_PACER_EXTERNAL 0x00 100#define DAQP_CONTORL_EXPANSION 0x20 101#define DAQP_CONTROL_EOS_INT_ENABLE 0x10 102#define DAQP_CONTROL_FIFO_INT_ENABLE 0x08 103#define DAQP_CONTROL_TRIGGER_ONESHOT 0x00 104#define DAQP_CONTROL_TRIGGER_CONTINUOUS 0x04 105#define DAQP_CONTROL_TRIGGER_INTERNAL 0x00 106#define DAQP_CONTROL_TRIGGER_EXTERNAL 0x02 107#define DAQP_CONTROL_TRIGGER_RISING 0x00 108#define DAQP_CONTROL_TRIGGER_FALLING 0x01 109 110#define DAQP_STATUS_IDLE 0x80 111#define DAQP_STATUS_RUNNING 0x40 112#define DAQP_STATUS_EVENTS 0x38 113#define DAQP_STATUS_DATA_LOST 0x20 114#define DAQP_STATUS_END_OF_SCAN 0x10 115#define DAQP_STATUS_FIFO_THRESHOLD 0x08 116#define DAQP_STATUS_FIFO_FULL 0x04 117#define DAQP_STATUS_FIFO_NEARFULL 0x02 118#define DAQP_STATUS_FIFO_EMPTY 0x01 119 120#define DAQP_COMMAND_ARM 0x80 121#define DAQP_COMMAND_RSTF 0x40 122#define DAQP_COMMAND_RSTQ 0x20 123#define DAQP_COMMAND_STOP 0x10 124#define DAQP_COMMAND_LATCH 0x08 125#define DAQP_COMMAND_100kHz 0x00 126#define DAQP_COMMAND_50kHz 0x02 127#define DAQP_COMMAND_25kHz 0x04 128#define DAQP_COMMAND_FIFO_DATA 0x01 129#define DAQP_COMMAND_FIFO_PROGRAM 0x00 130 131#define DAQP_AUX_TRIGGER_TTL 0x00 132#define DAQP_AUX_TRIGGER_ANALOG 0x80 133#define DAQP_AUX_TRIGGER_PRETRIGGER 0x40 134#define DAQP_AUX_TIMER_INT_ENABLE 0x20 135#define DAQP_AUX_TIMER_RELOAD 0x00 136#define DAQP_AUX_TIMER_PAUSE 0x08 137#define DAQP_AUX_TIMER_GO 0x10 138#define DAQP_AUX_TIMER_GO_EXTERNAL 0x18 139#define DAQP_AUX_TIMER_EXTERNAL_SRC 0x04 140#define DAQP_AUX_TIMER_INTERNAL_SRC 0x00 141#define DAQP_AUX_DA_DIRECT 0x00 142#define DAQP_AUX_DA_OVERFLOW 0x01 143#define DAQP_AUX_DA_EXTERNAL 0x02 144#define DAQP_AUX_DA_PACER 0x03 145 146#define DAQP_AUX_RUNNING 0x80 147#define DAQP_AUX_TRIGGERED 0x40 148#define DAQP_AUX_DA_BUFFER 0x20 149#define DAQP_AUX_TIMER_OVERFLOW 0x10 150#define DAQP_AUX_CONVERSION 0x08 151#define DAQP_AUX_DATA_LOST 0x04 152#define DAQP_AUX_FIFO_NEARFULL 0x02 153#define DAQP_AUX_FIFO_EMPTY 0x01 154 155static const struct comedi_lrange range_daqp_ai = { 156 4, { 157 BIP_RANGE(10), 158 BIP_RANGE(5), 159 BIP_RANGE(2.5), 160 BIP_RANGE(1.25) 161 } 162}; 163 164/* Cancel a running acquisition */ 165 166static int daqp_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 167{ 168 struct daqp_private *devpriv = dev->private; 169 170 if (devpriv->stop) 171 return -EIO; 172 173 outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND); 174 175 /* flush any linguring data in FIFO - superfluous here */ 176 /* outb(DAQP_COMMAND_RSTF, dev->iobase+DAQP_COMMAND); */ 177 178 devpriv->interrupt_mode = semaphore; 179 180 return 0; 181} 182 183/* Interrupt handler 184 * 185 * Operates in one of two modes. If devpriv->interrupt_mode is 186 * 'semaphore', just signal the devpriv->eos completion and return 187 * (one-shot mode). Otherwise (continuous mode), read data in from 188 * the card, transfer it to the buffer provided by the higher-level 189 * comedi kernel module, and signal various comedi callback routines, 190 * which run pretty quick. 191 */ 192static enum irqreturn daqp_interrupt(int irq, void *dev_id) 193{ 194 struct comedi_device *dev = dev_id; 195 struct daqp_private *devpriv = dev->private; 196 struct comedi_subdevice *s = dev->read_subdev; 197 int loop_limit = 10000; 198 int status; 199 200 if (!dev->attached) 201 return IRQ_NONE; 202 203 switch (devpriv->interrupt_mode) { 204 case semaphore: 205 complete(&devpriv->eos); 206 break; 207 208 case buffer: 209 while (!((status = inb(dev->iobase + DAQP_STATUS)) 210 & DAQP_STATUS_FIFO_EMPTY)) { 211 unsigned short data; 212 213 if (status & DAQP_STATUS_DATA_LOST) { 214 s->async->events |= 215 COMEDI_CB_EOA | COMEDI_CB_OVERFLOW; 216 dev_warn(dev->class_dev, "data lost\n"); 217 break; 218 } 219 220 data = inb(dev->iobase + DAQP_FIFO); 221 data |= inb(dev->iobase + DAQP_FIFO) << 8; 222 data ^= 0x8000; 223 224 comedi_buf_put(s, data); 225 226 /* If there's a limit, decrement it 227 * and stop conversion if zero 228 */ 229 230 if (devpriv->count > 0) { 231 devpriv->count--; 232 if (devpriv->count == 0) { 233 s->async->events |= COMEDI_CB_EOA; 234 break; 235 } 236 } 237 238 if ((loop_limit--) <= 0) 239 break; 240 } 241 242 if (loop_limit <= 0) { 243 dev_warn(dev->class_dev, 244 "loop_limit reached in daqp_interrupt()\n"); 245 s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 246 } 247 248 s->async->events |= COMEDI_CB_BLOCK; 249 250 cfc_handle_events(dev, s); 251 } 252 return IRQ_HANDLED; 253} 254 255static void daqp_ai_set_one_scanlist_entry(struct comedi_device *dev, 256 unsigned int chanspec, 257 int start) 258{ 259 unsigned int chan = CR_CHAN(chanspec); 260 unsigned int range = CR_RANGE(chanspec); 261 unsigned int aref = CR_AREF(chanspec); 262 unsigned int val; 263 264 val = DAQP_SCANLIST_CHANNEL(chan) | DAQP_SCANLIST_GAIN(range); 265 266 if (aref == AREF_DIFF) 267 val |= DAQP_SCANLIST_DIFFERENTIAL; 268 269 if (start) 270 val |= DAQP_SCANLIST_START; 271 272 outb(val & 0xff, dev->iobase + DAQP_SCANLIST); 273 outb((val >> 8) & 0xff, dev->iobase + DAQP_SCANLIST); 274} 275 276/* One-shot analog data acquisition routine */ 277 278static int daqp_ai_insn_read(struct comedi_device *dev, 279 struct comedi_subdevice *s, 280 struct comedi_insn *insn, unsigned int *data) 281{ 282 struct daqp_private *devpriv = dev->private; 283 int i; 284 int v; 285 int counter = 10000; 286 287 if (devpriv->stop) 288 return -EIO; 289 290 /* Stop any running conversion */ 291 daqp_ai_cancel(dev, s); 292 293 outb(0, dev->iobase + DAQP_AUX); 294 295 /* Reset scan list queue */ 296 outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND); 297 298 /* Program one scan list entry */ 299 daqp_ai_set_one_scanlist_entry(dev, insn->chanspec, 1); 300 301 /* Reset data FIFO (see page 28 of DAQP User's Manual) */ 302 303 outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND); 304 305 /* Set trigger */ 306 307 v = DAQP_CONTROL_TRIGGER_ONESHOT | DAQP_CONTROL_TRIGGER_INTERNAL 308 | DAQP_CONTROL_PACER_100kHz | DAQP_CONTROL_EOS_INT_ENABLE; 309 310 outb(v, dev->iobase + DAQP_CONTROL); 311 312 /* Reset any pending interrupts (my card has a tendency to require 313 * require multiple reads on the status register to achieve this) 314 */ 315 316 while (--counter 317 && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) 318 ; 319 if (!counter) { 320 dev_err(dev->class_dev, 321 "couldn't clear interrupts in status register\n"); 322 return -1; 323 } 324 325 init_completion(&devpriv->eos); 326 devpriv->interrupt_mode = semaphore; 327 328 for (i = 0; i < insn->n; i++) { 329 330 /* Start conversion */ 331 outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA, 332 dev->iobase + DAQP_COMMAND); 333 334 /* Wait for interrupt service routine to unblock completion */ 335 /* Maybe could use a timeout here, but it's interruptible */ 336 if (wait_for_completion_interruptible(&devpriv->eos)) 337 return -EINTR; 338 339 data[i] = inb(dev->iobase + DAQP_FIFO); 340 data[i] |= inb(dev->iobase + DAQP_FIFO) << 8; 341 data[i] ^= 0x8000; 342 } 343 344 return insn->n; 345} 346 347/* This function converts ns nanoseconds to a counter value suitable 348 * for programming the device. We always use the DAQP's 5 MHz clock, 349 * which with its 24-bit counter, allows values up to 84 seconds. 350 * Also, the function adjusts ns so that it cooresponds to the actual 351 * time that the device will use. 352 */ 353 354static int daqp_ns_to_timer(unsigned int *ns, unsigned int flags) 355{ 356 int timer; 357 358 timer = *ns / 200; 359 *ns = timer * 200; 360 361 return timer; 362} 363 364/* cmdtest tests a particular command to see if it is valid. 365 * Using the cmdtest ioctl, a user can create a valid cmd 366 * and then have it executed by the cmd ioctl. 367 * 368 * cmdtest returns 1,2,3,4 or 0, depending on which tests 369 * the command passes. 370 */ 371 372static int daqp_ai_cmdtest(struct comedi_device *dev, 373 struct comedi_subdevice *s, struct comedi_cmd *cmd) 374{ 375 int err = 0; 376 unsigned int arg; 377 378 /* Step 1 : check if triggers are trivially valid */ 379 380 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); 381 err |= cfc_check_trigger_src(&cmd->scan_begin_src, 382 TRIG_TIMER | TRIG_FOLLOW); 383 err |= cfc_check_trigger_src(&cmd->convert_src, 384 TRIG_TIMER | TRIG_NOW); 385 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 386 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 387 388 if (err) 389 return 1; 390 391 /* Step 2a : make sure trigger sources are unique */ 392 393 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); 394 err |= cfc_check_trigger_is_unique(cmd->convert_src); 395 err |= cfc_check_trigger_is_unique(cmd->stop_src); 396 397 /* Step 2b : and mutually compatible */ 398 399 if (err) 400 return 2; 401 402 /* Step 3: check if arguments are trivially valid */ 403 404 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 405 406#define MAX_SPEED 10000 /* 100 kHz - in nanoseconds */ 407 408 if (cmd->scan_begin_src == TRIG_TIMER) 409 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 410 MAX_SPEED); 411 412 /* If both scan_begin and convert are both timer values, the only 413 * way that can make sense is if the scan time is the number of 414 * conversions times the convert time 415 */ 416 417 if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER 418 && cmd->scan_begin_arg != cmd->convert_arg * cmd->scan_end_arg) { 419 err |= -EINVAL; 420 } 421 422 if (cmd->convert_src == TRIG_TIMER) 423 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, MAX_SPEED); 424 425 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 426 427 if (cmd->stop_src == TRIG_COUNT) 428 err |= cfc_check_trigger_arg_max(&cmd->stop_arg, 0x00ffffff); 429 else /* TRIG_NONE */ 430 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 431 432 if (err) 433 return 3; 434 435 /* step 4: fix up any arguments */ 436 437 if (cmd->scan_begin_src == TRIG_TIMER) { 438 arg = cmd->scan_begin_arg; 439 daqp_ns_to_timer(&arg, cmd->flags); 440 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg); 441 } 442 443 if (cmd->convert_src == TRIG_TIMER) { 444 arg = cmd->convert_arg; 445 daqp_ns_to_timer(&arg, cmd->flags); 446 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg); 447 } 448 449 if (err) 450 return 4; 451 452 return 0; 453} 454 455static int daqp_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 456{ 457 struct daqp_private *devpriv = dev->private; 458 struct comedi_cmd *cmd = &s->async->cmd; 459 int counter; 460 int scanlist_start_on_every_entry; 461 int threshold; 462 463 int i; 464 int v; 465 466 if (devpriv->stop) 467 return -EIO; 468 469 /* Stop any running conversion */ 470 daqp_ai_cancel(dev, s); 471 472 outb(0, dev->iobase + DAQP_AUX); 473 474 /* Reset scan list queue */ 475 outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND); 476 477 /* Program pacer clock 478 * 479 * There's two modes we can operate in. If convert_src is 480 * TRIG_TIMER, then convert_arg specifies the time between 481 * each conversion, so we program the pacer clock to that 482 * frequency and set the SCANLIST_START bit on every scanlist 483 * entry. Otherwise, convert_src is TRIG_NOW, which means 484 * we want the fastest possible conversions, scan_begin_src 485 * is TRIG_TIMER, and scan_begin_arg specifies the time between 486 * each scan, so we program the pacer clock to this frequency 487 * and only set the SCANLIST_START bit on the first entry. 488 */ 489 490 if (cmd->convert_src == TRIG_TIMER) { 491 counter = daqp_ns_to_timer(&cmd->convert_arg, cmd->flags); 492 outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW); 493 outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID); 494 outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH); 495 scanlist_start_on_every_entry = 1; 496 } else { 497 counter = daqp_ns_to_timer(&cmd->scan_begin_arg, cmd->flags); 498 outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW); 499 outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID); 500 outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH); 501 scanlist_start_on_every_entry = 0; 502 } 503 504 /* Program scan list */ 505 for (i = 0; i < cmd->chanlist_len; i++) { 506 int start = (i == 0 || scanlist_start_on_every_entry); 507 508 daqp_ai_set_one_scanlist_entry(dev, cmd->chanlist[i], start); 509 } 510 511 /* Now it's time to program the FIFO threshold, basically the 512 * number of samples the card will buffer before it interrupts 513 * the CPU. 514 * 515 * If we don't have a stop count, then use half the size of 516 * the FIFO (the manufacturer's recommendation). Consider 517 * that the FIFO can hold 2K samples (4K bytes). With the 518 * threshold set at half the FIFO size, we have a margin of 519 * error of 1024 samples. At the chip's maximum sample rate 520 * of 100,000 Hz, the CPU would have to delay interrupt 521 * service for a full 10 milliseconds in order to lose data 522 * here (as opposed to higher up in the kernel). I've never 523 * seen it happen. However, for slow sample rates it may 524 * buffer too much data and introduce too much delay for the 525 * user application. 526 * 527 * If we have a stop count, then things get more interesting. 528 * If the stop count is less than the FIFO size (actually 529 * three-quarters of the FIFO size - see below), we just use 530 * the stop count itself as the threshold, the card interrupts 531 * us when that many samples have been taken, and we kill the 532 * acquisition at that point and are done. If the stop count 533 * is larger than that, then we divide it by 2 until it's less 534 * than three quarters of the FIFO size (we always leave the 535 * top quarter of the FIFO as protection against sluggish CPU 536 * interrupt response) and use that as the threshold. So, if 537 * the stop count is 4000 samples, we divide by two twice to 538 * get 1000 samples, use that as the threshold, take four 539 * interrupts to get our 4000 samples and are done. 540 * 541 * The algorithm could be more clever. For example, if 81000 542 * samples are requested, we could set the threshold to 1500 543 * samples and take 54 interrupts to get 81000. But 54 isn't 544 * a power of two, so this algorithm won't find that option. 545 * Instead, it'll set the threshold at 1266 and take 64 546 * interrupts to get 81024 samples, of which the last 24 will 547 * be discarded... but we won't get the last interrupt until 548 * they've been collected. To find the first option, the 549 * computer could look at the prime decomposition of the 550 * sample count (81000 = 3^4 * 5^3 * 2^3) and factor it into a 551 * threshold (1500 = 3 * 5^3 * 2^2) and an interrupt count (54 552 * = 3^3 * 2). Hmmm... a one-line while loop or prime 553 * decomposition of integers... I'll leave it the way it is. 554 * 555 * I'll also note a mini-race condition before ignoring it in 556 * the code. Let's say we're taking 4000 samples, as before. 557 * After 1000 samples, we get an interrupt. But before that 558 * interrupt is completely serviced, another sample is taken 559 * and loaded into the FIFO. Since the interrupt handler 560 * empties the FIFO before returning, it will read 1001 samples. 561 * If that happens four times, we'll end up taking 4004 samples, 562 * not 4000. The interrupt handler will discard the extra four 563 * samples (by halting the acquisition with four samples still 564 * in the FIFO), but we will have to wait for them. 565 * 566 * In short, this code works pretty well, but for either of 567 * the two reasons noted, might end up waiting for a few more 568 * samples than actually requested. Shouldn't make too much 569 * of a difference. 570 */ 571 572 /* Save away the number of conversions we should perform, and 573 * compute the FIFO threshold (in bytes, not samples - that's 574 * why we multiple devpriv->count by 2 = sizeof(sample)) 575 */ 576 577 if (cmd->stop_src == TRIG_COUNT) { 578 devpriv->count = cmd->stop_arg * cmd->scan_end_arg; 579 threshold = 2 * devpriv->count; 580 while (threshold > DAQP_FIFO_SIZE * 3 / 4) 581 threshold /= 2; 582 } else { 583 devpriv->count = -1; 584 threshold = DAQP_FIFO_SIZE / 2; 585 } 586 587 /* Reset data FIFO (see page 28 of DAQP User's Manual) */ 588 589 outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND); 590 591 /* Set FIFO threshold. First two bytes are near-empty 592 * threshold, which is unused; next two bytes are near-full 593 * threshold. We computed the number of bytes we want in the 594 * FIFO when the interrupt is generated, what the card wants 595 * is actually the number of available bytes left in the FIFO 596 * when the interrupt is to happen. 597 */ 598 599 outb(0x00, dev->iobase + DAQP_FIFO); 600 outb(0x00, dev->iobase + DAQP_FIFO); 601 602 outb((DAQP_FIFO_SIZE - threshold) & 0xff, dev->iobase + DAQP_FIFO); 603 outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_FIFO); 604 605 /* Set trigger */ 606 607 v = DAQP_CONTROL_TRIGGER_CONTINUOUS | DAQP_CONTROL_TRIGGER_INTERNAL 608 | DAQP_CONTROL_PACER_5MHz | DAQP_CONTROL_FIFO_INT_ENABLE; 609 610 outb(v, dev->iobase + DAQP_CONTROL); 611 612 /* Reset any pending interrupts (my card has a tendency to require 613 * require multiple reads on the status register to achieve this) 614 */ 615 counter = 100; 616 while (--counter 617 && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) 618 ; 619 if (!counter) { 620 dev_err(dev->class_dev, 621 "couldn't clear interrupts in status register\n"); 622 return -1; 623 } 624 625 devpriv->interrupt_mode = buffer; 626 627 /* Start conversion */ 628 outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA, 629 dev->iobase + DAQP_COMMAND); 630 631 return 0; 632} 633 634static int daqp_ao_insn_write(struct comedi_device *dev, 635 struct comedi_subdevice *s, 636 struct comedi_insn *insn, 637 unsigned int *data) 638{ 639 struct daqp_private *devpriv = dev->private; 640 unsigned int chan = CR_CHAN(insn->chanspec); 641 int i; 642 643 if (devpriv->stop) 644 return -EIO; 645 646 /* Make sure D/A update mode is direct update */ 647 outb(0, dev->iobase + DAQP_AUX); 648 649 for (i = 0; i > insn->n; i++) { 650 unsigned val = data[i]; 651 652 s->readback[chan] = val; 653 654 val &= 0x0fff; 655 val ^= 0x0800; /* Flip the sign */ 656 val |= (chan << 12); 657 658 outw(val, dev->iobase + DAQP_DA); 659 } 660 661 return insn->n; 662} 663 664static int daqp_di_insn_bits(struct comedi_device *dev, 665 struct comedi_subdevice *s, 666 struct comedi_insn *insn, 667 unsigned int *data) 668{ 669 struct daqp_private *devpriv = dev->private; 670 671 if (devpriv->stop) 672 return -EIO; 673 674 data[0] = inb(dev->iobase + DAQP_DIGITAL_IO); 675 676 return insn->n; 677} 678 679static int daqp_do_insn_bits(struct comedi_device *dev, 680 struct comedi_subdevice *s, 681 struct comedi_insn *insn, 682 unsigned int *data) 683{ 684 struct daqp_private *devpriv = dev->private; 685 686 if (devpriv->stop) 687 return -EIO; 688 689 if (comedi_dio_update_state(s, data)) 690 outb(s->state, dev->iobase + DAQP_DIGITAL_IO); 691 692 data[1] = s->state; 693 694 return insn->n; 695} 696 697static int daqp_auto_attach(struct comedi_device *dev, 698 unsigned long context) 699{ 700 struct pcmcia_device *link = comedi_to_pcmcia_dev(dev); 701 struct daqp_private *devpriv; 702 struct comedi_subdevice *s; 703 int ret; 704 705 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 706 if (!devpriv) 707 return -ENOMEM; 708 709 link->config_flags |= CONF_AUTO_SET_IO | CONF_ENABLE_IRQ; 710 ret = comedi_pcmcia_enable(dev, NULL); 711 if (ret) 712 return ret; 713 dev->iobase = link->resource[0]->start; 714 715 link->priv = dev; 716 ret = pcmcia_request_irq(link, daqp_interrupt); 717 if (ret) 718 return ret; 719 720 ret = comedi_alloc_subdevices(dev, 4); 721 if (ret) 722 return ret; 723 724 s = &dev->subdevices[0]; 725 dev->read_subdev = s; 726 s->type = COMEDI_SUBD_AI; 727 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 728 s->n_chan = 8; 729 s->len_chanlist = 2048; 730 s->maxdata = 0xffff; 731 s->range_table = &range_daqp_ai; 732 s->insn_read = daqp_ai_insn_read; 733 s->do_cmdtest = daqp_ai_cmdtest; 734 s->do_cmd = daqp_ai_cmd; 735 s->cancel = daqp_ai_cancel; 736 737 s = &dev->subdevices[1]; 738 s->type = COMEDI_SUBD_AO; 739 s->subdev_flags = SDF_WRITEABLE; 740 s->n_chan = 2; 741 s->maxdata = 0x0fff; 742 s->range_table = &range_bipolar5; 743 s->insn_write = daqp_ao_insn_write; 744 s->insn_read = comedi_readback_insn_read; 745 746 ret = comedi_alloc_subdev_readback(s); 747 if (ret) 748 return ret; 749 750 s = &dev->subdevices[2]; 751 s->type = COMEDI_SUBD_DI; 752 s->subdev_flags = SDF_READABLE; 753 s->n_chan = 1; 754 s->maxdata = 1; 755 s->insn_bits = daqp_di_insn_bits; 756 757 s = &dev->subdevices[3]; 758 s->type = COMEDI_SUBD_DO; 759 s->subdev_flags = SDF_WRITEABLE; 760 s->n_chan = 1; 761 s->maxdata = 1; 762 s->insn_bits = daqp_do_insn_bits; 763 764 return 0; 765} 766 767static struct comedi_driver driver_daqp = { 768 .driver_name = "quatech_daqp_cs", 769 .module = THIS_MODULE, 770 .auto_attach = daqp_auto_attach, 771 .detach = comedi_pcmcia_disable, 772}; 773 774static int daqp_cs_suspend(struct pcmcia_device *link) 775{ 776 struct comedi_device *dev = link->priv; 777 struct daqp_private *devpriv = dev ? dev->private : NULL; 778 779 /* Mark the device as stopped, to block IO until later */ 780 if (devpriv) 781 devpriv->stop = 1; 782 783 return 0; 784} 785 786static int daqp_cs_resume(struct pcmcia_device *link) 787{ 788 struct comedi_device *dev = link->priv; 789 struct daqp_private *devpriv = dev ? dev->private : NULL; 790 791 if (devpriv) 792 devpriv->stop = 0; 793 794 return 0; 795} 796 797static int daqp_cs_attach(struct pcmcia_device *link) 798{ 799 return comedi_pcmcia_auto_config(link, &driver_daqp); 800} 801 802static const struct pcmcia_device_id daqp_cs_id_table[] = { 803 PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027), 804 PCMCIA_DEVICE_NULL 805}; 806MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table); 807 808static struct pcmcia_driver daqp_cs_driver = { 809 .name = "quatech_daqp_cs", 810 .owner = THIS_MODULE, 811 .id_table = daqp_cs_id_table, 812 .probe = daqp_cs_attach, 813 .remove = comedi_pcmcia_auto_unconfig, 814 .suspend = daqp_cs_suspend, 815 .resume = daqp_cs_resume, 816}; 817module_comedi_pcmcia_driver(driver_daqp, daqp_cs_driver); 818 819MODULE_DESCRIPTION("Comedi driver for Quatech DAQP PCMCIA data capture cards"); 820MODULE_AUTHOR("Brent Baccala <baccala@freesoft.org>"); 821MODULE_LICENSE("GPL"); 822