1/* 2 * das16.c 3 * DAS16 driver 4 * 5 * COMEDI - Linux Control and Measurement Device Interface 6 * Copyright (C) 2000 David A. Schleef <ds@schleef.org> 7 * Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com> 8 * Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 */ 20 21/* 22 * Driver: das16 23 * Description: DAS16 compatible boards 24 * Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze 25 * Devices: (Keithley Metrabyte) DAS-16 [das-16] 26 * (Keithley Metrabyte) DAS-16G [das-16g] 27 * (Keithley Metrabyte) DAS-16F [das-16f] 28 * (Keithley Metrabyte) DAS-1201 [das-1201] 29 * (Keithley Metrabyte) DAS-1202 [das-1202] 30 * (Keithley Metrabyte) DAS-1401 [das-1401] 31 * (Keithley Metrabyte) DAS-1402 [das-1402] 32 * (Keithley Metrabyte) DAS-1601 [das-1601] 33 * (Keithley Metrabyte) DAS-1602 [das-1602] 34 * (ComputerBoards) PC104-DAS16/JR [pc104-das16jr] 35 * (ComputerBoards) PC104-DAS16JR/16 [pc104-das16jr/16] 36 * (ComputerBoards) CIO-DAS16 [cio-das16] 37 * (ComputerBoards) CIO-DAS16F [cio-das16/f] 38 * (ComputerBoards) CIO-DAS16/JR [cio-das16/jr] 39 * (ComputerBoards) CIO-DAS16JR/16 [cio-das16jr/16] 40 * (ComputerBoards) CIO-DAS1401/12 [cio-das1401/12] 41 * (ComputerBoards) CIO-DAS1402/12 [cio-das1402/12] 42 * (ComputerBoards) CIO-DAS1402/16 [cio-das1402/16] 43 * (ComputerBoards) CIO-DAS1601/12 [cio-das1601/12] 44 * (ComputerBoards) CIO-DAS1602/12 [cio-das1602/12] 45 * (ComputerBoards) CIO-DAS1602/16 [cio-das1602/16] 46 * (ComputerBoards) CIO-DAS16/330 [cio-das16/330] 47 * Status: works 48 * Updated: 2003-10-12 49 * 50 * A rewrite of the das16 and das1600 drivers. 51 * 52 * Options: 53 * [0] - base io address 54 * [1] - irq (does nothing, irq is not used anymore) 55 * [2] - dma channel (optional, required for comedi_command support) 56 * [3] - master clock speed in MHz (optional, 1 or 10, ignored if 57 * board can probe clock, defaults to 1) 58 * [4] - analog input range lowest voltage in microvolts (optional, 59 * only useful if your board does not have software 60 * programmable gain) 61 * [5] - analog input range highest voltage in microvolts (optional, 62 * only useful if board does not have software programmable 63 * gain) 64 * [6] - analog output range lowest voltage in microvolts (optional) 65 * [7] - analog output range highest voltage in microvolts (optional) 66 * 67 * Passing a zero for an option is the same as leaving it unspecified. 68 */ 69 70/* 71 * Testing and debugging help provided by Daniel Koch. 72 * 73 * Keithley Manuals: 74 * 2309.PDF (das16) 75 * 4919.PDF (das1400, 1600) 76 * 4922.PDF (das-1400) 77 * 4923.PDF (das1200, 1400, 1600) 78 * 79 * Computer boards manuals also available from their website 80 * www.measurementcomputing.com 81 */ 82 83#include <linux/module.h> 84#include <linux/slab.h> 85#include <linux/delay.h> 86#include <linux/pci.h> 87#include <linux/interrupt.h> 88 89#include <asm/dma.h> 90 91#include "../comedidev.h" 92 93#include "8253.h" 94#include "8255.h" 95#include "comedi_fc.h" 96 97#define DAS16_DMA_SIZE 0xff00 /* size in bytes of allocated dma buffer */ 98 99/* 100 * Register I/O map 101 */ 102#define DAS16_TRIG_REG 0x00 103#define DAS16_AI_LSB_REG 0x00 104#define DAS16_AI_MSB_REG 0x01 105#define DAS16_MUX_REG 0x02 106#define DAS16_DIO_REG 0x03 107#define DAS16_AO_LSB_REG(x) ((x) ? 0x06 : 0x04) 108#define DAS16_AO_MSB_REG(x) ((x) ? 0x07 : 0x05) 109#define DAS16_STATUS_REG 0x08 110#define DAS16_STATUS_BUSY (1 << 7) 111#define DAS16_STATUS_UNIPOLAR (1 << 6) 112#define DAS16_STATUS_MUXBIT (1 << 5) 113#define DAS16_STATUS_INT (1 << 4) 114#define DAS16_CTRL_REG 0x09 115#define DAS16_CTRL_INTE (1 << 7) 116#define DAS16_CTRL_IRQ(x) (((x) & 0x7) << 4) 117#define DAS16_CTRL_DMAE (1 << 2) 118#define DAS16_CTRL_PACING_MASK (3 << 0) 119#define DAS16_CTRL_INT_PACER (3 << 0) 120#define DAS16_CTRL_EXT_PACER (2 << 0) 121#define DAS16_CTRL_SOFT_PACER (0 << 0) 122#define DAS16_PACER_REG 0x0a 123#define DAS16_PACER_BURST_LEN(x) (((x) & 0xf) << 4) 124#define DAS16_PACER_CTR0 (1 << 1) 125#define DAS16_PACER_TRIG0 (1 << 0) 126#define DAS16_GAIN_REG 0x0b 127#define DAS16_TIMER_BASE_REG 0x0c /* to 0x0f */ 128 129#define DAS1600_CONV_REG 0x404 130#define DAS1600_CONV_DISABLE (1 << 6) 131#define DAS1600_BURST_REG 0x405 132#define DAS1600_BURST_VAL (1 << 6) 133#define DAS1600_ENABLE_REG 0x406 134#define DAS1600_ENABLE_VAL (1 << 6) 135#define DAS1600_STATUS_REG 0x407 136#define DAS1600_STATUS_BME (1 << 6) 137#define DAS1600_STATUS_ME (1 << 5) 138#define DAS1600_STATUS_CD (1 << 4) 139#define DAS1600_STATUS_WS (1 << 1) 140#define DAS1600_STATUS_CLK_10MHZ (1 << 0) 141 142static const struct comedi_lrange range_das1x01_bip = { 143 4, { 144 BIP_RANGE(10), 145 BIP_RANGE(1), 146 BIP_RANGE(0.1), 147 BIP_RANGE(0.01) 148 } 149}; 150 151static const struct comedi_lrange range_das1x01_unip = { 152 4, { 153 UNI_RANGE(10), 154 UNI_RANGE(1), 155 UNI_RANGE(0.1), 156 UNI_RANGE(0.01) 157 } 158}; 159 160static const struct comedi_lrange range_das1x02_bip = { 161 4, { 162 BIP_RANGE(10), 163 BIP_RANGE(5), 164 BIP_RANGE(2.5), 165 BIP_RANGE(1.25) 166 } 167}; 168 169static const struct comedi_lrange range_das1x02_unip = { 170 4, { 171 UNI_RANGE(10), 172 UNI_RANGE(5), 173 UNI_RANGE(2.5), 174 UNI_RANGE(1.25) 175 } 176}; 177 178static const struct comedi_lrange range_das16jr = { 179 9, { 180 BIP_RANGE(10), 181 BIP_RANGE(5), 182 BIP_RANGE(2.5), 183 BIP_RANGE(1.25), 184 BIP_RANGE(0.625), 185 UNI_RANGE(10), 186 UNI_RANGE(5), 187 UNI_RANGE(2.5), 188 UNI_RANGE(1.25) 189 } 190}; 191 192static const struct comedi_lrange range_das16jr_16 = { 193 8, { 194 BIP_RANGE(10), 195 BIP_RANGE(5), 196 BIP_RANGE(2.5), 197 BIP_RANGE(1.25), 198 UNI_RANGE(10), 199 UNI_RANGE(5), 200 UNI_RANGE(2.5), 201 UNI_RANGE(1.25) 202 } 203}; 204 205static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 }; 206static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; 207static const int das1600_gainlist[] = { 0, 1, 2, 3 }; 208 209enum { 210 das16_pg_none = 0, 211 das16_pg_16jr, 212 das16_pg_16jr_16, 213 das16_pg_1601, 214 das16_pg_1602, 215}; 216static const int *const das16_gainlists[] = { 217 NULL, 218 das16jr_gainlist, 219 das16jr_16_gainlist, 220 das1600_gainlist, 221 das1600_gainlist, 222}; 223 224static const struct comedi_lrange *const das16_ai_uni_lranges[] = { 225 &range_unknown, 226 &range_das16jr, 227 &range_das16jr_16, 228 &range_das1x01_unip, 229 &range_das1x02_unip, 230}; 231 232static const struct comedi_lrange *const das16_ai_bip_lranges[] = { 233 &range_unknown, 234 &range_das16jr, 235 &range_das16jr_16, 236 &range_das1x01_bip, 237 &range_das1x02_bip, 238}; 239 240struct das16_board { 241 const char *name; 242 unsigned int ai_maxdata; 243 unsigned int ai_speed; /* max conversion speed in nanosec */ 244 unsigned int ai_pg; 245 unsigned int has_ao:1; 246 unsigned int has_8255:1; 247 248 unsigned int i8255_offset; 249 250 unsigned int size; 251 unsigned int id; 252}; 253 254static const struct das16_board das16_boards[] = { 255 { 256 .name = "das-16", 257 .ai_maxdata = 0x0fff, 258 .ai_speed = 15000, 259 .ai_pg = das16_pg_none, 260 .has_ao = 1, 261 .has_8255 = 1, 262 .i8255_offset = 0x10, 263 .size = 0x14, 264 .id = 0x00, 265 }, { 266 .name = "das-16g", 267 .ai_maxdata = 0x0fff, 268 .ai_speed = 15000, 269 .ai_pg = das16_pg_none, 270 .has_ao = 1, 271 .has_8255 = 1, 272 .i8255_offset = 0x10, 273 .size = 0x14, 274 .id = 0x00, 275 }, { 276 .name = "das-16f", 277 .ai_maxdata = 0x0fff, 278 .ai_speed = 8500, 279 .ai_pg = das16_pg_none, 280 .has_ao = 1, 281 .has_8255 = 1, 282 .i8255_offset = 0x10, 283 .size = 0x14, 284 .id = 0x00, 285 }, { 286 .name = "cio-das16", 287 .ai_maxdata = 0x0fff, 288 .ai_speed = 20000, 289 .ai_pg = das16_pg_none, 290 .has_ao = 1, 291 .has_8255 = 1, 292 .i8255_offset = 0x10, 293 .size = 0x14, 294 .id = 0x80, 295 }, { 296 .name = "cio-das16/f", 297 .ai_maxdata = 0x0fff, 298 .ai_speed = 10000, 299 .ai_pg = das16_pg_none, 300 .has_ao = 1, 301 .has_8255 = 1, 302 .i8255_offset = 0x10, 303 .size = 0x14, 304 .id = 0x80, 305 }, { 306 .name = "cio-das16/jr", 307 .ai_maxdata = 0x0fff, 308 .ai_speed = 7692, 309 .ai_pg = das16_pg_16jr, 310 .size = 0x10, 311 .id = 0x00, 312 }, { 313 .name = "pc104-das16jr", 314 .ai_maxdata = 0x0fff, 315 .ai_speed = 3300, 316 .ai_pg = das16_pg_16jr, 317 .size = 0x10, 318 .id = 0x00, 319 }, { 320 .name = "cio-das16jr/16", 321 .ai_maxdata = 0xffff, 322 .ai_speed = 10000, 323 .ai_pg = das16_pg_16jr_16, 324 .size = 0x10, 325 .id = 0x00, 326 }, { 327 .name = "pc104-das16jr/16", 328 .ai_maxdata = 0xffff, 329 .ai_speed = 10000, 330 .ai_pg = das16_pg_16jr_16, 331 .size = 0x10, 332 .id = 0x00, 333 }, { 334 .name = "das-1201", 335 .ai_maxdata = 0x0fff, 336 .ai_speed = 20000, 337 .ai_pg = das16_pg_none, 338 .has_8255 = 1, 339 .i8255_offset = 0x400, 340 .size = 0x408, 341 .id = 0x20, 342 }, { 343 .name = "das-1202", 344 .ai_maxdata = 0x0fff, 345 .ai_speed = 10000, 346 .ai_pg = das16_pg_none, 347 .has_8255 = 1, 348 .i8255_offset = 0x400, 349 .size = 0x408, 350 .id = 0x20, 351 }, { 352 .name = "das-1401", 353 .ai_maxdata = 0x0fff, 354 .ai_speed = 10000, 355 .ai_pg = das16_pg_1601, 356 .size = 0x408, 357 .id = 0xc0, 358 }, { 359 .name = "das-1402", 360 .ai_maxdata = 0x0fff, 361 .ai_speed = 10000, 362 .ai_pg = das16_pg_1602, 363 .size = 0x408, 364 .id = 0xc0, 365 }, { 366 .name = "das-1601", 367 .ai_maxdata = 0x0fff, 368 .ai_speed = 10000, 369 .ai_pg = das16_pg_1601, 370 .has_ao = 1, 371 .has_8255 = 1, 372 .i8255_offset = 0x400, 373 .size = 0x408, 374 .id = 0xc0, 375 }, { 376 .name = "das-1602", 377 .ai_maxdata = 0x0fff, 378 .ai_speed = 10000, 379 .ai_pg = das16_pg_1602, 380 .has_ao = 1, 381 .has_8255 = 1, 382 .i8255_offset = 0x400, 383 .size = 0x408, 384 .id = 0xc0, 385 }, { 386 .name = "cio-das1401/12", 387 .ai_maxdata = 0x0fff, 388 .ai_speed = 6250, 389 .ai_pg = das16_pg_1601, 390 .size = 0x408, 391 .id = 0xc0, 392 }, { 393 .name = "cio-das1402/12", 394 .ai_maxdata = 0x0fff, 395 .ai_speed = 6250, 396 .ai_pg = das16_pg_1602, 397 .size = 0x408, 398 .id = 0xc0, 399 }, { 400 .name = "cio-das1402/16", 401 .ai_maxdata = 0xffff, 402 .ai_speed = 10000, 403 .ai_pg = das16_pg_1602, 404 .size = 0x408, 405 .id = 0xc0, 406 }, { 407 .name = "cio-das1601/12", 408 .ai_maxdata = 0x0fff, 409 .ai_speed = 6250, 410 .ai_pg = das16_pg_1601, 411 .has_ao = 1, 412 .has_8255 = 1, 413 .i8255_offset = 0x400, 414 .size = 0x408, 415 .id = 0xc0, 416 }, { 417 .name = "cio-das1602/12", 418 .ai_maxdata = 0x0fff, 419 .ai_speed = 10000, 420 .ai_pg = das16_pg_1602, 421 .has_ao = 1, 422 .has_8255 = 1, 423 .i8255_offset = 0x400, 424 .size = 0x408, 425 .id = 0xc0, 426 }, { 427 .name = "cio-das1602/16", 428 .ai_maxdata = 0xffff, 429 .ai_speed = 10000, 430 .ai_pg = das16_pg_1602, 431 .has_ao = 1, 432 .has_8255 = 1, 433 .i8255_offset = 0x400, 434 .size = 0x408, 435 .id = 0xc0, 436 }, { 437 .name = "cio-das16/330", 438 .ai_maxdata = 0x0fff, 439 .ai_speed = 3030, 440 .ai_pg = das16_pg_16jr, 441 .size = 0x14, 442 .id = 0xf0, 443 }, 444}; 445 446/* Period for timer interrupt in jiffies. It's a function 447 * to deal with possibility of dynamic HZ patches */ 448static inline int timer_period(void) 449{ 450 return HZ / 20; 451} 452 453struct das16_private_struct { 454 unsigned int clockbase; 455 unsigned int ctrl_reg; 456 unsigned long adc_byte_count; 457 unsigned int divisor1; 458 unsigned int divisor2; 459 unsigned int dma_chan; 460 uint16_t *dma_buffer[2]; 461 dma_addr_t dma_buffer_addr[2]; 462 unsigned int current_buffer; 463 unsigned int dma_transfer_size; 464 struct comedi_lrange *user_ai_range_table; 465 struct comedi_lrange *user_ao_range_table; 466 struct timer_list timer; 467 short timer_running; 468 unsigned long extra_iobase; 469 unsigned int can_burst:1; 470}; 471 472static void das16_ai_enable(struct comedi_device *dev, 473 unsigned int mode, unsigned int src) 474{ 475 struct das16_private_struct *devpriv = dev->private; 476 477 devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE | 478 DAS16_CTRL_DMAE | 479 DAS16_CTRL_PACING_MASK); 480 devpriv->ctrl_reg |= mode; 481 482 if (src == TRIG_EXT) 483 devpriv->ctrl_reg |= DAS16_CTRL_EXT_PACER; 484 else 485 devpriv->ctrl_reg |= DAS16_CTRL_INT_PACER; 486 outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG); 487} 488 489static void das16_ai_disable(struct comedi_device *dev) 490{ 491 struct das16_private_struct *devpriv = dev->private; 492 493 /* disable interrupts, dma and pacer clocked conversions */ 494 devpriv->ctrl_reg &= ~(DAS16_CTRL_INTE | 495 DAS16_CTRL_DMAE | 496 DAS16_CTRL_PACING_MASK); 497 outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG); 498} 499 500/* the pc104-das16jr (at least) has problems if the dma 501 transfer is interrupted in the middle of transferring 502 a 16 bit sample, so this function takes care to get 503 an even transfer count after disabling dma 504 channel. 505*/ 506static int disable_dma_on_even(struct comedi_device *dev) 507{ 508 struct das16_private_struct *devpriv = dev->private; 509 static const int disable_limit = 100; 510 static const int enable_timeout = 100; 511 int residue; 512 int new_residue; 513 int i; 514 int j; 515 516 disable_dma(devpriv->dma_chan); 517 residue = get_dma_residue(devpriv->dma_chan); 518 for (i = 0; i < disable_limit && (residue % 2); ++i) { 519 enable_dma(devpriv->dma_chan); 520 for (j = 0; j < enable_timeout; ++j) { 521 udelay(2); 522 new_residue = get_dma_residue(devpriv->dma_chan); 523 if (new_residue != residue) 524 break; 525 } 526 disable_dma(devpriv->dma_chan); 527 residue = get_dma_residue(devpriv->dma_chan); 528 } 529 if (i == disable_limit) { 530 dev_err(dev->class_dev, 531 "failed to get an even dma transfer, could be trouble\n"); 532 } 533 return residue; 534} 535 536static void das16_interrupt(struct comedi_device *dev) 537{ 538 struct das16_private_struct *devpriv = dev->private; 539 struct comedi_subdevice *s = dev->read_subdev; 540 struct comedi_async *async = s->async; 541 struct comedi_cmd *cmd = &async->cmd; 542 unsigned long spin_flags; 543 unsigned long dma_flags; 544 int num_bytes, residue; 545 int buffer_index; 546 547 spin_lock_irqsave(&dev->spinlock, spin_flags); 548 if (!(devpriv->ctrl_reg & DAS16_CTRL_DMAE)) { 549 spin_unlock_irqrestore(&dev->spinlock, spin_flags); 550 return; 551 } 552 553 dma_flags = claim_dma_lock(); 554 clear_dma_ff(devpriv->dma_chan); 555 residue = disable_dma_on_even(dev); 556 557 /* figure out how many points to read */ 558 if (residue > devpriv->dma_transfer_size) { 559 dev_err(dev->class_dev, "residue > transfer size!\n"); 560 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 561 num_bytes = 0; 562 } else 563 num_bytes = devpriv->dma_transfer_size - residue; 564 565 if (cmd->stop_src == TRIG_COUNT && 566 num_bytes >= devpriv->adc_byte_count) { 567 num_bytes = devpriv->adc_byte_count; 568 async->events |= COMEDI_CB_EOA; 569 } 570 571 buffer_index = devpriv->current_buffer; 572 devpriv->current_buffer = (devpriv->current_buffer + 1) % 2; 573 devpriv->adc_byte_count -= num_bytes; 574 575 /* re-enable dma */ 576 if ((async->events & COMEDI_CB_EOA) == 0) { 577 set_dma_addr(devpriv->dma_chan, 578 devpriv->dma_buffer_addr[devpriv->current_buffer]); 579 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); 580 enable_dma(devpriv->dma_chan); 581 } 582 release_dma_lock(dma_flags); 583 584 spin_unlock_irqrestore(&dev->spinlock, spin_flags); 585 586 cfc_write_array_to_buffer(s, 587 devpriv->dma_buffer[buffer_index], num_bytes); 588 589 cfc_handle_events(dev, s); 590} 591 592static void das16_timer_interrupt(unsigned long arg) 593{ 594 struct comedi_device *dev = (struct comedi_device *)arg; 595 struct das16_private_struct *devpriv = dev->private; 596 597 das16_interrupt(dev); 598 599 if (devpriv->timer_running) 600 mod_timer(&devpriv->timer, jiffies + timer_period()); 601} 602 603static int das16_ai_check_chanlist(struct comedi_device *dev, 604 struct comedi_subdevice *s, 605 struct comedi_cmd *cmd) 606{ 607 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); 608 unsigned int range0 = CR_RANGE(cmd->chanlist[0]); 609 int i; 610 611 for (i = 1; i < cmd->chanlist_len; i++) { 612 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 613 unsigned int range = CR_RANGE(cmd->chanlist[i]); 614 615 if (chan != ((chan0 + i) % s->n_chan)) { 616 dev_dbg(dev->class_dev, 617 "entries in chanlist must be consecutive channels, counting upwards\n"); 618 return -EINVAL; 619 } 620 621 if (range != range0) { 622 dev_dbg(dev->class_dev, 623 "entries in chanlist must all have the same gain\n"); 624 return -EINVAL; 625 } 626 } 627 628 return 0; 629} 630 631static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, 632 struct comedi_cmd *cmd) 633{ 634 const struct das16_board *board = dev->board_ptr; 635 struct das16_private_struct *devpriv = dev->private; 636 int err = 0; 637 unsigned int trig_mask; 638 unsigned int arg; 639 640 /* Step 1 : check if triggers are trivially valid */ 641 642 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW); 643 644 trig_mask = TRIG_FOLLOW; 645 if (devpriv->can_burst) 646 trig_mask |= TRIG_TIMER | TRIG_EXT; 647 err |= cfc_check_trigger_src(&cmd->scan_begin_src, trig_mask); 648 649 trig_mask = TRIG_TIMER | TRIG_EXT; 650 if (devpriv->can_burst) 651 trig_mask |= TRIG_NOW; 652 err |= cfc_check_trigger_src(&cmd->convert_src, trig_mask); 653 654 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 655 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 656 657 if (err) 658 return 1; 659 660 /* Step 2a : make sure trigger sources are unique */ 661 662 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); 663 err |= cfc_check_trigger_is_unique(cmd->convert_src); 664 err |= cfc_check_trigger_is_unique(cmd->stop_src); 665 666 /* Step 2b : and mutually compatible */ 667 668 /* make sure scan_begin_src and convert_src dont conflict */ 669 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) 670 err |= -EINVAL; 671 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) 672 err |= -EINVAL; 673 674 if (err) 675 return 2; 676 677 /* Step 3: check if arguments are trivially valid */ 678 679 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 680 681 if (cmd->scan_begin_src == TRIG_FOLLOW) /* internal trigger */ 682 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0); 683 684 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 685 686 /* check against maximum frequency */ 687 if (cmd->scan_begin_src == TRIG_TIMER) 688 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 689 board->ai_speed * cmd->chanlist_len); 690 691 if (cmd->convert_src == TRIG_TIMER) 692 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 693 board->ai_speed); 694 695 if (cmd->stop_src == TRIG_COUNT) 696 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); 697 else /* TRIG_NONE */ 698 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 699 700 if (err) 701 return 3; 702 703 /* step 4: fix up arguments */ 704 if (cmd->scan_begin_src == TRIG_TIMER) { 705 arg = cmd->scan_begin_arg; 706 i8253_cascade_ns_to_timer(devpriv->clockbase, 707 &devpriv->divisor1, 708 &devpriv->divisor2, 709 &arg, cmd->flags); 710 err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg); 711 } 712 if (cmd->convert_src == TRIG_TIMER) { 713 arg = cmd->convert_arg; 714 i8253_cascade_ns_to_timer(devpriv->clockbase, 715 &devpriv->divisor1, 716 &devpriv->divisor2, 717 &arg, cmd->flags); 718 err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg); 719 } 720 if (err) 721 return 4; 722 723 /* Step 5: check channel list if it exists */ 724 if (cmd->chanlist && cmd->chanlist_len > 0) 725 err |= das16_ai_check_chanlist(dev, s, cmd); 726 727 if (err) 728 return 5; 729 730 return 0; 731} 732 733static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, 734 unsigned int flags) 735{ 736 struct das16_private_struct *devpriv = dev->private; 737 unsigned long timer_base = dev->iobase + DAS16_TIMER_BASE_REG; 738 739 i8253_cascade_ns_to_timer(devpriv->clockbase, 740 &devpriv->divisor1, &devpriv->divisor2, 741 &ns, flags); 742 743 i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY); 744 i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY); 745 i8254_write(timer_base, 0, 1, devpriv->divisor1); 746 i8254_write(timer_base, 0, 2, devpriv->divisor2); 747 748 return ns; 749} 750 751static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) 752{ 753 const struct das16_board *board = dev->board_ptr; 754 struct das16_private_struct *devpriv = dev->private; 755 struct comedi_async *async = s->async; 756 struct comedi_cmd *cmd = &async->cmd; 757 unsigned int byte; 758 unsigned long flags; 759 int range; 760 761 if (cmd->flags & CMDF_PRIORITY) { 762 dev_err(dev->class_dev, 763 "isa dma transfers cannot be performed with CMDF_PRIORITY, aborting\n"); 764 return -1; 765 } 766 767 devpriv->adc_byte_count = cmd->stop_arg * cfc_bytes_per_scan(s); 768 769 if (devpriv->can_burst) 770 outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV_REG); 771 772 /* set scan limits */ 773 byte = CR_CHAN(cmd->chanlist[0]); 774 byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4; 775 outb(byte, dev->iobase + DAS16_MUX_REG); 776 777 /* set gain (this is also burst rate register but according to 778 * computer boards manual, burst rate does nothing, even on 779 * keithley cards) */ 780 if (board->ai_pg != das16_pg_none) { 781 range = CR_RANGE(cmd->chanlist[0]); 782 outb((das16_gainlists[board->ai_pg])[range], 783 dev->iobase + DAS16_GAIN_REG); 784 } 785 786 /* set counter mode and counts */ 787 cmd->convert_arg = das16_set_pacer(dev, cmd->convert_arg, cmd->flags); 788 789 /* enable counters */ 790 byte = 0; 791 if (devpriv->can_burst) { 792 if (cmd->convert_src == TRIG_NOW) { 793 outb(DAS1600_BURST_VAL, 794 dev->iobase + DAS1600_BURST_REG); 795 /* set burst length */ 796 byte |= DAS16_PACER_BURST_LEN(cmd->chanlist_len - 1); 797 } else { 798 outb(0, dev->iobase + DAS1600_BURST_REG); 799 } 800 } 801 outb(byte, dev->iobase + DAS16_PACER_REG); 802 803 /* set up dma transfer */ 804 flags = claim_dma_lock(); 805 disable_dma(devpriv->dma_chan); 806 /* clear flip-flop to make sure 2-byte registers for 807 * count and address get set correctly */ 808 clear_dma_ff(devpriv->dma_chan); 809 devpriv->current_buffer = 0; 810 set_dma_addr(devpriv->dma_chan, 811 devpriv->dma_buffer_addr[devpriv->current_buffer]); 812 devpriv->dma_transfer_size = DAS16_DMA_SIZE; 813 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); 814 enable_dma(devpriv->dma_chan); 815 release_dma_lock(flags); 816 817 /* set up interrupt */ 818 devpriv->timer_running = 1; 819 devpriv->timer.expires = jiffies + timer_period(); 820 add_timer(&devpriv->timer); 821 822 das16_ai_enable(dev, DAS16_CTRL_DMAE, cmd->convert_src); 823 824 if (devpriv->can_burst) 825 outb(0, dev->iobase + DAS1600_CONV_REG); 826 827 return 0; 828} 829 830static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 831{ 832 struct das16_private_struct *devpriv = dev->private; 833 unsigned long flags; 834 835 spin_lock_irqsave(&dev->spinlock, flags); 836 837 das16_ai_disable(dev); 838 disable_dma(devpriv->dma_chan); 839 840 /* disable SW timer */ 841 if (devpriv->timer_running) { 842 devpriv->timer_running = 0; 843 del_timer(&devpriv->timer); 844 } 845 846 if (devpriv->can_burst) 847 outb(0, dev->iobase + DAS1600_BURST_REG); 848 849 spin_unlock_irqrestore(&dev->spinlock, flags); 850 851 return 0; 852} 853 854static void das16_ai_munge(struct comedi_device *dev, 855 struct comedi_subdevice *s, void *array, 856 unsigned int num_bytes, 857 unsigned int start_chan_index) 858{ 859 unsigned int i, num_samples = num_bytes / sizeof(short); 860 unsigned short *data = array; 861 862 for (i = 0; i < num_samples; i++) { 863 data[i] = le16_to_cpu(data[i]); 864 if (s->maxdata == 0x0fff) 865 data[i] >>= 4; 866 data[i] &= s->maxdata; 867 } 868} 869 870static int das16_ai_eoc(struct comedi_device *dev, 871 struct comedi_subdevice *s, 872 struct comedi_insn *insn, 873 unsigned long context) 874{ 875 unsigned int status; 876 877 status = inb(dev->iobase + DAS16_STATUS_REG); 878 if ((status & DAS16_STATUS_BUSY) == 0) 879 return 0; 880 return -EBUSY; 881} 882 883static int das16_ai_insn_read(struct comedi_device *dev, 884 struct comedi_subdevice *s, 885 struct comedi_insn *insn, 886 unsigned int *data) 887{ 888 const struct das16_board *board = dev->board_ptr; 889 unsigned int chan = CR_CHAN(insn->chanspec); 890 unsigned int range = CR_RANGE(insn->chanspec); 891 unsigned int val; 892 int ret; 893 int i; 894 895 das16_ai_disable(dev); 896 897 /* set multiplexer */ 898 outb(chan | (chan << 4), dev->iobase + DAS16_MUX_REG); 899 900 /* set gain */ 901 if (board->ai_pg != das16_pg_none) { 902 outb((das16_gainlists[board->ai_pg])[range], 903 dev->iobase + DAS16_GAIN_REG); 904 } 905 906 for (i = 0; i < insn->n; i++) { 907 /* trigger conversion */ 908 outb_p(0, dev->iobase + DAS16_TRIG_REG); 909 910 ret = comedi_timeout(dev, s, insn, das16_ai_eoc, 0); 911 if (ret) 912 return ret; 913 914 val = inb(dev->iobase + DAS16_AI_MSB_REG) << 8; 915 val |= inb(dev->iobase + DAS16_AI_LSB_REG); 916 if (s->maxdata == 0x0fff) 917 val >>= 4; 918 val &= s->maxdata; 919 920 data[i] = val; 921 } 922 923 return insn->n; 924} 925 926static int das16_ao_insn_write(struct comedi_device *dev, 927 struct comedi_subdevice *s, 928 struct comedi_insn *insn, 929 unsigned int *data) 930{ 931 unsigned int chan = CR_CHAN(insn->chanspec); 932 int i; 933 934 for (i = 0; i < insn->n; i++) { 935 unsigned int val = data[i]; 936 937 s->readback[chan] = val; 938 939 val <<= 4; 940 941 outb(val & 0xff, dev->iobase + DAS16_AO_LSB_REG(chan)); 942 outb((val >> 8) & 0xff, dev->iobase + DAS16_AO_MSB_REG(chan)); 943 } 944 945 return insn->n; 946} 947 948static int das16_di_insn_bits(struct comedi_device *dev, 949 struct comedi_subdevice *s, 950 struct comedi_insn *insn, 951 unsigned int *data) 952{ 953 data[1] = inb(dev->iobase + DAS16_DIO_REG) & 0xf; 954 955 return insn->n; 956} 957 958static int das16_do_insn_bits(struct comedi_device *dev, 959 struct comedi_subdevice *s, 960 struct comedi_insn *insn, 961 unsigned int *data) 962{ 963 if (comedi_dio_update_state(s, data)) 964 outb(s->state, dev->iobase + DAS16_DIO_REG); 965 966 data[1] = s->state; 967 968 return insn->n; 969} 970 971static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) 972{ 973 const struct das16_board *board = dev->board_ptr; 974 int diobits; 975 976 /* diobits indicates boards */ 977 diobits = inb(dev->iobase + DAS16_DIO_REG) & 0xf0; 978 if (board->id != diobits) { 979 dev_err(dev->class_dev, 980 "requested board's id bits are incorrect (0x%x != 0x%x)\n", 981 board->id, diobits); 982 return -EINVAL; 983 } 984 985 return 0; 986} 987 988static void das16_reset(struct comedi_device *dev) 989{ 990 outb(0, dev->iobase + DAS16_STATUS_REG); 991 outb(0, dev->iobase + DAS16_CTRL_REG); 992 outb(0, dev->iobase + DAS16_PACER_REG); 993 outb(0, dev->iobase + DAS16_TIMER_BASE_REG + i8254_control_reg); 994} 995 996static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) 997{ 998 const struct das16_board *board = dev->board_ptr; 999 struct das16_private_struct *devpriv; 1000 struct comedi_subdevice *s; 1001 struct comedi_lrange *lrange; 1002 struct comedi_krange *krange; 1003 unsigned int dma_chan = it->options[2]; 1004 unsigned int status; 1005 int ret; 1006 1007 /* check that clock setting is valid */ 1008 if (it->options[3]) { 1009 if (it->options[3] != 0 && 1010 it->options[3] != 1 && it->options[3] != 10) { 1011 dev_err(dev->class_dev, 1012 "Invalid option. Master clock must be set to 1 or 10 (MHz)\n"); 1013 return -EINVAL; 1014 } 1015 } 1016 1017 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1018 if (!devpriv) 1019 return -ENOMEM; 1020 1021 if (board->size < 0x400) { 1022 ret = comedi_request_region(dev, it->options[0], board->size); 1023 if (ret) 1024 return ret; 1025 } else { 1026 ret = comedi_request_region(dev, it->options[0], 0x10); 1027 if (ret) 1028 return ret; 1029 /* Request an additional region for the 8255 */ 1030 ret = __comedi_request_region(dev, dev->iobase + 0x400, 1031 board->size & 0x3ff); 1032 if (ret) 1033 return ret; 1034 devpriv->extra_iobase = dev->iobase + 0x400; 1035 devpriv->can_burst = 1; 1036 } 1037 1038 /* probe id bits to make sure they are consistent */ 1039 if (das16_probe(dev, it)) 1040 return -EINVAL; 1041 1042 /* get master clock speed */ 1043 if (devpriv->can_burst) { 1044 status = inb(dev->iobase + DAS1600_STATUS_REG); 1045 1046 if (status & DAS1600_STATUS_CLK_10MHZ) 1047 devpriv->clockbase = I8254_OSC_BASE_10MHZ; 1048 else 1049 devpriv->clockbase = I8254_OSC_BASE_1MHZ; 1050 } else { 1051 if (it->options[3]) 1052 devpriv->clockbase = I8254_OSC_BASE_1MHZ / 1053 it->options[3]; 1054 else 1055 devpriv->clockbase = I8254_OSC_BASE_1MHZ; 1056 } 1057 1058 /* initialize dma */ 1059 if (dma_chan == 1 || dma_chan == 3) { 1060 unsigned long flags; 1061 int i; 1062 1063 if (request_dma(dma_chan, dev->board_name)) { 1064 dev_err(dev->class_dev, 1065 "failed to request dma channel %i\n", 1066 dma_chan); 1067 return -EINVAL; 1068 } 1069 devpriv->dma_chan = dma_chan; 1070 1071 /* allocate dma buffers */ 1072 for (i = 0; i < 2; i++) { 1073 void *p; 1074 1075 p = pci_alloc_consistent(NULL, DAS16_DMA_SIZE, 1076 &devpriv->dma_buffer_addr[i]); 1077 if (!p) 1078 return -ENOMEM; 1079 devpriv->dma_buffer[i] = p; 1080 } 1081 1082 flags = claim_dma_lock(); 1083 disable_dma(devpriv->dma_chan); 1084 set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); 1085 release_dma_lock(flags); 1086 1087 init_timer(&devpriv->timer); 1088 devpriv->timer.function = das16_timer_interrupt; 1089 devpriv->timer.data = (unsigned long)dev; 1090 } 1091 1092 /* get any user-defined input range */ 1093 if (board->ai_pg == das16_pg_none && 1094 (it->options[4] || it->options[5])) { 1095 /* allocate single-range range table */ 1096 lrange = kzalloc(sizeof(*lrange) + sizeof(*krange), GFP_KERNEL); 1097 if (!lrange) 1098 return -ENOMEM; 1099 1100 /* initialize ai range */ 1101 devpriv->user_ai_range_table = lrange; 1102 lrange->length = 1; 1103 krange = devpriv->user_ai_range_table->range; 1104 krange->min = it->options[4]; 1105 krange->max = it->options[5]; 1106 krange->flags = UNIT_volt; 1107 } 1108 1109 /* get any user-defined output range */ 1110 if (it->options[6] || it->options[7]) { 1111 /* allocate single-range range table */ 1112 lrange = kzalloc(sizeof(*lrange) + sizeof(*krange), GFP_KERNEL); 1113 if (!lrange) 1114 return -ENOMEM; 1115 1116 /* initialize ao range */ 1117 devpriv->user_ao_range_table = lrange; 1118 lrange->length = 1; 1119 krange = devpriv->user_ao_range_table->range; 1120 krange->min = it->options[6]; 1121 krange->max = it->options[7]; 1122 krange->flags = UNIT_volt; 1123 } 1124 1125 ret = comedi_alloc_subdevices(dev, 4 + board->has_8255); 1126 if (ret) 1127 return ret; 1128 1129 status = inb(dev->iobase + DAS16_STATUS_REG); 1130 1131 /* Analog Input subdevice */ 1132 s = &dev->subdevices[0]; 1133 s->type = COMEDI_SUBD_AI; 1134 s->subdev_flags = SDF_READABLE; 1135 if (status & DAS16_STATUS_MUXBIT) { 1136 s->subdev_flags |= SDF_GROUND; 1137 s->n_chan = 16; 1138 } else { 1139 s->subdev_flags |= SDF_DIFF; 1140 s->n_chan = 8; 1141 } 1142 s->len_chanlist = s->n_chan; 1143 s->maxdata = board->ai_maxdata; 1144 if (devpriv->user_ai_range_table) { /* user defined ai range */ 1145 s->range_table = devpriv->user_ai_range_table; 1146 } else if (status & DAS16_STATUS_UNIPOLAR) { 1147 s->range_table = das16_ai_uni_lranges[board->ai_pg]; 1148 } else { 1149 s->range_table = das16_ai_bip_lranges[board->ai_pg]; 1150 } 1151 s->insn_read = das16_ai_insn_read; 1152 if (devpriv->dma_chan) { 1153 dev->read_subdev = s; 1154 s->subdev_flags |= SDF_CMD_READ; 1155 s->do_cmdtest = das16_cmd_test; 1156 s->do_cmd = das16_cmd_exec; 1157 s->cancel = das16_cancel; 1158 s->munge = das16_ai_munge; 1159 } 1160 1161 /* Analog Output subdevice */ 1162 s = &dev->subdevices[1]; 1163 if (board->has_ao) { 1164 s->type = COMEDI_SUBD_AO; 1165 s->subdev_flags = SDF_WRITABLE; 1166 s->n_chan = 2; 1167 s->maxdata = 0x0fff; 1168 s->range_table = devpriv->user_ao_range_table; 1169 s->insn_write = das16_ao_insn_write; 1170 s->insn_read = comedi_readback_insn_read; 1171 1172 ret = comedi_alloc_subdev_readback(s); 1173 if (ret) 1174 return ret; 1175 } else { 1176 s->type = COMEDI_SUBD_UNUSED; 1177 } 1178 1179 /* Digital Input subdevice */ 1180 s = &dev->subdevices[2]; 1181 s->type = COMEDI_SUBD_DI; 1182 s->subdev_flags = SDF_READABLE; 1183 s->n_chan = 4; 1184 s->maxdata = 1; 1185 s->range_table = &range_digital; 1186 s->insn_bits = das16_di_insn_bits; 1187 1188 /* Digital Output subdevice */ 1189 s = &dev->subdevices[3]; 1190 s->type = COMEDI_SUBD_DO; 1191 s->subdev_flags = SDF_WRITABLE; 1192 s->n_chan = 4; 1193 s->maxdata = 1; 1194 s->range_table = &range_digital; 1195 s->insn_bits = das16_do_insn_bits; 1196 1197 /* initialize digital output lines */ 1198 outb(s->state, dev->iobase + DAS16_DIO_REG); 1199 1200 /* 8255 Digital I/O subdevice */ 1201 if (board->has_8255) { 1202 s = &dev->subdevices[4]; 1203 ret = subdev_8255_init(dev, s, NULL, board->i8255_offset); 1204 if (ret) 1205 return ret; 1206 } 1207 1208 das16_reset(dev); 1209 /* set the interrupt level */ 1210 devpriv->ctrl_reg = DAS16_CTRL_IRQ(dev->irq); 1211 outb(devpriv->ctrl_reg, dev->iobase + DAS16_CTRL_REG); 1212 1213 if (devpriv->can_burst) { 1214 outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE_REG); 1215 outb(0, dev->iobase + DAS1600_CONV_REG); 1216 outb(0, dev->iobase + DAS1600_BURST_REG); 1217 } 1218 1219 return 0; 1220} 1221 1222static void das16_detach(struct comedi_device *dev) 1223{ 1224 const struct das16_board *board = dev->board_ptr; 1225 struct das16_private_struct *devpriv = dev->private; 1226 int i; 1227 1228 if (devpriv) { 1229 if (dev->iobase) 1230 das16_reset(dev); 1231 1232 for (i = 0; i < 2; i++) { 1233 if (devpriv->dma_buffer[i]) 1234 pci_free_consistent(NULL, DAS16_DMA_SIZE, 1235 devpriv->dma_buffer[i], 1236 devpriv-> 1237 dma_buffer_addr[i]); 1238 } 1239 if (devpriv->dma_chan) 1240 free_dma(devpriv->dma_chan); 1241 kfree(devpriv->user_ai_range_table); 1242 kfree(devpriv->user_ao_range_table); 1243 1244 if (devpriv->extra_iobase) 1245 release_region(devpriv->extra_iobase, 1246 board->size & 0x3ff); 1247 } 1248 1249 comedi_legacy_detach(dev); 1250} 1251 1252static struct comedi_driver das16_driver = { 1253 .driver_name = "das16", 1254 .module = THIS_MODULE, 1255 .attach = das16_attach, 1256 .detach = das16_detach, 1257 .board_name = &das16_boards[0].name, 1258 .num_names = ARRAY_SIZE(das16_boards), 1259 .offset = sizeof(das16_boards[0]), 1260}; 1261module_comedi_driver(das16_driver); 1262 1263MODULE_AUTHOR("Comedi http://www.comedi.org"); 1264MODULE_DESCRIPTION("Comedi driver for DAS16 compatible boards"); 1265MODULE_LICENSE("GPL"); 1266