das1800.c revision 1e3a2875684bcc4af1e2f6597fdd502cc59e3593
1/* 2 comedi/drivers/das1800.c 3 Driver for Keitley das1700/das1800 series boards 4 Copyright (C) 2000 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: das1800 27Description: Keithley Metrabyte DAS1800 (& compatibles) 28Author: Frank Mori Hess <fmhess@users.sourceforge.net> 29Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st), 30 DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao), 31 DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da), 32 DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da), 33 DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st), 34 DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc), 35 DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st), 36 DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr), 37 DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc), 38 DAS-1802AO (das-1802ao) 39Status: works 40 41The waveform analog output on the 'ao' cards is not supported. 42If you need it, send me (Frank Hess) an email. 43 44Configuration options: 45 [0] - I/O port base address 46 [1] - IRQ (optional, required for timed or externally triggered conversions) 47 [2] - DMA0 (optional, requires irq) 48 [3] - DMA1 (optional, requires irq and dma0) 49*/ 50/* 51 52This driver supports the following Keithley boards: 53 54das-1701st 55das-1701st-da 56das-1701ao 57das-1702st 58das-1702st-da 59das-1702hr 60das-1702hr-da 61das-1702ao 62das-1801st 63das-1801st-da 64das-1801hc 65das-1801ao 66das-1802st 67das-1802st-da 68das-1802hr 69das-1802hr-da 70das-1802hc 71das-1802ao 72 73Options: 74 [0] - base io address 75 [1] - irq (optional, required for timed or externally triggered conversions) 76 [2] - dma0 (optional, requires irq) 77 [3] - dma1 (optional, requires irq and dma0) 78 79irq can be omitted, although the cmd interface will not work without it. 80 81analog input cmd triggers supported: 82 start_src: TRIG_NOW | TRIG_EXT 83 scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT 84 scan_end_src: TRIG_COUNT 85 convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW) 86 stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE 87 88scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's 89'burst mode' which limits the valid conversion time to 64 microseconds 90(convert_arg <= 64000). This limitation does not apply if scan_begin_src 91is TRIG_FOLLOW. 92 93NOTES: 94Only the DAS-1801ST has been tested by me. 95Unipolar and bipolar ranges cannot be mixed in the channel/gain list. 96 97TODO: 98 Make it automatically allocate irq and dma channels if they are not specified 99 Add support for analog out on 'ao' cards 100 read insn for analog out 101*/ 102 103#include <linux/interrupt.h> 104#include <linux/slab.h> 105#include <linux/io.h> 106#include "../comedidev.h" 107 108#include <linux/ioport.h> 109#include <asm/dma.h> 110 111#include "8253.h" 112#include "comedi_fc.h" 113 114/* misc. defines */ 115#define DAS1800_SIZE 16 /* uses 16 io addresses */ 116#define FIFO_SIZE 1024 /* 1024 sample fifo */ 117#define TIMER_BASE 200 /* 5 Mhz master clock */ 118#define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */ 119#define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */ 120 121/* Registers for the das1800 */ 122#define DAS1800_FIFO 0x0 123#define DAS1800_QRAM 0x0 124#define DAS1800_DAC 0x0 125#define DAS1800_SELECT 0x2 126#define ADC 0x0 127#define QRAM 0x1 128#define DAC(a) (0x2 + a) 129#define DAS1800_DIGITAL 0x3 130#define DAS1800_CONTROL_A 0x4 131#define FFEN 0x1 132#define CGEN 0x4 133#define CGSL 0x8 134#define TGEN 0x10 135#define TGSL 0x20 136#define ATEN 0x80 137#define DAS1800_CONTROL_B 0x5 138#define DMA_CH5 0x1 139#define DMA_CH6 0x2 140#define DMA_CH7 0x3 141#define DMA_CH5_CH6 0x5 142#define DMA_CH6_CH7 0x6 143#define DMA_CH7_CH5 0x7 144#define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */ 145#define DMA_DUAL 0x4 146#define IRQ3 0x8 147#define IRQ5 0x10 148#define IRQ7 0x18 149#define IRQ10 0x28 150#define IRQ11 0x30 151#define IRQ15 0x38 152#define FIMD 0x40 153#define DAS1800_CONTROL_C 0X6 154#define IPCLK 0x1 155#define XPCLK 0x3 156#define BMDE 0x4 157#define CMEN 0x8 158#define UQEN 0x10 159#define SD 0x40 160#define UB 0x80 161#define DAS1800_STATUS 0x7 162/* bits that prevent interrupt status bits (and CVEN) from being cleared on write */ 163#define CLEAR_INTR_MASK (CVEN_MASK | 0x1f) 164#define INT 0x1 165#define DMATC 0x2 166#define CT0TC 0x8 167#define OVF 0x10 168#define FHF 0x20 169#define FNE 0x40 170#define CVEN_MASK 0x40 /* masks CVEN on write */ 171#define CVEN 0x80 172#define DAS1800_BURST_LENGTH 0x8 173#define DAS1800_BURST_RATE 0x9 174#define DAS1800_QRAM_ADDRESS 0xa 175#define DAS1800_COUNTER 0xc 176 177#define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */ 178 179enum { 180 das1701st, das1701st_da, das1702st, das1702st_da, das1702hr, 181 das1702hr_da, 182 das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da, 183 das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao 184}; 185 186static int das1800_attach(struct comedi_device *dev, 187 struct comedi_devconfig *it); 188static int das1800_detach(struct comedi_device *dev); 189static int das1800_probe(struct comedi_device *dev); 190static int das1800_cancel(struct comedi_device *dev, 191 struct comedi_subdevice *s); 192static irqreturn_t das1800_interrupt(int irq, void *d); 193static int das1800_ai_poll(struct comedi_device *dev, 194 struct comedi_subdevice *s); 195static void das1800_ai_handler(struct comedi_device *dev); 196static void das1800_handle_dma(struct comedi_device *dev, 197 struct comedi_subdevice *s, unsigned int status); 198static void das1800_flush_dma(struct comedi_device *dev, 199 struct comedi_subdevice *s); 200static void das1800_flush_dma_channel(struct comedi_device *dev, 201 struct comedi_subdevice *s, 202 unsigned int channel, uint16_t *buffer); 203static void das1800_handle_fifo_half_full(struct comedi_device *dev, 204 struct comedi_subdevice *s); 205static void das1800_handle_fifo_not_empty(struct comedi_device *dev, 206 struct comedi_subdevice *s); 207static int das1800_ai_do_cmdtest(struct comedi_device *dev, 208 struct comedi_subdevice *s, 209 struct comedi_cmd *cmd); 210static int das1800_ai_do_cmd(struct comedi_device *dev, 211 struct comedi_subdevice *s); 212static int das1800_ai_rinsn(struct comedi_device *dev, 213 struct comedi_subdevice *s, 214 struct comedi_insn *insn, unsigned int *data); 215static int das1800_ao_winsn(struct comedi_device *dev, 216 struct comedi_subdevice *s, 217 struct comedi_insn *insn, unsigned int *data); 218static int das1800_di_rbits(struct comedi_device *dev, 219 struct comedi_subdevice *s, 220 struct comedi_insn *insn, unsigned int *data); 221static int das1800_do_wbits(struct comedi_device *dev, 222 struct comedi_subdevice *s, 223 struct comedi_insn *insn, unsigned int *data); 224 225static int das1800_set_frequency(struct comedi_device *dev); 226static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode); 227static unsigned int suggest_transfer_size(struct comedi_cmd *cmd); 228 229/* analog input ranges */ 230static const struct comedi_lrange range_ai_das1801 = { 231 8, 232 { 233 RANGE(-5, 5), 234 RANGE(-1, 1), 235 RANGE(-0.1, 0.1), 236 RANGE(-0.02, 0.02), 237 RANGE(0, 5), 238 RANGE(0, 1), 239 RANGE(0, 0.1), 240 RANGE(0, 0.02), 241 } 242}; 243 244static const struct comedi_lrange range_ai_das1802 = { 245 8, 246 { 247 RANGE(-10, 10), 248 RANGE(-5, 5), 249 RANGE(-2.5, 2.5), 250 RANGE(-1.25, 1.25), 251 RANGE(0, 10), 252 RANGE(0, 5), 253 RANGE(0, 2.5), 254 RANGE(0, 1.25), 255 } 256}; 257 258struct das1800_board { 259 const char *name; 260 int ai_speed; /* max conversion period in nanoseconds */ 261 int resolution; /* bits of ai resolution */ 262 int qram_len; /* length of card's channel / gain queue */ 263 int common; /* supports AREF_COMMON flag */ 264 int do_n_chan; /* number of digital output channels */ 265 int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */ 266 int ao_n_chan; /* number of analog out channels */ 267 const struct comedi_lrange *range_ai; /* available input ranges */ 268}; 269 270/* Warning: the maximum conversion speeds listed below are 271 * not always achievable depending on board setup (see 272 * user manual.) 273 */ 274static const struct das1800_board das1800_boards[] = { 275 { 276 .name = "das-1701st", 277 .ai_speed = 6250, 278 .resolution = 12, 279 .qram_len = 256, 280 .common = 1, 281 .do_n_chan = 4, 282 .ao_ability = 0, 283 .ao_n_chan = 0, 284 .range_ai = &range_ai_das1801, 285 }, 286 { 287 .name = "das-1701st-da", 288 .ai_speed = 6250, 289 .resolution = 12, 290 .qram_len = 256, 291 .common = 1, 292 .do_n_chan = 4, 293 .ao_ability = 1, 294 .ao_n_chan = 4, 295 .range_ai = &range_ai_das1801, 296 }, 297 { 298 .name = "das-1702st", 299 .ai_speed = 6250, 300 .resolution = 12, 301 .qram_len = 256, 302 .common = 1, 303 .do_n_chan = 4, 304 .ao_ability = 0, 305 .ao_n_chan = 0, 306 .range_ai = &range_ai_das1802, 307 }, 308 { 309 .name = "das-1702st-da", 310 .ai_speed = 6250, 311 .resolution = 12, 312 .qram_len = 256, 313 .common = 1, 314 .do_n_chan = 4, 315 .ao_ability = 1, 316 .ao_n_chan = 4, 317 .range_ai = &range_ai_das1802, 318 }, 319 { 320 .name = "das-1702hr", 321 .ai_speed = 20000, 322 .resolution = 16, 323 .qram_len = 256, 324 .common = 1, 325 .do_n_chan = 4, 326 .ao_ability = 0, 327 .ao_n_chan = 0, 328 .range_ai = &range_ai_das1802, 329 }, 330 { 331 .name = "das-1702hr-da", 332 .ai_speed = 20000, 333 .resolution = 16, 334 .qram_len = 256, 335 .common = 1, 336 .do_n_chan = 4, 337 .ao_ability = 1, 338 .ao_n_chan = 2, 339 .range_ai = &range_ai_das1802, 340 }, 341 { 342 .name = "das-1701ao", 343 .ai_speed = 6250, 344 .resolution = 12, 345 .qram_len = 256, 346 .common = 1, 347 .do_n_chan = 4, 348 .ao_ability = 2, 349 .ao_n_chan = 2, 350 .range_ai = &range_ai_das1801, 351 }, 352 { 353 .name = "das-1702ao", 354 .ai_speed = 6250, 355 .resolution = 12, 356 .qram_len = 256, 357 .common = 1, 358 .do_n_chan = 4, 359 .ao_ability = 2, 360 .ao_n_chan = 2, 361 .range_ai = &range_ai_das1802, 362 }, 363 { 364 .name = "das-1801st", 365 .ai_speed = 3000, 366 .resolution = 12, 367 .qram_len = 256, 368 .common = 1, 369 .do_n_chan = 4, 370 .ao_ability = 0, 371 .ao_n_chan = 0, 372 .range_ai = &range_ai_das1801, 373 }, 374 { 375 .name = "das-1801st-da", 376 .ai_speed = 3000, 377 .resolution = 12, 378 .qram_len = 256, 379 .common = 1, 380 .do_n_chan = 4, 381 .ao_ability = 0, 382 .ao_n_chan = 4, 383 .range_ai = &range_ai_das1801, 384 }, 385 { 386 .name = "das-1802st", 387 .ai_speed = 3000, 388 .resolution = 12, 389 .qram_len = 256, 390 .common = 1, 391 .do_n_chan = 4, 392 .ao_ability = 0, 393 .ao_n_chan = 0, 394 .range_ai = &range_ai_das1802, 395 }, 396 { 397 .name = "das-1802st-da", 398 .ai_speed = 3000, 399 .resolution = 12, 400 .qram_len = 256, 401 .common = 1, 402 .do_n_chan = 4, 403 .ao_ability = 1, 404 .ao_n_chan = 4, 405 .range_ai = &range_ai_das1802, 406 }, 407 { 408 .name = "das-1802hr", 409 .ai_speed = 10000, 410 .resolution = 16, 411 .qram_len = 256, 412 .common = 1, 413 .do_n_chan = 4, 414 .ao_ability = 0, 415 .ao_n_chan = 0, 416 .range_ai = &range_ai_das1802, 417 }, 418 { 419 .name = "das-1802hr-da", 420 .ai_speed = 10000, 421 .resolution = 16, 422 .qram_len = 256, 423 .common = 1, 424 .do_n_chan = 4, 425 .ao_ability = 1, 426 .ao_n_chan = 2, 427 .range_ai = &range_ai_das1802, 428 }, 429 { 430 .name = "das-1801hc", 431 .ai_speed = 3000, 432 .resolution = 12, 433 .qram_len = 64, 434 .common = 0, 435 .do_n_chan = 8, 436 .ao_ability = 1, 437 .ao_n_chan = 2, 438 .range_ai = &range_ai_das1801, 439 }, 440 { 441 .name = "das-1802hc", 442 .ai_speed = 3000, 443 .resolution = 12, 444 .qram_len = 64, 445 .common = 0, 446 .do_n_chan = 8, 447 .ao_ability = 1, 448 .ao_n_chan = 2, 449 .range_ai = &range_ai_das1802, 450 }, 451 { 452 .name = "das-1801ao", 453 .ai_speed = 3000, 454 .resolution = 12, 455 .qram_len = 256, 456 .common = 1, 457 .do_n_chan = 4, 458 .ao_ability = 2, 459 .ao_n_chan = 2, 460 .range_ai = &range_ai_das1801, 461 }, 462 { 463 .name = "das-1802ao", 464 .ai_speed = 3000, 465 .resolution = 12, 466 .qram_len = 256, 467 .common = 1, 468 .do_n_chan = 4, 469 .ao_ability = 2, 470 .ao_n_chan = 2, 471 .range_ai = &range_ai_das1802, 472 }, 473}; 474 475/* 476 * Useful for shorthand access to the particular board structure 477 */ 478#define thisboard ((const struct das1800_board *)dev->board_ptr) 479 480struct das1800_private { 481 volatile unsigned int count; /* number of data points left to be taken */ 482 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */ 483 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */ 484 int do_bits; /* digital output bits */ 485 int irq_dma_bits; /* bits for control register b */ 486 /* dma bits for control register b, stored so that dma can be 487 * turned on and off */ 488 int dma_bits; 489 unsigned int dma0; /* dma channels used */ 490 unsigned int dma1; 491 volatile unsigned int dma_current; /* dma channel currently in use */ 492 uint16_t *ai_buf0; /* pointers to dma buffers */ 493 uint16_t *ai_buf1; 494 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */ 495 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */ 496 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */ 497 short ao_update_bits; /* remembers the last write to the 'update' dac */ 498}; 499 500#define devpriv ((struct das1800_private *)dev->private) 501 502/* analog out range for boards with basic analog out */ 503static const struct comedi_lrange range_ao_1 = { 504 1, 505 { 506 RANGE(-10, 10), 507 } 508}; 509 510/* analog out range for 'ao' boards */ 511/* 512static const struct comedi_lrange range_ao_2 = { 513 2, 514 { 515 RANGE(-10, 10), 516 RANGE(-5, 5), 517 } 518}; 519*/ 520 521static struct comedi_driver driver_das1800 = { 522 .driver_name = "das1800", 523 .module = THIS_MODULE, 524 .attach = das1800_attach, 525 .detach = das1800_detach, 526 .num_names = ARRAY_SIZE(das1800_boards), 527 .board_name = &das1800_boards[0].name, 528 .offset = sizeof(struct das1800_board), 529}; 530 531/* 532 * A convenient macro that defines init_module() and cleanup_module(), 533 * as necessary. 534 */ 535static int __init driver_das1800_init_module(void) 536{ 537 return comedi_driver_register(&driver_das1800); 538} 539 540static void __exit driver_das1800_cleanup_module(void) 541{ 542 comedi_driver_unregister(&driver_das1800); 543} 544 545module_init(driver_das1800_init_module); 546module_exit(driver_das1800_cleanup_module); 547 548static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, 549 unsigned int dma1) 550{ 551 unsigned long flags; 552 553 /* need an irq to do dma */ 554 if (dev->irq && dma0) { 555 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ 556 switch ((dma0 & 0x7) | (dma1 << 4)) { 557 case 0x5: /* dma0 == 5 */ 558 devpriv->dma_bits |= DMA_CH5; 559 break; 560 case 0x6: /* dma0 == 6 */ 561 devpriv->dma_bits |= DMA_CH6; 562 break; 563 case 0x7: /* dma0 == 7 */ 564 devpriv->dma_bits |= DMA_CH7; 565 break; 566 case 0x65: /* dma0 == 5, dma1 == 6 */ 567 devpriv->dma_bits |= DMA_CH5_CH6; 568 break; 569 case 0x76: /* dma0 == 6, dma1 == 7 */ 570 devpriv->dma_bits |= DMA_CH6_CH7; 571 break; 572 case 0x57: /* dma0 == 7, dma1 == 5 */ 573 devpriv->dma_bits |= DMA_CH7_CH5; 574 break; 575 default: 576 printk(" only supports dma channels 5 through 7\n" 577 " Dual dma only allows the following combinations:\n" 578 " dma 5,6 / 6,7 / or 7,5\n"); 579 return -EINVAL; 580 break; 581 } 582 if (request_dma(dma0, driver_das1800.driver_name)) { 583 dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", 584 dma0); 585 return -EINVAL; 586 } 587 devpriv->dma0 = dma0; 588 devpriv->dma_current = dma0; 589 if (dma1) { 590 if (request_dma(dma1, driver_das1800.driver_name)) { 591 dev_err(dev->hw_dev, "failed to allocate dma channel %i\n", 592 dma1); 593 return -EINVAL; 594 } 595 devpriv->dma1 = dma1; 596 } 597 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 598 if (devpriv->ai_buf0 == NULL) 599 return -ENOMEM; 600 devpriv->dma_current_buf = devpriv->ai_buf0; 601 if (dma1) { 602 devpriv->ai_buf1 = 603 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 604 if (devpriv->ai_buf1 == NULL) 605 return -ENOMEM; 606 } 607 flags = claim_dma_lock(); 608 disable_dma(devpriv->dma0); 609 set_dma_mode(devpriv->dma0, DMA_MODE_READ); 610 if (dma1) { 611 disable_dma(devpriv->dma1); 612 set_dma_mode(devpriv->dma1, DMA_MODE_READ); 613 } 614 release_dma_lock(flags); 615 } 616 return 0; 617} 618 619static int das1800_attach(struct comedi_device *dev, 620 struct comedi_devconfig *it) 621{ 622 struct comedi_subdevice *s; 623 unsigned long iobase = it->options[0]; 624 unsigned int irq = it->options[1]; 625 unsigned int dma0 = it->options[2]; 626 unsigned int dma1 = it->options[3]; 627 unsigned long iobase2; 628 int board; 629 int retval; 630 631 /* allocate and initialize dev->private */ 632 if (alloc_private(dev, sizeof(struct das1800_private)) < 0) 633 return -ENOMEM; 634 635 printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name, 636 iobase); 637 if (irq) { 638 printk(", irq %u", irq); 639 if (dma0) { 640 printk(", dma %u", dma0); 641 if (dma1) 642 printk(" and %u", dma1); 643 } 644 } 645 printk("\n"); 646 647 if (iobase == 0) { 648 printk(" io base address required\n"); 649 return -EINVAL; 650 } 651 652 /* check if io addresses are available */ 653 if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) { 654 printk 655 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", 656 iobase, iobase + DAS1800_SIZE - 1); 657 return -EIO; 658 } 659 dev->iobase = iobase; 660 661 board = das1800_probe(dev); 662 if (board < 0) { 663 dev_err(dev->hw_dev, "unable to determine board type\n"); 664 return -ENODEV; 665 } 666 667 dev->board_ptr = das1800_boards + board; 668 dev->board_name = thisboard->name; 669 670 /* if it is an 'ao' board with fancy analog out then we need extra io ports */ 671 if (thisboard->ao_ability == 2) { 672 iobase2 = iobase + IOBASE2; 673 if (!request_region(iobase2, DAS1800_SIZE, 674 driver_das1800.driver_name)) { 675 printk 676 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", 677 iobase2, iobase2 + DAS1800_SIZE - 1); 678 return -EIO; 679 } 680 devpriv->iobase2 = iobase2; 681 } 682 683 /* grab our IRQ */ 684 if (irq) { 685 if (request_irq(irq, das1800_interrupt, 0, 686 driver_das1800.driver_name, dev)) { 687 dev_dbg(dev->hw_dev, "unable to allocate irq %u\n", 688 irq); 689 return -EINVAL; 690 } 691 } 692 dev->irq = irq; 693 694 /* set bits that tell card which irq to use */ 695 switch (irq) { 696 case 0: 697 break; 698 case 3: 699 devpriv->irq_dma_bits |= 0x8; 700 break; 701 case 5: 702 devpriv->irq_dma_bits |= 0x10; 703 break; 704 case 7: 705 devpriv->irq_dma_bits |= 0x18; 706 break; 707 case 10: 708 devpriv->irq_dma_bits |= 0x28; 709 break; 710 case 11: 711 devpriv->irq_dma_bits |= 0x30; 712 break; 713 case 15: 714 devpriv->irq_dma_bits |= 0x38; 715 break; 716 default: 717 dev_err(dev->hw_dev, "irq out of range\n"); 718 return -EINVAL; 719 break; 720 } 721 722 retval = das1800_init_dma(dev, dma0, dma1); 723 if (retval < 0) 724 return retval; 725 726 if (devpriv->ai_buf0 == NULL) { 727 devpriv->ai_buf0 = 728 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); 729 if (devpriv->ai_buf0 == NULL) 730 return -ENOMEM; 731 } 732 733 if (alloc_subdevices(dev, 4) < 0) 734 return -ENOMEM; 735 736 /* analog input subdevice */ 737 s = dev->subdevices + 0; 738 dev->read_subdev = s; 739 s->type = COMEDI_SUBD_AI; 740 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; 741 if (thisboard->common) 742 s->subdev_flags |= SDF_COMMON; 743 s->n_chan = thisboard->qram_len; 744 s->len_chanlist = thisboard->qram_len; 745 s->maxdata = (1 << thisboard->resolution) - 1; 746 s->range_table = thisboard->range_ai; 747 s->do_cmd = das1800_ai_do_cmd; 748 s->do_cmdtest = das1800_ai_do_cmdtest; 749 s->insn_read = das1800_ai_rinsn; 750 s->poll = das1800_ai_poll; 751 s->cancel = das1800_cancel; 752 753 /* analog out */ 754 s = dev->subdevices + 1; 755 if (thisboard->ao_ability == 1) { 756 s->type = COMEDI_SUBD_AO; 757 s->subdev_flags = SDF_WRITABLE; 758 s->n_chan = thisboard->ao_n_chan; 759 s->maxdata = (1 << thisboard->resolution) - 1; 760 s->range_table = &range_ao_1; 761 s->insn_write = das1800_ao_winsn; 762 } else { 763 s->type = COMEDI_SUBD_UNUSED; 764 } 765 766 /* di */ 767 s = dev->subdevices + 2; 768 s->type = COMEDI_SUBD_DI; 769 s->subdev_flags = SDF_READABLE; 770 s->n_chan = 4; 771 s->maxdata = 1; 772 s->range_table = &range_digital; 773 s->insn_bits = das1800_di_rbits; 774 775 /* do */ 776 s = dev->subdevices + 3; 777 s->type = COMEDI_SUBD_DO; 778 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 779 s->n_chan = thisboard->do_n_chan; 780 s->maxdata = 1; 781 s->range_table = &range_digital; 782 s->insn_bits = das1800_do_wbits; 783 784 das1800_cancel(dev, dev->read_subdev); 785 786 /* initialize digital out channels */ 787 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 788 789 /* initialize analog out channels */ 790 if (thisboard->ao_ability == 1) { 791 /* select 'update' dac channel for baseAddress + 0x0 */ 792 outb(DAC(thisboard->ao_n_chan - 1), 793 dev->iobase + DAS1800_SELECT); 794 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 795 } 796 797 return 0; 798}; 799 800static int das1800_detach(struct comedi_device *dev) 801{ 802 /* only free stuff if it has been allocated by _attach */ 803 if (dev->iobase) 804 release_region(dev->iobase, DAS1800_SIZE); 805 if (dev->irq) 806 free_irq(dev->irq, dev); 807 if (dev->private) { 808 if (devpriv->iobase2) 809 release_region(devpriv->iobase2, DAS1800_SIZE); 810 if (devpriv->dma0) 811 free_dma(devpriv->dma0); 812 if (devpriv->dma1) 813 free_dma(devpriv->dma1); 814 kfree(devpriv->ai_buf0); 815 kfree(devpriv->ai_buf1); 816 } 817 818 printk("comedi%d: %s: remove\n", dev->minor, 819 driver_das1800.driver_name); 820 821 return 0; 822}; 823 824/* probes and checks das-1800 series board type 825 */ 826static int das1800_probe(struct comedi_device *dev) 827{ 828 int id; 829 int board; 830 831 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */ 832 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards; 833 834 switch (id) { 835 case 0x3: 836 if (board == das1801st_da || board == das1802st_da || 837 board == das1701st_da || board == das1702st_da) { 838 printk(" Board model: %s\n", 839 das1800_boards[board].name); 840 return board; 841 } 842 printk 843 (" Board model (probed, not recommended): das-1800st-da series\n"); 844 return das1801st; 845 break; 846 case 0x4: 847 if (board == das1802hr_da || board == das1702hr_da) { 848 printk(" Board model: %s\n", 849 das1800_boards[board].name); 850 return board; 851 } 852 printk 853 (" Board model (probed, not recommended): das-1802hr-da\n"); 854 return das1802hr; 855 break; 856 case 0x5: 857 if (board == das1801ao || board == das1802ao || 858 board == das1701ao || board == das1702ao) { 859 printk(" Board model: %s\n", 860 das1800_boards[board].name); 861 return board; 862 } 863 printk 864 (" Board model (probed, not recommended): das-1800ao series\n"); 865 return das1801ao; 866 break; 867 case 0x6: 868 if (board == das1802hr || board == das1702hr) { 869 printk(" Board model: %s\n", 870 das1800_boards[board].name); 871 return board; 872 } 873 printk(" Board model (probed, not recommended): das-1802hr\n"); 874 return das1802hr; 875 break; 876 case 0x7: 877 if (board == das1801st || board == das1802st || 878 board == das1701st || board == das1702st) { 879 printk(" Board model: %s\n", 880 das1800_boards[board].name); 881 return board; 882 } 883 printk 884 (" Board model (probed, not recommended): das-1800st series\n"); 885 return das1801st; 886 break; 887 case 0x8: 888 if (board == das1801hc || board == das1802hc) { 889 printk(" Board model: %s\n", 890 das1800_boards[board].name); 891 return board; 892 } 893 printk 894 (" Board model (probed, not recommended): das-1800hc series\n"); 895 return das1801hc; 896 break; 897 default: 898 printk 899 (" Board model: probe returned 0x%x (unknown, please report)\n", 900 id); 901 return board; 902 break; 903 } 904 return -1; 905} 906 907static int das1800_ai_poll(struct comedi_device *dev, 908 struct comedi_subdevice *s) 909{ 910 unsigned long flags; 911 912 /* prevent race with interrupt handler */ 913 spin_lock_irqsave(&dev->spinlock, flags); 914 das1800_ai_handler(dev); 915 spin_unlock_irqrestore(&dev->spinlock, flags); 916 917 return s->async->buf_write_count - s->async->buf_read_count; 918} 919 920static irqreturn_t das1800_interrupt(int irq, void *d) 921{ 922 struct comedi_device *dev = d; 923 unsigned int status; 924 925 if (dev->attached == 0) { 926 comedi_error(dev, "premature interrupt"); 927 return IRQ_HANDLED; 928 } 929 930 /* Prevent race with das1800_ai_poll() on multi processor systems. 931 * Also protects indirect addressing in das1800_ai_handler */ 932 spin_lock(&dev->spinlock); 933 status = inb(dev->iobase + DAS1800_STATUS); 934 935 /* if interrupt was not caused by das-1800 */ 936 if (!(status & INT)) { 937 spin_unlock(&dev->spinlock); 938 return IRQ_NONE; 939 } 940 /* clear the interrupt status bit INT */ 941 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); 942 /* handle interrupt */ 943 das1800_ai_handler(dev); 944 945 spin_unlock(&dev->spinlock); 946 return IRQ_HANDLED; 947} 948 949/* the guts of the interrupt handler, that is shared with das1800_ai_poll */ 950static void das1800_ai_handler(struct comedi_device *dev) 951{ 952 struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */ 953 struct comedi_async *async = s->async; 954 struct comedi_cmd *cmd = &async->cmd; 955 unsigned int status = inb(dev->iobase + DAS1800_STATUS); 956 957 async->events = 0; 958 /* select adc for base address + 0 */ 959 outb(ADC, dev->iobase + DAS1800_SELECT); 960 /* dma buffer full */ 961 if (devpriv->irq_dma_bits & DMA_ENABLED) { 962 /* look for data from dma transfer even if dma terminal count hasn't happened yet */ 963 das1800_handle_dma(dev, s, status); 964 } else if (status & FHF) { /* if fifo half full */ 965 das1800_handle_fifo_half_full(dev, s); 966 } else if (status & FNE) { /* if fifo not empty */ 967 das1800_handle_fifo_not_empty(dev, s); 968 } 969 970 async->events |= COMEDI_CB_BLOCK; 971 /* if the card's fifo has overflowed */ 972 if (status & OVF) { 973 /* clear OVF interrupt bit */ 974 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); 975 comedi_error(dev, "DAS1800 FIFO overflow"); 976 das1800_cancel(dev, s); 977 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 978 comedi_event(dev, s); 979 return; 980 } 981 /* stop taking data if appropriate */ 982 /* stop_src TRIG_EXT */ 983 if (status & CT0TC) { 984 /* clear CT0TC interrupt bit */ 985 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS); 986 /* make sure we get all remaining data from board before quitting */ 987 if (devpriv->irq_dma_bits & DMA_ENABLED) 988 das1800_flush_dma(dev, s); 989 else 990 das1800_handle_fifo_not_empty(dev, s); 991 das1800_cancel(dev, s); /* disable hardware conversions */ 992 async->events |= COMEDI_CB_EOA; 993 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */ 994 das1800_cancel(dev, s); /* disable hardware conversions */ 995 async->events |= COMEDI_CB_EOA; 996 } 997 998 comedi_event(dev, s); 999 1000 return; 1001} 1002 1003static void das1800_handle_dma(struct comedi_device *dev, 1004 struct comedi_subdevice *s, unsigned int status) 1005{ 1006 unsigned long flags; 1007 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1008 1009 flags = claim_dma_lock(); 1010 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1011 devpriv->dma_current_buf); 1012 /* re-enable dma channel */ 1013 set_dma_addr(devpriv->dma_current, 1014 virt_to_bus(devpriv->dma_current_buf)); 1015 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); 1016 enable_dma(devpriv->dma_current); 1017 release_dma_lock(flags); 1018 1019 if (status & DMATC) { 1020 /* clear DMATC interrupt bit */ 1021 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); 1022 /* switch dma channels for next time, if appropriate */ 1023 if (dual_dma) { 1024 /* read data from the other channel next time */ 1025 if (devpriv->dma_current == devpriv->dma0) { 1026 devpriv->dma_current = devpriv->dma1; 1027 devpriv->dma_current_buf = devpriv->ai_buf1; 1028 } else { 1029 devpriv->dma_current = devpriv->dma0; 1030 devpriv->dma_current_buf = devpriv->ai_buf0; 1031 } 1032 } 1033 } 1034 1035 return; 1036} 1037 1038static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, 1039 uint16_t sample) 1040{ 1041 sample += 1 << (thisboard->resolution - 1); 1042 return sample; 1043} 1044 1045static void munge_data(struct comedi_device *dev, uint16_t * array, 1046 unsigned int num_elements) 1047{ 1048 unsigned int i; 1049 int unipolar; 1050 1051 /* see if card is using a unipolar or bipolar range so we can munge data correctly */ 1052 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1053 1054 /* convert to unsigned type if we are in a bipolar mode */ 1055 if (!unipolar) { 1056 for (i = 0; i < num_elements; i++) 1057 array[i] = munge_bipolar_sample(dev, array[i]); 1058 } 1059} 1060 1061/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). 1062 * Assumes dma lock is held */ 1063static void das1800_flush_dma_channel(struct comedi_device *dev, 1064 struct comedi_subdevice *s, 1065 unsigned int channel, uint16_t *buffer) 1066{ 1067 unsigned int num_bytes, num_samples; 1068 struct comedi_cmd *cmd = &s->async->cmd; 1069 1070 disable_dma(channel); 1071 1072 /* clear flip-flop to make sure 2-byte registers 1073 * get set correctly */ 1074 clear_dma_ff(channel); 1075 1076 /* figure out how many points to read */ 1077 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); 1078 num_samples = num_bytes / sizeof(short); 1079 1080 /* if we only need some of the points */ 1081 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) 1082 num_samples = devpriv->count; 1083 1084 munge_data(dev, buffer, num_samples); 1085 cfc_write_array_to_buffer(s, buffer, num_bytes); 1086 if (s->async->cmd.stop_src == TRIG_COUNT) 1087 devpriv->count -= num_samples; 1088 1089 return; 1090} 1091 1092/* flushes remaining data from board when external trigger has stopped acquisition 1093 * and we are using dma transfers */ 1094static void das1800_flush_dma(struct comedi_device *dev, 1095 struct comedi_subdevice *s) 1096{ 1097 unsigned long flags; 1098 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1099 1100 flags = claim_dma_lock(); 1101 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1102 devpriv->dma_current_buf); 1103 1104 if (dual_dma) { 1105 /* switch to other channel and flush it */ 1106 if (devpriv->dma_current == devpriv->dma0) { 1107 devpriv->dma_current = devpriv->dma1; 1108 devpriv->dma_current_buf = devpriv->ai_buf1; 1109 } else { 1110 devpriv->dma_current = devpriv->dma0; 1111 devpriv->dma_current_buf = devpriv->ai_buf0; 1112 } 1113 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1114 devpriv->dma_current_buf); 1115 } 1116 1117 release_dma_lock(flags); 1118 1119 /* get any remaining samples in fifo */ 1120 das1800_handle_fifo_not_empty(dev, s); 1121 1122 return; 1123} 1124 1125static void das1800_handle_fifo_half_full(struct comedi_device *dev, 1126 struct comedi_subdevice *s) 1127{ 1128 int numPoints = 0; /* number of points to read */ 1129 struct comedi_cmd *cmd = &s->async->cmd; 1130 1131 numPoints = FIFO_SIZE / 2; 1132 /* if we only need some of the points */ 1133 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) 1134 numPoints = devpriv->count; 1135 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); 1136 munge_data(dev, devpriv->ai_buf0, numPoints); 1137 cfc_write_array_to_buffer(s, devpriv->ai_buf0, 1138 numPoints * sizeof(devpriv->ai_buf0[0])); 1139 if (cmd->stop_src == TRIG_COUNT) 1140 devpriv->count -= numPoints; 1141 return; 1142} 1143 1144static void das1800_handle_fifo_not_empty(struct comedi_device *dev, 1145 struct comedi_subdevice *s) 1146{ 1147 short dpnt; 1148 int unipolar; 1149 struct comedi_cmd *cmd = &s->async->cmd; 1150 1151 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1152 1153 while (inb(dev->iobase + DAS1800_STATUS) & FNE) { 1154 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) 1155 break; 1156 dpnt = inw(dev->iobase + DAS1800_FIFO); 1157 /* convert to unsigned type if we are in a bipolar mode */ 1158 if (!unipolar) 1159 ; 1160 dpnt = munge_bipolar_sample(dev, dpnt); 1161 cfc_write_to_buffer(s, dpnt); 1162 if (cmd->stop_src == TRIG_COUNT) 1163 devpriv->count--; 1164 } 1165 1166 return; 1167} 1168 1169static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 1170{ 1171 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ 1172 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ 1173 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ 1174 if (devpriv->dma0) 1175 disable_dma(devpriv->dma0); 1176 if (devpriv->dma1) 1177 disable_dma(devpriv->dma1); 1178 return 0; 1179} 1180 1181/* test analog input cmd */ 1182static int das1800_ai_do_cmdtest(struct comedi_device *dev, 1183 struct comedi_subdevice *s, 1184 struct comedi_cmd *cmd) 1185{ 1186 int err = 0; 1187 int tmp; 1188 unsigned int tmp_arg; 1189 int i; 1190 int unipolar; 1191 1192 /* step 1: make sure trigger sources are trivially valid */ 1193 1194 tmp = cmd->start_src; 1195 cmd->start_src &= TRIG_NOW | TRIG_EXT; 1196 if (!cmd->start_src || tmp != cmd->start_src) 1197 err++; 1198 1199 tmp = cmd->scan_begin_src; 1200 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 1201 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 1202 err++; 1203 1204 tmp = cmd->convert_src; 1205 cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 1206 if (!cmd->convert_src || tmp != cmd->convert_src) 1207 err++; 1208 1209 tmp = cmd->scan_end_src; 1210 cmd->scan_end_src &= TRIG_COUNT; 1211 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 1212 err++; 1213 1214 tmp = cmd->stop_src; 1215 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE; 1216 if (!cmd->stop_src || tmp != cmd->stop_src) 1217 err++; 1218 1219 if (err) 1220 return 1; 1221 1222 /* step 2: make sure trigger sources are unique and mutually compatible */ 1223 1224 /* uniqueness check */ 1225 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 1226 err++; 1227 if (cmd->scan_begin_src != TRIG_FOLLOW && 1228 cmd->scan_begin_src != TRIG_TIMER && 1229 cmd->scan_begin_src != TRIG_EXT) 1230 err++; 1231 if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 1232 err++; 1233 if (cmd->stop_src != TRIG_COUNT && 1234 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT) 1235 err++; 1236 /* compatibility check */ 1237 if (cmd->scan_begin_src != TRIG_FOLLOW && 1238 cmd->convert_src != TRIG_TIMER) 1239 err++; 1240 1241 if (err) 1242 return 2; 1243 1244 /* step 3: make sure arguments are trivially compatible */ 1245 1246 if (cmd->start_arg != 0) { 1247 cmd->start_arg = 0; 1248 err++; 1249 } 1250 if (cmd->convert_src == TRIG_TIMER) { 1251 if (cmd->convert_arg < thisboard->ai_speed) { 1252 cmd->convert_arg = thisboard->ai_speed; 1253 err++; 1254 } 1255 } 1256 if (!cmd->chanlist_len) { 1257 cmd->chanlist_len = 1; 1258 err++; 1259 } 1260 if (cmd->scan_end_arg != cmd->chanlist_len) { 1261 cmd->scan_end_arg = cmd->chanlist_len; 1262 err++; 1263 } 1264 1265 switch (cmd->stop_src) { 1266 case TRIG_COUNT: 1267 if (!cmd->stop_arg) { 1268 cmd->stop_arg = 1; 1269 err++; 1270 } 1271 break; 1272 case TRIG_NONE: 1273 if (cmd->stop_arg != 0) { 1274 cmd->stop_arg = 0; 1275 err++; 1276 } 1277 break; 1278 default: 1279 break; 1280 } 1281 1282 if (err) 1283 return 3; 1284 1285 /* step 4: fix up any arguments */ 1286 1287 if (cmd->convert_src == TRIG_TIMER) { 1288 /* if we are not in burst mode */ 1289 if (cmd->scan_begin_src == TRIG_FOLLOW) { 1290 tmp_arg = cmd->convert_arg; 1291 /* calculate counter values that give desired timing */ 1292 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1293 &(devpriv->divisor1), 1294 &(devpriv->divisor2), 1295 &(cmd->convert_arg), 1296 cmd-> 1297 flags & TRIG_ROUND_MASK); 1298 if (tmp_arg != cmd->convert_arg) 1299 err++; 1300 } 1301 /* if we are in burst mode */ 1302 else { 1303 /* check that convert_arg is compatible */ 1304 tmp_arg = cmd->convert_arg; 1305 cmd->convert_arg = 1306 burst_convert_arg(cmd->convert_arg, 1307 cmd->flags & TRIG_ROUND_MASK); 1308 if (tmp_arg != cmd->convert_arg) 1309 err++; 1310 1311 if (cmd->scan_begin_src == TRIG_TIMER) { 1312 /* if scans are timed faster than conversion rate allows */ 1313 if (cmd->convert_arg * cmd->chanlist_len > 1314 cmd->scan_begin_arg) { 1315 cmd->scan_begin_arg = 1316 cmd->convert_arg * 1317 cmd->chanlist_len; 1318 err++; 1319 } 1320 tmp_arg = cmd->scan_begin_arg; 1321 /* calculate counter values that give desired timing */ 1322 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1323 &(devpriv-> 1324 divisor1), 1325 &(devpriv-> 1326 divisor2), 1327 &(cmd-> 1328 scan_begin_arg), 1329 cmd-> 1330 flags & 1331 TRIG_ROUND_MASK); 1332 if (tmp_arg != cmd->scan_begin_arg) 1333 err++; 1334 } 1335 } 1336 } 1337 1338 if (err) 1339 return 4; 1340 1341 /* make sure user is not trying to mix unipolar and bipolar ranges */ 1342 if (cmd->chanlist) { 1343 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR; 1344 for (i = 1; i < cmd->chanlist_len; i++) { 1345 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) { 1346 comedi_error(dev, 1347 "unipolar and bipolar ranges cannot be mixed in the chanlist"); 1348 err++; 1349 break; 1350 } 1351 } 1352 } 1353 1354 if (err) 1355 return 5; 1356 1357 return 0; 1358} 1359 1360/* analog input cmd interface */ 1361 1362/* first, some utility functions used in the main ai_do_cmd() */ 1363 1364/* returns appropriate bits for control register a, depending on command */ 1365static int control_a_bits(struct comedi_cmd cmd) 1366{ 1367 int control_a; 1368 1369 control_a = FFEN; /* enable fifo */ 1370 if (cmd.stop_src == TRIG_EXT) 1371 control_a |= ATEN; 1372 switch (cmd.start_src) { 1373 case TRIG_EXT: 1374 control_a |= TGEN | CGSL; 1375 break; 1376 case TRIG_NOW: 1377 control_a |= CGEN; 1378 break; 1379 default: 1380 break; 1381 } 1382 1383 return control_a; 1384} 1385 1386/* returns appropriate bits for control register c, depending on command */ 1387static int control_c_bits(struct comedi_cmd cmd) 1388{ 1389 int control_c; 1390 int aref; 1391 1392 /* set clock source to internal or external, select analog reference, 1393 * select unipolar / bipolar 1394 */ 1395 aref = CR_AREF(cmd.chanlist[0]); 1396 control_c = UQEN; /* enable upper qram addresses */ 1397 if (aref != AREF_DIFF) 1398 control_c |= SD; 1399 if (aref == AREF_COMMON) 1400 control_c |= CMEN; 1401 /* if a unipolar range was selected */ 1402 if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR) 1403 control_c |= UB; 1404 switch (cmd.scan_begin_src) { 1405 case TRIG_FOLLOW: /* not in burst mode */ 1406 switch (cmd.convert_src) { 1407 case TRIG_TIMER: 1408 /* trig on cascaded counters */ 1409 control_c |= IPCLK; 1410 break; 1411 case TRIG_EXT: 1412 /* trig on falling edge of external trigger */ 1413 control_c |= XPCLK; 1414 break; 1415 default: 1416 break; 1417 } 1418 break; 1419 case TRIG_TIMER: 1420 /* burst mode with internal pacer clock */ 1421 control_c |= BMDE | IPCLK; 1422 break; 1423 case TRIG_EXT: 1424 /* burst mode with external trigger */ 1425 control_c |= BMDE | XPCLK; 1426 break; 1427 default: 1428 break; 1429 } 1430 1431 return control_c; 1432} 1433 1434/* sets up counters */ 1435static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) 1436{ 1437 /* setup cascaded counters for conversion/scan frequency */ 1438 switch (cmd.scan_begin_src) { 1439 case TRIG_FOLLOW: /* not in burst mode */ 1440 if (cmd.convert_src == TRIG_TIMER) { 1441 /* set conversion frequency */ 1442 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1443 &(devpriv->divisor1), 1444 &(devpriv->divisor2), 1445 &(cmd.convert_arg), 1446 cmd. 1447 flags & TRIG_ROUND_MASK); 1448 if (das1800_set_frequency(dev) < 0) 1449 return -1; 1450 } 1451 break; 1452 case TRIG_TIMER: /* in burst mode */ 1453 /* set scan frequency */ 1454 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), 1455 &(devpriv->divisor2), 1456 &(cmd.scan_begin_arg), 1457 cmd.flags & TRIG_ROUND_MASK); 1458 if (das1800_set_frequency(dev) < 0) 1459 return -1; 1460 break; 1461 default: 1462 break; 1463 } 1464 1465 /* setup counter 0 for 'about triggering' */ 1466 if (cmd.stop_src == TRIG_EXT) { 1467 /* load counter 0 in mode 0 */ 1468 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0); 1469 } 1470 1471 return 0; 1472} 1473 1474/* sets up dma */ 1475static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd) 1476{ 1477 unsigned long lock_flags; 1478 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1479 1480 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) 1481 return; 1482 1483 /* determine a reasonable dma transfer size */ 1484 devpriv->dma_transfer_size = suggest_transfer_size(&cmd); 1485 lock_flags = claim_dma_lock(); 1486 disable_dma(devpriv->dma0); 1487 /* clear flip-flop to make sure 2-byte registers for 1488 * count and address get set correctly */ 1489 clear_dma_ff(devpriv->dma0); 1490 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0)); 1491 /* set appropriate size of transfer */ 1492 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size); 1493 devpriv->dma_current = devpriv->dma0; 1494 devpriv->dma_current_buf = devpriv->ai_buf0; 1495 enable_dma(devpriv->dma0); 1496 /* set up dual dma if appropriate */ 1497 if (dual_dma) { 1498 disable_dma(devpriv->dma1); 1499 /* clear flip-flop to make sure 2-byte registers for 1500 * count and address get set correctly */ 1501 clear_dma_ff(devpriv->dma1); 1502 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1)); 1503 /* set appropriate size of transfer */ 1504 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size); 1505 enable_dma(devpriv->dma1); 1506 } 1507 release_dma_lock(lock_flags); 1508 1509 return; 1510} 1511 1512/* programs channel/gain list into card */ 1513static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd) 1514{ 1515 int i, n, chan_range; 1516 unsigned long irq_flags; 1517 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */ 1518 const int range_bitshift = 8; 1519 1520 n = cmd.chanlist_len; 1521 /* spinlock protects indirect addressing */ 1522 spin_lock_irqsave(&dev->spinlock, irq_flags); 1523 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1524 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */ 1525 /* make channel / gain list */ 1526 for (i = 0; i < n; i++) { 1527 chan_range = 1528 CR_CHAN(cmd. 1529 chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) & 1530 range_mask) << range_bitshift); 1531 outw(chan_range, dev->iobase + DAS1800_QRAM); 1532 } 1533 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1534 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1535 1536 return; 1537} 1538 1539/* analog input do_cmd */ 1540static int das1800_ai_do_cmd(struct comedi_device *dev, 1541 struct comedi_subdevice *s) 1542{ 1543 int ret; 1544 int control_a, control_c; 1545 struct comedi_async *async = s->async; 1546 struct comedi_cmd cmd = async->cmd; 1547 1548 if (!dev->irq) { 1549 comedi_error(dev, 1550 "no irq assigned for das-1800, cannot do hardware conversions"); 1551 return -1; 1552 } 1553 1554 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT 1555 * (because dma in handler is unsafe at hard real-time priority) */ 1556 if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) 1557 devpriv->irq_dma_bits &= ~DMA_ENABLED; 1558 else 1559 devpriv->irq_dma_bits |= devpriv->dma_bits; 1560 /* interrupt on end of conversion for TRIG_WAKE_EOS */ 1561 if (cmd.flags & TRIG_WAKE_EOS) { 1562 /* interrupt fifo not empty */ 1563 devpriv->irq_dma_bits &= ~FIMD; 1564 } else { 1565 /* interrupt fifo half full */ 1566 devpriv->irq_dma_bits |= FIMD; 1567 } 1568 /* determine how many conversions we need */ 1569 if (cmd.stop_src == TRIG_COUNT) 1570 devpriv->count = cmd.stop_arg * cmd.chanlist_len; 1571 1572 das1800_cancel(dev, s); 1573 1574 /* determine proper bits for control registers */ 1575 control_a = control_a_bits(cmd); 1576 control_c = control_c_bits(cmd); 1577 1578 /* setup card and start */ 1579 program_chanlist(dev, cmd); 1580 ret = setup_counters(dev, cmd); 1581 if (ret < 0) { 1582 comedi_error(dev, "Error setting up counters"); 1583 return ret; 1584 } 1585 setup_dma(dev, cmd); 1586 outb(control_c, dev->iobase + DAS1800_CONTROL_C); 1587 /* set conversion rate and length for burst mode */ 1588 if (control_c & BMDE) { 1589 /* program conversion period with number of microseconds minus 1 */ 1590 outb(cmd.convert_arg / 1000 - 1, 1591 dev->iobase + DAS1800_BURST_RATE); 1592 outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); 1593 } 1594 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */ 1595 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */ 1596 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1597 1598 return 0; 1599} 1600 1601/* read analog input */ 1602static int das1800_ai_rinsn(struct comedi_device *dev, 1603 struct comedi_subdevice *s, 1604 struct comedi_insn *insn, unsigned int *data) 1605{ 1606 int i, n; 1607 int chan, range, aref, chan_range; 1608 int timeout = 1000; 1609 short dpnt; 1610 int conv_flags = 0; 1611 unsigned long irq_flags; 1612 1613 /* set up analog reference and unipolar / bipolar mode */ 1614 aref = CR_AREF(insn->chanspec); 1615 conv_flags |= UQEN; 1616 if (aref != AREF_DIFF) 1617 conv_flags |= SD; 1618 if (aref == AREF_COMMON) 1619 conv_flags |= CMEN; 1620 /* if a unipolar range was selected */ 1621 if (CR_RANGE(insn->chanspec) & UNIPOLAR) 1622 conv_flags |= UB; 1623 1624 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */ 1625 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1626 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */ 1627 outb(FFEN, dev->iobase + DAS1800_CONTROL_A); 1628 1629 chan = CR_CHAN(insn->chanspec); 1630 /* mask of unipolar/bipolar bit from range */ 1631 range = CR_RANGE(insn->chanspec) & 0x3; 1632 chan_range = chan | (range << 8); 1633 spin_lock_irqsave(&dev->spinlock, irq_flags); 1634 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1635 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */ 1636 outw(chan_range, dev->iobase + DAS1800_QRAM); 1637 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1638 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */ 1639 1640 for (n = 0; n < insn->n; n++) { 1641 /* trigger conversion */ 1642 outb(0, dev->iobase + DAS1800_FIFO); 1643 for (i = 0; i < timeout; i++) { 1644 if (inb(dev->iobase + DAS1800_STATUS) & FNE) 1645 break; 1646 } 1647 if (i == timeout) { 1648 comedi_error(dev, "timeout"); 1649 n = -ETIME; 1650 goto exit; 1651 } 1652 dpnt = inw(dev->iobase + DAS1800_FIFO); 1653 /* shift data to offset binary for bipolar ranges */ 1654 if ((conv_flags & UB) == 0) 1655 dpnt += 1 << (thisboard->resolution - 1); 1656 data[n] = dpnt; 1657 } 1658exit: 1659 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1660 1661 return n; 1662} 1663 1664/* writes to an analog output channel */ 1665static int das1800_ao_winsn(struct comedi_device *dev, 1666 struct comedi_subdevice *s, 1667 struct comedi_insn *insn, unsigned int *data) 1668{ 1669 int chan = CR_CHAN(insn->chanspec); 1670/* int range = CR_RANGE(insn->chanspec); */ 1671 int update_chan = thisboard->ao_n_chan - 1; 1672 short output; 1673 unsigned long irq_flags; 1674 1675 /* card expects two's complement data */ 1676 output = data[0] - (1 << (thisboard->resolution - 1)); 1677 /* if the write is to the 'update' channel, we need to remember its value */ 1678 if (chan == update_chan) 1679 devpriv->ao_update_bits = output; 1680 /* write to channel */ 1681 spin_lock_irqsave(&dev->spinlock, irq_flags); 1682 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */ 1683 outw(output, dev->iobase + DAS1800_DAC); 1684 /* now we need to write to 'update' channel to update all dac channels */ 1685 if (chan != update_chan) { 1686 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */ 1687 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1688 } 1689 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1690 1691 return 1; 1692} 1693 1694/* reads from digital input channels */ 1695static int das1800_di_rbits(struct comedi_device *dev, 1696 struct comedi_subdevice *s, 1697 struct comedi_insn *insn, unsigned int *data) 1698{ 1699 1700 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; 1701 data[0] = 0; 1702 1703 return 2; 1704} 1705 1706/* writes to digital output channels */ 1707static int das1800_do_wbits(struct comedi_device *dev, 1708 struct comedi_subdevice *s, 1709 struct comedi_insn *insn, unsigned int *data) 1710{ 1711 unsigned int wbits; 1712 1713 /* only set bits that have been masked */ 1714 data[0] &= (1 << s->n_chan) - 1; 1715 wbits = devpriv->do_bits; 1716 wbits &= ~data[0]; 1717 wbits |= data[0] & data[1]; 1718 devpriv->do_bits = wbits; 1719 1720 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 1721 1722 data[1] = devpriv->do_bits; 1723 1724 return 2; 1725} 1726 1727/* loads counters with divisor1, divisor2 from private structure */ 1728static int das1800_set_frequency(struct comedi_device *dev) 1729{ 1730 int err = 0; 1731 1732 /* counter 1, mode 2 */ 1733 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1, 1734 2)) 1735 err++; 1736 /* counter 2, mode 2 */ 1737 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2, 1738 2)) 1739 err++; 1740 if (err) 1741 return -1; 1742 1743 return 0; 1744} 1745 1746/* converts requested conversion timing to timing compatible with 1747 * hardware, used only when card is in 'burst mode' 1748 */ 1749static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode) 1750{ 1751 unsigned int micro_sec; 1752 1753 /* in burst mode, the maximum conversion time is 64 microseconds */ 1754 if (convert_arg > 64000) 1755 convert_arg = 64000; 1756 1757 /* the conversion time must be an integral number of microseconds */ 1758 switch (round_mode) { 1759 case TRIG_ROUND_NEAREST: 1760 default: 1761 micro_sec = (convert_arg + 500) / 1000; 1762 break; 1763 case TRIG_ROUND_DOWN: 1764 micro_sec = convert_arg / 1000; 1765 break; 1766 case TRIG_ROUND_UP: 1767 micro_sec = (convert_arg - 1) / 1000 + 1; 1768 break; 1769 } 1770 1771 /* return number of nanoseconds */ 1772 return micro_sec * 1000; 1773} 1774 1775/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ 1776static unsigned int suggest_transfer_size(struct comedi_cmd *cmd) 1777{ 1778 unsigned int size = DMA_BUF_SIZE; 1779 static const int sample_size = 2; /* size in bytes of one sample from board */ 1780 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ 1781 unsigned int max_size; /* maximum size we will allow for a transfer */ 1782 1783 /* make dma buffer fill in 0.3 seconds for timed modes */ 1784 switch (cmd->scan_begin_src) { 1785 case TRIG_FOLLOW: /* not in burst mode */ 1786 if (cmd->convert_src == TRIG_TIMER) 1787 size = (fill_time / cmd->convert_arg) * sample_size; 1788 break; 1789 case TRIG_TIMER: 1790 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * 1791 sample_size; 1792 break; 1793 default: 1794 size = DMA_BUF_SIZE; 1795 break; 1796 } 1797 1798 /* set a minimum and maximum size allowed */ 1799 max_size = DMA_BUF_SIZE; 1800 /* if we are taking limited number of conversions, limit transfer size to that */ 1801 if (cmd->stop_src == TRIG_COUNT && 1802 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) 1803 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; 1804 1805 if (size > max_size) 1806 size = max_size; 1807 if (size < sample_size) 1808 size = sample_size; 1809 1810 return size; 1811} 1812 1813MODULE_AUTHOR("Comedi http://www.comedi.org"); 1814MODULE_DESCRIPTION("Comedi low-level driver"); 1815MODULE_LICENSE("GPL"); 1816