ni_at_a2150.c revision 71b5f4f11971dea972832ad63a994c7e5b45db6b
1/* 2 comedi/drivers/ni_at_a2150.c 3 Driver for National Instruments AT-A2150 boards 4 Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net> 5 6 COMEDI - Linux Control and Measurement Device Interface 7 Copyright (C) 2000 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_at_a2150 27Description: National Instruments AT-A2150 28Author: Frank Mori Hess 29Status: works 30Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s) 31 32If you want to ac couple the board's inputs, use AREF_OTHER. 33 34Configuration options: 35 [0] - I/O port base address 36 [1] - IRQ (optional, required for timed conversions) 37 [2] - DMA (optional, required for timed conversions) 38 39*/ 40/* 41Yet another driver for obsolete hardware brought to you by Frank Hess. 42Testing and debugging help provided by Dave Andruczyk. 43 44This driver supports the boards: 45 46AT-A2150C 47AT-A2150S 48 49The only difference is their master clock frequencies. 50 51Options: 52 [0] - base io address 53 [1] - irq 54 [2] - dma channel 55 56References (from ftp://ftp.natinst.com/support/manuals): 57 58 320360.pdf AT-A2150 User Manual 59 60TODO: 61 62analog level triggering 63TRIG_WAKE_EOS 64 65*/ 66 67#include "../comedidev.h" 68 69#include <linux/ioport.h> 70#include <asm/dma.h> 71 72#include "8253.h" 73#include "comedi_fc.h" 74 75#define A2150_SIZE 28 76#define A2150_DMA_BUFFER_SIZE 0xff00 // size in bytes of dma buffer 77 78//#define A2150_DEBUG // enable debugging code 79#undef A2150_DEBUG // disable debugging code 80 81/* Registers and bits */ 82#define CONFIG_REG 0x0 83#define CHANNEL_BITS(x) ((x) & 0x7) 84#define CHANNEL_MASK 0x7 85#define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3) 86#define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5) 87#define CLOCK_MASK (0xf << 3) 88#define ENABLE0_BIT 0x80 // enable (don't internally ground) channels 0 and 1 89#define ENABLE1_BIT 0x100 // enable (don't internally ground) channels 2 and 3 90#define AC0_BIT 0x200 // ac couple channels 0,1 91#define AC1_BIT 0x400 // ac couple channels 2,3 92#define APD_BIT 0x800 // analog power down 93#define DPD_BIT 0x1000 // digital power down 94#define TRIGGER_REG 0x2 // trigger config register 95#define POST_TRIGGER_BITS 0x2 96#define DELAY_TRIGGER_BITS 0x3 97#define HW_TRIG_EN 0x10 // enable hardware trigger 98#define FIFO_START_REG 0x6 // software start aquistion trigger 99#define FIFO_RESET_REG 0x8 // clears fifo + fifo flags 100#define FIFO_DATA_REG 0xa // read data 101#define DMA_TC_CLEAR_REG 0xe // clear dma terminal count interrupt 102#define STATUS_REG 0x12 // read only 103#define FNE_BIT 0x1 // fifo not empty 104#define OVFL_BIT 0x8 // fifo overflow 105#define EDAQ_BIT 0x10 // end of aquisition interrupt 106#define DCAL_BIT 0x20 // offset calibration in progress 107#define INTR_BIT 0x40 // interrupt has occured 108#define DMA_TC_BIT 0x80 // dma terminal count interrupt has occured 109#define ID_BITS(x) (((x) >> 8) & 0x3) 110#define IRQ_DMA_CNTRL_REG 0x12 // write only 111#define DMA_CHAN_BITS(x) ((x) & 0x7) // sets dma channel 112#define DMA_EN_BIT 0x8 // enables dma 113#define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) // sets irq level 114#define FIFO_INTR_EN_BIT 0x100 // enable fifo interrupts 115#define FIFO_INTR_FHF_BIT 0x200 // interrupt fifo half full 116#define DMA_INTR_EN_BIT 0x800 // enable interrupt on dma terminal count 117#define DMA_DEM_EN_BIT 0x1000 // enables demand mode dma 118#define I8253_BASE_REG 0x14 119#define I8253_MODE_REG 0x17 120#define HW_COUNT_DISABLE 0x30 // disable hardware counting of conversions 121 122typedef struct a2150_board_struct { 123 const char *name; 124 int clock[4]; // master clock periods, in nanoseconds 125 int num_clocks; // number of available master clock speeds 126 int ai_speed; // maximum conversion rate in nanoseconds 127} a2150_board; 128 129//analog input range 130static const comedi_lrange range_a2150 = { 131 1, 132 { 133 RANGE(-2.828, 2.828), 134 } 135}; 136 137// enum must match board indices 138enum { a2150_c, a2150_s }; 139static const a2150_board a2150_boards[] = { 140 { 141 name: "at-a2150c", 142 clock: {31250, 22676, 20833, 19531}, 143 num_clocks:4, 144 ai_speed:19531, 145 }, 146 { 147 name: "at-a2150s", 148 clock: {62500, 50000, 41667, 0}, 149 num_clocks:3, 150 ai_speed:41667, 151 }, 152}; 153 154/* 155 * Useful for shorthand access to the particular board structure 156 */ 157#define thisboard ((const a2150_board *)dev->board_ptr) 158 159typedef struct { 160 volatile unsigned int count; /* number of data points left to be taken */ 161 unsigned int dma; // dma channel 162 s16 *dma_buffer; // dma buffer 163 unsigned int dma_transfer_size; // size in bytes of dma transfers 164 int irq_dma_bits; // irq/dma register bits 165 int config_bits; // config register bits 166} a2150_private; 167 168#define devpriv ((a2150_private *)dev->private) 169 170static int a2150_attach(struct comedi_device * dev, comedi_devconfig * it); 171static int a2150_detach(struct comedi_device * dev); 172static int a2150_cancel(struct comedi_device * dev, comedi_subdevice * s); 173 174static comedi_driver driver_a2150 = { 175 driver_name:"ni_at_a2150", 176 module:THIS_MODULE, 177 attach:a2150_attach, 178 detach:a2150_detach, 179}; 180 181static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG); 182static int a2150_ai_cmdtest(struct comedi_device * dev, comedi_subdevice * s, 183 comedi_cmd * cmd); 184static int a2150_ai_cmd(struct comedi_device * dev, comedi_subdevice * s); 185static int a2150_ai_rinsn(struct comedi_device * dev, comedi_subdevice * s, 186 comedi_insn * insn, unsigned int * data); 187static int a2150_get_timing(struct comedi_device * dev, unsigned int *period, 188 int flags); 189static int a2150_probe(struct comedi_device * dev); 190static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel, 191 unsigned int num_channels); 192/* 193 * A convenient macro that defines init_module() and cleanup_module(), 194 * as necessary. 195 */ 196COMEDI_INITCLEANUP(driver_a2150); 197 198#ifdef A2150_DEBUG 199 200static void ni_dump_regs(struct comedi_device * dev) 201{ 202 rt_printk("config bits 0x%x\n", devpriv->config_bits); 203 rt_printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits); 204 rt_printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG)); 205} 206 207#endif 208 209/* interrupt service routine */ 210static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG) 211{ 212 int i; 213 int status; 214 unsigned long flags; 215 struct comedi_device *dev = d; 216 comedi_subdevice *s = dev->read_subdev; 217 comedi_async *async; 218 comedi_cmd *cmd; 219 unsigned int max_points, num_points, residue, leftover; 220 short dpnt; 221 static const int sample_size = sizeof(devpriv->dma_buffer[0]); 222 223 if (dev->attached == 0) { 224 comedi_error(dev, "premature interrupt"); 225 return IRQ_HANDLED; 226 } 227 // initialize async here to make sure s is not NULL 228 async = s->async; 229 async->events = 0; 230 cmd = &async->cmd; 231 232 status = inw(dev->iobase + STATUS_REG); 233 234 if ((status & INTR_BIT) == 0) { 235 comedi_error(dev, "spurious interrupt"); 236 return IRQ_NONE; 237 } 238 239 if (status & OVFL_BIT) { 240 comedi_error(dev, "fifo overflow"); 241 a2150_cancel(dev, s); 242 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 243 } 244 245 if ((status & DMA_TC_BIT) == 0) { 246 comedi_error(dev, "caught non-dma interrupt? Aborting."); 247 a2150_cancel(dev, s); 248 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 249 comedi_event(dev, s); 250 return IRQ_HANDLED; 251 } 252 253 flags = claim_dma_lock(); 254 disable_dma(devpriv->dma); 255 /* clear flip-flop to make sure 2-byte registers for 256 * count and address get set correctly */ 257 clear_dma_ff(devpriv->dma); 258 259 // figure out how many points to read 260 max_points = devpriv->dma_transfer_size / sample_size; 261 /* residue is the number of points left to be done on the dma 262 * transfer. It should always be zero at this point unless 263 * the stop_src is set to external triggering. 264 */ 265 residue = get_dma_residue(devpriv->dma) / sample_size; 266 num_points = max_points - residue; 267 if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT) 268 num_points = devpriv->count; 269 270 // figure out how many points will be stored next time 271 leftover = 0; 272 if (cmd->stop_src == TRIG_NONE) { 273 leftover = devpriv->dma_transfer_size / sample_size; 274 } else if (devpriv->count > max_points) { 275 leftover = devpriv->count - max_points; 276 if (leftover > max_points) 277 leftover = max_points; 278 } 279 /* there should only be a residue if collection was stopped by having 280 * the stop_src set to an external trigger, in which case there 281 * will be no more data 282 */ 283 if (residue) 284 leftover = 0; 285 286 for (i = 0; i < num_points; i++) { 287 /* write data point to comedi buffer */ 288 dpnt = devpriv->dma_buffer[i]; 289 // convert from 2's complement to unsigned coding 290 dpnt ^= 0x8000; 291 cfc_write_to_buffer(s, dpnt); 292 if (cmd->stop_src == TRIG_COUNT) { 293 if (--devpriv->count == 0) { /* end of acquisition */ 294 a2150_cancel(dev, s); 295 async->events |= COMEDI_CB_EOA; 296 break; 297 } 298 } 299 } 300 // re-enable dma 301 if (leftover) { 302 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer)); 303 set_dma_count(devpriv->dma, leftover * sample_size); 304 enable_dma(devpriv->dma); 305 } 306 release_dma_lock(flags); 307 308 async->events |= COMEDI_CB_BLOCK; 309 310 comedi_event(dev, s); 311 312 /* clear interrupt */ 313 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG); 314 315 return IRQ_HANDLED; 316} 317 318// probes board type, returns offset 319static int a2150_probe(struct comedi_device * dev) 320{ 321 int status = inw(dev->iobase + STATUS_REG); 322 return ID_BITS(status); 323} 324 325static int a2150_attach(struct comedi_device * dev, comedi_devconfig * it) 326{ 327 comedi_subdevice *s; 328 unsigned long iobase = it->options[0]; 329 unsigned int irq = it->options[1]; 330 unsigned int dma = it->options[2]; 331 static const int timeout = 2000; 332 int i; 333 334 printk("comedi%d: %s: io 0x%lx", dev->minor, driver_a2150.driver_name, 335 iobase); 336 if (irq) { 337 printk(", irq %u", irq); 338 } else { 339 printk(", no irq"); 340 } 341 if (dma) { 342 printk(", dma %u", dma); 343 } else { 344 printk(", no dma"); 345 } 346 printk("\n"); 347 348 /* allocate and initialize dev->private */ 349 if (alloc_private(dev, sizeof(a2150_private)) < 0) 350 return -ENOMEM; 351 352 if (iobase == 0) { 353 printk(" io base address required\n"); 354 return -EINVAL; 355 } 356 357 /* check if io addresses are available */ 358 if (!request_region(iobase, A2150_SIZE, driver_a2150.driver_name)) { 359 printk(" I/O port conflict\n"); 360 return -EIO; 361 } 362 dev->iobase = iobase; 363 364 /* grab our IRQ */ 365 if (irq) { 366 // check that irq is supported 367 if (irq < 3 || irq == 8 || irq == 13 || irq > 15) { 368 printk(" invalid irq line %u\n", irq); 369 return -EINVAL; 370 } 371 if (comedi_request_irq(irq, a2150_interrupt, 0, 372 driver_a2150.driver_name, dev)) { 373 printk("unable to allocate irq %u\n", irq); 374 return -EINVAL; 375 } 376 devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq); 377 dev->irq = irq; 378 } 379 // initialize dma 380 if (dma) { 381 if (dma == 4 || dma > 7) { 382 printk(" invalid dma channel %u\n", dma); 383 return -EINVAL; 384 } 385 if (request_dma(dma, driver_a2150.driver_name)) { 386 printk(" failed to allocate dma channel %u\n", dma); 387 return -EINVAL; 388 } 389 devpriv->dma = dma; 390 devpriv->dma_buffer = 391 kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA); 392 if (devpriv->dma_buffer == NULL) 393 return -ENOMEM; 394 395 disable_dma(dma); 396 set_dma_mode(dma, DMA_MODE_READ); 397 398 devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma); 399 } 400 401 dev->board_ptr = a2150_boards + a2150_probe(dev); 402 dev->board_name = thisboard->name; 403 404 if (alloc_subdevices(dev, 1) < 0) 405 return -ENOMEM; 406 407 /* analog input subdevice */ 408 s = dev->subdevices + 0; 409 dev->read_subdev = s; 410 s->type = COMEDI_SUBD_AI; 411 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ; 412 s->n_chan = 4; 413 s->len_chanlist = 4; 414 s->maxdata = 0xffff; 415 s->range_table = &range_a2150; 416 s->do_cmd = a2150_ai_cmd; 417 s->do_cmdtest = a2150_ai_cmdtest; 418 s->insn_read = a2150_ai_rinsn; 419 s->cancel = a2150_cancel; 420 421 /* need to do this for software counting of completed conversions, to 422 * prevent hardware count from stopping aquisition */ 423 outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG); 424 425 // set card's irq and dma levels 426 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG); 427 428 // reset and sync adc clock circuitry 429 outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG); 430 outw_p(DPD_BIT, dev->iobase + CONFIG_REG); 431 // initialize configuration register 432 devpriv->config_bits = 0; 433 outw(devpriv->config_bits, dev->iobase + CONFIG_REG); 434 // wait until offset calibration is done, then enable analog inputs 435 for (i = 0; i < timeout; i++) { 436 if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0) 437 break; 438 comedi_udelay(1000); 439 } 440 if (i == timeout) { 441 printk(" timed out waiting for offset calibration to complete\n"); 442 return -ETIME; 443 } 444 devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT; 445 outw(devpriv->config_bits, dev->iobase + CONFIG_REG); 446 447 return 0; 448}; 449 450static int a2150_detach(struct comedi_device * dev) 451{ 452 printk("comedi%d: %s: remove\n", dev->minor, driver_a2150.driver_name); 453 454 /* only free stuff if it has been allocated by _attach */ 455 if (dev->iobase) { 456 // put board in power-down mode 457 outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG); 458 release_region(dev->iobase, A2150_SIZE); 459 } 460 461 if (dev->irq) 462 comedi_free_irq(dev->irq, dev); 463 if (devpriv) { 464 if (devpriv->dma) 465 free_dma(devpriv->dma); 466 if (devpriv->dma_buffer) 467 kfree(devpriv->dma_buffer); 468 } 469 470 return 0; 471}; 472 473static int a2150_cancel(struct comedi_device * dev, comedi_subdevice * s) 474{ 475 // disable dma on card 476 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT; 477 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG); 478 479 // disable computer's dma 480 disable_dma(devpriv->dma); 481 482 // clear fifo and reset triggering circuitry 483 outw(0, dev->iobase + FIFO_RESET_REG); 484 485 return 0; 486} 487 488static int a2150_ai_cmdtest(struct comedi_device * dev, comedi_subdevice * s, 489 comedi_cmd * cmd) 490{ 491 int err = 0; 492 int tmp; 493 int startChan; 494 int i; 495 496 /* step 1: make sure trigger sources are trivially valid */ 497 498 tmp = cmd->start_src; 499 cmd->start_src &= TRIG_NOW | TRIG_EXT; 500 if (!cmd->start_src || tmp != cmd->start_src) 501 err++; 502 503 tmp = cmd->scan_begin_src; 504 cmd->scan_begin_src &= TRIG_TIMER; 505 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 506 err++; 507 508 tmp = cmd->convert_src; 509 cmd->convert_src &= TRIG_NOW; 510 if (!cmd->convert_src || tmp != cmd->convert_src) 511 err++; 512 513 tmp = cmd->scan_end_src; 514 cmd->scan_end_src &= TRIG_COUNT; 515 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 516 err++; 517 518 tmp = cmd->stop_src; 519 cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 520 if (!cmd->stop_src || tmp != cmd->stop_src) 521 err++; 522 523 if (err) 524 return 1; 525 526 /* step 2: make sure trigger sources are unique and mutually compatible */ 527 528 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 529 err++; 530 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 531 err++; 532 533 if (err) 534 return 2; 535 536 /* step 3: make sure arguments are trivially compatible */ 537 538 if (cmd->start_arg != 0) { 539 cmd->start_arg = 0; 540 err++; 541 } 542 if (cmd->convert_src == TRIG_TIMER) { 543 if (cmd->convert_arg < thisboard->ai_speed) { 544 cmd->convert_arg = thisboard->ai_speed; 545 err++; 546 } 547 } 548 if (!cmd->chanlist_len) { 549 cmd->chanlist_len = 1; 550 err++; 551 } 552 if (cmd->scan_end_arg != cmd->chanlist_len) { 553 cmd->scan_end_arg = cmd->chanlist_len; 554 err++; 555 } 556 if (cmd->stop_src == TRIG_COUNT) { 557 if (!cmd->stop_arg) { 558 cmd->stop_arg = 1; 559 err++; 560 } 561 } else { /* TRIG_NONE */ 562 if (cmd->stop_arg != 0) { 563 cmd->stop_arg = 0; 564 err++; 565 } 566 } 567 568 if (err) 569 return 3; 570 571 /* step 4: fix up any arguments */ 572 573 if (cmd->scan_begin_src == TRIG_TIMER) { 574 tmp = cmd->scan_begin_arg; 575 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags); 576 if (tmp != cmd->scan_begin_arg) 577 err++; 578 } 579 580 if (err) 581 return 4; 582 583 // check channel/gain list against card's limitations 584 if (cmd->chanlist) { 585 startChan = CR_CHAN(cmd->chanlist[0]); 586 for (i = 1; i < cmd->chanlist_len; i++) { 587 if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) { 588 comedi_error(dev, 589 "entries in chanlist must be consecutive channels, counting upwards\n"); 590 err++; 591 } 592 } 593 if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) { 594 comedi_error(dev, 595 "length 2 chanlist must be channels 0,1 or channels 2,3"); 596 err++; 597 } 598 if (cmd->chanlist_len == 3) { 599 comedi_error(dev, 600 "chanlist must have 1,2 or 4 channels"); 601 err++; 602 } 603 if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) || 604 CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3])) 605 { 606 comedi_error(dev, 607 "channels 0/1 and 2/3 must have the same analog reference"); 608 err++; 609 } 610 } 611 612 if (err) 613 return 5; 614 615 return 0; 616} 617 618static int a2150_ai_cmd(struct comedi_device * dev, comedi_subdevice * s) 619{ 620 comedi_async *async = s->async; 621 comedi_cmd *cmd = &async->cmd; 622 unsigned long lock_flags; 623 unsigned int old_config_bits = devpriv->config_bits; 624 unsigned int trigger_bits; 625 626 if (!dev->irq || !devpriv->dma) { 627 comedi_error(dev, 628 " irq and dma required, cannot do hardware conversions"); 629 return -1; 630 } 631 if (cmd->flags & TRIG_RT) { 632 comedi_error(dev, 633 " dma incompatible with hard real-time interrupt (TRIG_RT), aborting"); 634 return -1; 635 } 636 // clear fifo and reset triggering circuitry 637 outw(0, dev->iobase + FIFO_RESET_REG); 638 639 /* setup chanlist */ 640 if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]), 641 cmd->chanlist_len) < 0) 642 return -1; 643 644 // setup ac/dc coupling 645 if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER) 646 devpriv->config_bits |= AC0_BIT; 647 else 648 devpriv->config_bits &= ~AC0_BIT; 649 if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER) 650 devpriv->config_bits |= AC1_BIT; 651 else 652 devpriv->config_bits &= ~AC1_BIT; 653 654 // setup timing 655 a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags); 656 657 // send timing, channel, config bits 658 outw(devpriv->config_bits, dev->iobase + CONFIG_REG); 659 660 // initialize number of samples remaining 661 devpriv->count = cmd->stop_arg * cmd->chanlist_len; 662 663 // enable computer's dma 664 lock_flags = claim_dma_lock(); 665 disable_dma(devpriv->dma); 666 /* clear flip-flop to make sure 2-byte registers for 667 * count and address get set correctly */ 668 clear_dma_ff(devpriv->dma); 669 set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer)); 670 // set size of transfer to fill in 1/3 second 671#define ONE_THIRD_SECOND 333333333 672 devpriv->dma_transfer_size = 673 sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len * 674 ONE_THIRD_SECOND / cmd->scan_begin_arg; 675 if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE) 676 devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE; 677 if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0])) 678 devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]); 679 devpriv->dma_transfer_size -= 680 devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]); 681 set_dma_count(devpriv->dma, devpriv->dma_transfer_size); 682 enable_dma(devpriv->dma); 683 release_dma_lock(lock_flags); 684 685 /* clear dma interrupt before enabling it, to try and get rid of that 686 * one spurious interrupt that has been happening */ 687 outw(0x00, dev->iobase + DMA_TC_CLEAR_REG); 688 689 // enable dma on card 690 devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT; 691 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG); 692 693 // may need to wait 72 sampling periods if timing was changed 694 i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0); 695 696 // setup start triggering 697 trigger_bits = 0; 698 // decide if we need to wait 72 periods for valid data 699 if (cmd->start_src == TRIG_NOW && 700 (old_config_bits & CLOCK_MASK) != 701 (devpriv->config_bits & CLOCK_MASK)) { 702 // set trigger source to delay trigger 703 trigger_bits |= DELAY_TRIGGER_BITS; 704 } else { 705 // otherwise no delay 706 trigger_bits |= POST_TRIGGER_BITS; 707 } 708 // enable external hardware trigger 709 if (cmd->start_src == TRIG_EXT) { 710 trigger_bits |= HW_TRIG_EN; 711 } else if (cmd->start_src == TRIG_OTHER) { 712 // XXX add support for level/slope start trigger using TRIG_OTHER 713 comedi_error(dev, "you shouldn't see this?"); 714 } 715 // send trigger config bits 716 outw(trigger_bits, dev->iobase + TRIGGER_REG); 717 718 // start aquisition for soft trigger 719 if (cmd->start_src == TRIG_NOW) { 720 outw(0, dev->iobase + FIFO_START_REG); 721 } 722#ifdef A2150_DEBUG 723 ni_dump_regs(dev); 724#endif 725 726 return 0; 727} 728 729static int a2150_ai_rinsn(struct comedi_device * dev, comedi_subdevice * s, 730 comedi_insn * insn, unsigned int * data) 731{ 732 unsigned int i, n; 733 static const int timeout = 100000; 734 static const int filter_delay = 36; 735 736 // clear fifo and reset triggering circuitry 737 outw(0, dev->iobase + FIFO_RESET_REG); 738 739 /* setup chanlist */ 740 if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0) 741 return -1; 742 743 // set dc coupling 744 devpriv->config_bits &= ~AC0_BIT; 745 devpriv->config_bits &= ~AC1_BIT; 746 747 // send timing, channel, config bits 748 outw(devpriv->config_bits, dev->iobase + CONFIG_REG); 749 750 // disable dma on card 751 devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT; 752 outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG); 753 754 // setup start triggering 755 outw(0, dev->iobase + TRIGGER_REG); 756 757 // start aquisition for soft trigger 758 outw(0, dev->iobase + FIFO_START_REG); 759 760 /* there is a 35.6 sample delay for data to get through the antialias filter */ 761 for (n = 0; n < filter_delay; n++) { 762 for (i = 0; i < timeout; i++) { 763 if (inw(dev->iobase + STATUS_REG) & FNE_BIT) 764 break; 765 comedi_udelay(1); 766 } 767 if (i == timeout) { 768 comedi_error(dev, "timeout"); 769 return -ETIME; 770 } 771 inw(dev->iobase + FIFO_DATA_REG); 772 } 773 774 // read data 775 for (n = 0; n < insn->n; n++) { 776 for (i = 0; i < timeout; i++) { 777 if (inw(dev->iobase + STATUS_REG) & FNE_BIT) 778 break; 779 comedi_udelay(1); 780 } 781 if (i == timeout) { 782 comedi_error(dev, "timeout"); 783 return -ETIME; 784 } 785#ifdef A2150_DEBUG 786 ni_dump_regs(dev); 787#endif 788 data[n] = inw(dev->iobase + FIFO_DATA_REG); 789#ifdef A2150_DEBUG 790 rt_printk(" data is %i\n", data[n]); 791#endif 792 data[n] ^= 0x8000; 793 } 794 795 // clear fifo and reset triggering circuitry 796 outw(0, dev->iobase + FIFO_RESET_REG); 797 798 return n; 799} 800 801/* sets bits in devpriv->clock_bits to nearest approximation of requested period, 802 * adjusts requested period to actual timing. */ 803static int a2150_get_timing(struct comedi_device * dev, unsigned int *period, 804 int flags) 805{ 806 int lub, glb, temp; 807 int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index; 808 int i, j; 809 810 // initialize greatest lower and least upper bounds 811 lub_divisor_shift = 3; 812 lub_index = 0; 813 lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift); 814 glb_divisor_shift = 0; 815 glb_index = thisboard->num_clocks - 1; 816 glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift); 817 818 // make sure period is in available range 819 if (*period < glb) 820 *period = glb; 821 if (*period > lub) 822 *period = lub; 823 824 // we can multiply period by 1, 2, 4, or 8, using (1 << i) 825 for (i = 0; i < 4; i++) { 826 // there are a maximum of 4 master clocks 827 for (j = 0; j < thisboard->num_clocks; j++) { 828 // temp is the period in nanosec we are evaluating 829 temp = thisboard->clock[j] * (1 << i); 830 // if it is the best match yet 831 if (temp < lub && temp >= *period) { 832 lub_divisor_shift = i; 833 lub_index = j; 834 lub = temp; 835 } 836 if (temp > glb && temp <= *period) { 837 glb_divisor_shift = i; 838 glb_index = j; 839 glb = temp; 840 } 841 } 842 } 843 flags &= TRIG_ROUND_MASK; 844 switch (flags) { 845 case TRIG_ROUND_NEAREST: 846 default: 847 // if least upper bound is better approximation 848 if (lub - *period < *period - glb) { 849 *period = lub; 850 } else { 851 *period = glb; 852 } 853 break; 854 case TRIG_ROUND_UP: 855 *period = lub; 856 break; 857 case TRIG_ROUND_DOWN: 858 *period = glb; 859 break; 860 } 861 862 // set clock bits for config register appropriately 863 devpriv->config_bits &= ~CLOCK_MASK; 864 if (*period == lub) { 865 devpriv->config_bits |= 866 CLOCK_SELECT_BITS(lub_index) | 867 CLOCK_DIVISOR_BITS(lub_divisor_shift); 868 } else { 869 devpriv->config_bits |= 870 CLOCK_SELECT_BITS(glb_index) | 871 CLOCK_DIVISOR_BITS(glb_divisor_shift); 872 } 873 874 return 0; 875} 876 877static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel, 878 unsigned int num_channels) 879{ 880 if (start_channel + num_channels > 4) 881 return -1; 882 883 devpriv->config_bits &= ~CHANNEL_MASK; 884 885 switch (num_channels) { 886 case 1: 887 devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel); 888 break; 889 case 2: 890 if (start_channel == 0) { 891 devpriv->config_bits |= CHANNEL_BITS(0x2); 892 } else if (start_channel == 2) { 893 devpriv->config_bits |= CHANNEL_BITS(0x3); 894 } else { 895 return -1; 896 } 897 break; 898 case 4: 899 devpriv->config_bits |= CHANNEL_BITS(0x1); 900 break; 901 default: 902 return -1; 903 break; 904 } 905 906 return 0; 907} 908