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