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