das1800.c revision a142785d7c9dd572a5dd963f7142174901465006
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 printk(" failed to allocate dma channel %i\n", dma0); 584 return -EINVAL; 585 } 586 devpriv->dma0 = dma0; 587 devpriv->dma_current = dma0; 588 if (dma1) { 589 if (request_dma(dma1, driver_das1800.driver_name)) { 590 printk(" failed to allocate dma channel %i\n", 591 dma1); 592 return -EINVAL; 593 } 594 devpriv->dma1 = dma1; 595 } 596 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 597 if (devpriv->ai_buf0 == NULL) 598 return -ENOMEM; 599 devpriv->dma_current_buf = devpriv->ai_buf0; 600 if (dma1) { 601 devpriv->ai_buf1 = 602 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 603 if (devpriv->ai_buf1 == NULL) 604 return -ENOMEM; 605 } 606 flags = claim_dma_lock(); 607 disable_dma(devpriv->dma0); 608 set_dma_mode(devpriv->dma0, DMA_MODE_READ); 609 if (dma1) { 610 disable_dma(devpriv->dma1); 611 set_dma_mode(devpriv->dma1, DMA_MODE_READ); 612 } 613 release_dma_lock(flags); 614 } 615 return 0; 616} 617 618static int das1800_attach(struct comedi_device *dev, 619 struct comedi_devconfig *it) 620{ 621 struct comedi_subdevice *s; 622 unsigned long iobase = it->options[0]; 623 unsigned int irq = it->options[1]; 624 unsigned int dma0 = it->options[2]; 625 unsigned int dma1 = it->options[3]; 626 unsigned long iobase2; 627 int board; 628 int retval; 629 630 /* allocate and initialize dev->private */ 631 if (alloc_private(dev, sizeof(struct das1800_private)) < 0) 632 return -ENOMEM; 633 634 printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name, 635 iobase); 636 if (irq) { 637 printk(", irq %u", irq); 638 if (dma0) { 639 printk(", dma %u", dma0); 640 if (dma1) 641 printk(" and %u", dma1); 642 } 643 } 644 printk("\n"); 645 646 if (iobase == 0) { 647 printk(" io base address required\n"); 648 return -EINVAL; 649 } 650 651 /* check if io addresses are available */ 652 if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) { 653 printk 654 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", 655 iobase, iobase + DAS1800_SIZE - 1); 656 return -EIO; 657 } 658 dev->iobase = iobase; 659 660 board = das1800_probe(dev); 661 if (board < 0) { 662 printk(" unable to determine board type\n"); 663 return -ENODEV; 664 } 665 666 dev->board_ptr = das1800_boards + board; 667 dev->board_name = thisboard->name; 668 669 /* if it is an 'ao' board with fancy analog out then we need extra io ports */ 670 if (thisboard->ao_ability == 2) { 671 iobase2 = iobase + IOBASE2; 672 if (!request_region(iobase2, DAS1800_SIZE, 673 driver_das1800.driver_name)) { 674 printk 675 (" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", 676 iobase2, iobase2 + DAS1800_SIZE - 1); 677 return -EIO; 678 } 679 devpriv->iobase2 = iobase2; 680 } 681 682 /* grab our IRQ */ 683 if (irq) { 684 if (request_irq(irq, das1800_interrupt, 0, 685 driver_das1800.driver_name, dev)) { 686 printk(" unable to allocate irq %u\n", irq); 687 return -EINVAL; 688 } 689 } 690 dev->irq = irq; 691 692 /* set bits that tell card which irq to use */ 693 switch (irq) { 694 case 0: 695 break; 696 case 3: 697 devpriv->irq_dma_bits |= 0x8; 698 break; 699 case 5: 700 devpriv->irq_dma_bits |= 0x10; 701 break; 702 case 7: 703 devpriv->irq_dma_bits |= 0x18; 704 break; 705 case 10: 706 devpriv->irq_dma_bits |= 0x28; 707 break; 708 case 11: 709 devpriv->irq_dma_bits |= 0x30; 710 break; 711 case 15: 712 devpriv->irq_dma_bits |= 0x38; 713 break; 714 default: 715 printk(" irq out of range\n"); 716 return -EINVAL; 717 break; 718 } 719 720 retval = das1800_init_dma(dev, dma0, dma1); 721 if (retval < 0) 722 return retval; 723 724 if (devpriv->ai_buf0 == NULL) { 725 devpriv->ai_buf0 = 726 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); 727 if (devpriv->ai_buf0 == NULL) 728 return -ENOMEM; 729 } 730 731 if (alloc_subdevices(dev, 4) < 0) 732 return -ENOMEM; 733 734 /* analog input subdevice */ 735 s = dev->subdevices + 0; 736 dev->read_subdev = s; 737 s->type = COMEDI_SUBD_AI; 738 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ; 739 if (thisboard->common) 740 s->subdev_flags |= SDF_COMMON; 741 s->n_chan = thisboard->qram_len; 742 s->len_chanlist = thisboard->qram_len; 743 s->maxdata = (1 << thisboard->resolution) - 1; 744 s->range_table = thisboard->range_ai; 745 s->do_cmd = das1800_ai_do_cmd; 746 s->do_cmdtest = das1800_ai_do_cmdtest; 747 s->insn_read = das1800_ai_rinsn; 748 s->poll = das1800_ai_poll; 749 s->cancel = das1800_cancel; 750 751 /* analog out */ 752 s = dev->subdevices + 1; 753 if (thisboard->ao_ability == 1) { 754 s->type = COMEDI_SUBD_AO; 755 s->subdev_flags = SDF_WRITABLE; 756 s->n_chan = thisboard->ao_n_chan; 757 s->maxdata = (1 << thisboard->resolution) - 1; 758 s->range_table = &range_ao_1; 759 s->insn_write = das1800_ao_winsn; 760 } else { 761 s->type = COMEDI_SUBD_UNUSED; 762 } 763 764 /* di */ 765 s = dev->subdevices + 2; 766 s->type = COMEDI_SUBD_DI; 767 s->subdev_flags = SDF_READABLE; 768 s->n_chan = 4; 769 s->maxdata = 1; 770 s->range_table = &range_digital; 771 s->insn_bits = das1800_di_rbits; 772 773 /* do */ 774 s = dev->subdevices + 3; 775 s->type = COMEDI_SUBD_DO; 776 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 777 s->n_chan = thisboard->do_n_chan; 778 s->maxdata = 1; 779 s->range_table = &range_digital; 780 s->insn_bits = das1800_do_wbits; 781 782 das1800_cancel(dev, dev->read_subdev); 783 784 /* initialize digital out channels */ 785 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 786 787 /* initialize analog out channels */ 788 if (thisboard->ao_ability == 1) { 789 /* select 'update' dac channel for baseAddress + 0x0 */ 790 outb(DAC(thisboard->ao_n_chan - 1), 791 dev->iobase + DAS1800_SELECT); 792 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 793 } 794 795 return 0; 796}; 797 798static int das1800_detach(struct comedi_device *dev) 799{ 800 /* only free stuff if it has been allocated by _attach */ 801 if (dev->iobase) 802 release_region(dev->iobase, DAS1800_SIZE); 803 if (dev->irq) 804 free_irq(dev->irq, dev); 805 if (dev->private) { 806 if (devpriv->iobase2) 807 release_region(devpriv->iobase2, DAS1800_SIZE); 808 if (devpriv->dma0) 809 free_dma(devpriv->dma0); 810 if (devpriv->dma1) 811 free_dma(devpriv->dma1); 812 kfree(devpriv->ai_buf0); 813 kfree(devpriv->ai_buf1); 814 } 815 816 printk("comedi%d: %s: remove\n", dev->minor, 817 driver_das1800.driver_name); 818 819 return 0; 820}; 821 822/* probes and checks das-1800 series board type 823 */ 824static int das1800_probe(struct comedi_device *dev) 825{ 826 int id; 827 int board; 828 829 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */ 830 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards; 831 832 switch (id) { 833 case 0x3: 834 if (board == das1801st_da || board == das1802st_da || 835 board == das1701st_da || board == das1702st_da) { 836 printk(" Board model: %s\n", 837 das1800_boards[board].name); 838 return board; 839 } 840 printk 841 (" Board model (probed, not recommended): das-1800st-da series\n"); 842 return das1801st; 843 break; 844 case 0x4: 845 if (board == das1802hr_da || board == das1702hr_da) { 846 printk(" Board model: %s\n", 847 das1800_boards[board].name); 848 return board; 849 } 850 printk 851 (" Board model (probed, not recommended): das-1802hr-da\n"); 852 return das1802hr; 853 break; 854 case 0x5: 855 if (board == das1801ao || board == das1802ao || 856 board == das1701ao || board == das1702ao) { 857 printk(" Board model: %s\n", 858 das1800_boards[board].name); 859 return board; 860 } 861 printk 862 (" Board model (probed, not recommended): das-1800ao series\n"); 863 return das1801ao; 864 break; 865 case 0x6: 866 if (board == das1802hr || board == das1702hr) { 867 printk(" Board model: %s\n", 868 das1800_boards[board].name); 869 return board; 870 } 871 printk(" Board model (probed, not recommended): das-1802hr\n"); 872 return das1802hr; 873 break; 874 case 0x7: 875 if (board == das1801st || board == das1802st || 876 board == das1701st || board == das1702st) { 877 printk(" Board model: %s\n", 878 das1800_boards[board].name); 879 return board; 880 } 881 printk 882 (" Board model (probed, not recommended): das-1800st series\n"); 883 return das1801st; 884 break; 885 case 0x8: 886 if (board == das1801hc || board == das1802hc) { 887 printk(" Board model: %s\n", 888 das1800_boards[board].name); 889 return board; 890 } 891 printk 892 (" Board model (probed, not recommended): das-1800hc series\n"); 893 return das1801hc; 894 break; 895 default: 896 printk 897 (" Board model: probe returned 0x%x (unknown, please report)\n", 898 id); 899 return board; 900 break; 901 } 902 return -1; 903} 904 905static int das1800_ai_poll(struct comedi_device *dev, 906 struct comedi_subdevice *s) 907{ 908 unsigned long flags; 909 910 /* prevent race with interrupt handler */ 911 spin_lock_irqsave(&dev->spinlock, flags); 912 das1800_ai_handler(dev); 913 spin_unlock_irqrestore(&dev->spinlock, flags); 914 915 return s->async->buf_write_count - s->async->buf_read_count; 916} 917 918static irqreturn_t das1800_interrupt(int irq, void *d) 919{ 920 struct comedi_device *dev = d; 921 unsigned int status; 922 923 if (dev->attached == 0) { 924 comedi_error(dev, "premature interrupt"); 925 return IRQ_HANDLED; 926 } 927 928 /* Prevent race with das1800_ai_poll() on multi processor systems. 929 * Also protects indirect addressing in das1800_ai_handler */ 930 spin_lock(&dev->spinlock); 931 status = inb(dev->iobase + DAS1800_STATUS); 932 933 /* if interrupt was not caused by das-1800 */ 934 if (!(status & INT)) { 935 spin_unlock(&dev->spinlock); 936 return IRQ_NONE; 937 } 938 /* clear the interrupt status bit INT */ 939 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); 940 /* handle interrupt */ 941 das1800_ai_handler(dev); 942 943 spin_unlock(&dev->spinlock); 944 return IRQ_HANDLED; 945} 946 947/* the guts of the interrupt handler, that is shared with das1800_ai_poll */ 948static void das1800_ai_handler(struct comedi_device *dev) 949{ 950 struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */ 951 struct comedi_async *async = s->async; 952 struct comedi_cmd *cmd = &async->cmd; 953 unsigned int status = inb(dev->iobase + DAS1800_STATUS); 954 955 async->events = 0; 956 /* select adc for base address + 0 */ 957 outb(ADC, dev->iobase + DAS1800_SELECT); 958 /* dma buffer full */ 959 if (devpriv->irq_dma_bits & DMA_ENABLED) { 960 /* look for data from dma transfer even if dma terminal count hasn't happened yet */ 961 das1800_handle_dma(dev, s, status); 962 } else if (status & FHF) { /* if fifo half full */ 963 das1800_handle_fifo_half_full(dev, s); 964 } else if (status & FNE) { /* if fifo not empty */ 965 das1800_handle_fifo_not_empty(dev, s); 966 } 967 968 async->events |= COMEDI_CB_BLOCK; 969 /* if the card's fifo has overflowed */ 970 if (status & OVF) { 971 /* clear OVF interrupt bit */ 972 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); 973 comedi_error(dev, "DAS1800 FIFO overflow"); 974 das1800_cancel(dev, s); 975 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 976 comedi_event(dev, s); 977 return; 978 } 979 /* stop taking data if appropriate */ 980 /* stop_src TRIG_EXT */ 981 if (status & CT0TC) { 982 /* clear CT0TC interrupt bit */ 983 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS); 984 /* make sure we get all remaining data from board before quitting */ 985 if (devpriv->irq_dma_bits & DMA_ENABLED) 986 das1800_flush_dma(dev, s); 987 else 988 das1800_handle_fifo_not_empty(dev, s); 989 das1800_cancel(dev, s); /* disable hardware conversions */ 990 async->events |= COMEDI_CB_EOA; 991 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */ 992 das1800_cancel(dev, s); /* disable hardware conversions */ 993 async->events |= COMEDI_CB_EOA; 994 } 995 996 comedi_event(dev, s); 997 998 return; 999} 1000 1001static void das1800_handle_dma(struct comedi_device *dev, 1002 struct comedi_subdevice *s, unsigned int status) 1003{ 1004 unsigned long flags; 1005 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1006 1007 flags = claim_dma_lock(); 1008 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1009 devpriv->dma_current_buf); 1010 /* re-enable dma channel */ 1011 set_dma_addr(devpriv->dma_current, 1012 virt_to_bus(devpriv->dma_current_buf)); 1013 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); 1014 enable_dma(devpriv->dma_current); 1015 release_dma_lock(flags); 1016 1017 if (status & DMATC) { 1018 /* clear DMATC interrupt bit */ 1019 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); 1020 /* switch dma channels for next time, if appropriate */ 1021 if (dual_dma) { 1022 /* read data from the other channel next time */ 1023 if (devpriv->dma_current == devpriv->dma0) { 1024 devpriv->dma_current = devpriv->dma1; 1025 devpriv->dma_current_buf = devpriv->ai_buf1; 1026 } else { 1027 devpriv->dma_current = devpriv->dma0; 1028 devpriv->dma_current_buf = devpriv->ai_buf0; 1029 } 1030 } 1031 } 1032 1033 return; 1034} 1035 1036static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, 1037 uint16_t sample) 1038{ 1039 sample += 1 << (thisboard->resolution - 1); 1040 return sample; 1041} 1042 1043static void munge_data(struct comedi_device *dev, uint16_t * array, 1044 unsigned int num_elements) 1045{ 1046 unsigned int i; 1047 int unipolar; 1048 1049 /* see if card is using a unipolar or bipolar range so we can munge data correctly */ 1050 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1051 1052 /* convert to unsigned type if we are in a bipolar mode */ 1053 if (!unipolar) { 1054 for (i = 0; i < num_elements; i++) 1055 array[i] = munge_bipolar_sample(dev, array[i]); 1056 } 1057} 1058 1059/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). 1060 * Assumes dma lock is held */ 1061static void das1800_flush_dma_channel(struct comedi_device *dev, 1062 struct comedi_subdevice *s, 1063 unsigned int channel, uint16_t *buffer) 1064{ 1065 unsigned int num_bytes, num_samples; 1066 struct comedi_cmd *cmd = &s->async->cmd; 1067 1068 disable_dma(channel); 1069 1070 /* clear flip-flop to make sure 2-byte registers 1071 * get set correctly */ 1072 clear_dma_ff(channel); 1073 1074 /* figure out how many points to read */ 1075 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); 1076 num_samples = num_bytes / sizeof(short); 1077 1078 /* if we only need some of the points */ 1079 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) 1080 num_samples = devpriv->count; 1081 1082 munge_data(dev, buffer, num_samples); 1083 cfc_write_array_to_buffer(s, buffer, num_bytes); 1084 if (s->async->cmd.stop_src == TRIG_COUNT) 1085 devpriv->count -= num_samples; 1086 1087 return; 1088} 1089 1090/* flushes remaining data from board when external trigger has stopped acquisition 1091 * and we are using dma transfers */ 1092static void das1800_flush_dma(struct comedi_device *dev, 1093 struct comedi_subdevice *s) 1094{ 1095 unsigned long flags; 1096 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1097 1098 flags = claim_dma_lock(); 1099 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1100 devpriv->dma_current_buf); 1101 1102 if (dual_dma) { 1103 /* switch to other channel and flush it */ 1104 if (devpriv->dma_current == devpriv->dma0) { 1105 devpriv->dma_current = devpriv->dma1; 1106 devpriv->dma_current_buf = devpriv->ai_buf1; 1107 } else { 1108 devpriv->dma_current = devpriv->dma0; 1109 devpriv->dma_current_buf = devpriv->ai_buf0; 1110 } 1111 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1112 devpriv->dma_current_buf); 1113 } 1114 1115 release_dma_lock(flags); 1116 1117 /* get any remaining samples in fifo */ 1118 das1800_handle_fifo_not_empty(dev, s); 1119 1120 return; 1121} 1122 1123static void das1800_handle_fifo_half_full(struct comedi_device *dev, 1124 struct comedi_subdevice *s) 1125{ 1126 int numPoints = 0; /* number of points to read */ 1127 struct comedi_cmd *cmd = &s->async->cmd; 1128 1129 numPoints = FIFO_SIZE / 2; 1130 /* if we only need some of the points */ 1131 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) 1132 numPoints = devpriv->count; 1133 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); 1134 munge_data(dev, devpriv->ai_buf0, numPoints); 1135 cfc_write_array_to_buffer(s, devpriv->ai_buf0, 1136 numPoints * sizeof(devpriv->ai_buf0[0])); 1137 if (cmd->stop_src == TRIG_COUNT) 1138 devpriv->count -= numPoints; 1139 return; 1140} 1141 1142static void das1800_handle_fifo_not_empty(struct comedi_device *dev, 1143 struct comedi_subdevice *s) 1144{ 1145 short dpnt; 1146 int unipolar; 1147 struct comedi_cmd *cmd = &s->async->cmd; 1148 1149 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1150 1151 while (inb(dev->iobase + DAS1800_STATUS) & FNE) { 1152 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) 1153 break; 1154 dpnt = inw(dev->iobase + DAS1800_FIFO); 1155 /* convert to unsigned type if we are in a bipolar mode */ 1156 if (!unipolar) 1157 ; 1158 dpnt = munge_bipolar_sample(dev, dpnt); 1159 cfc_write_to_buffer(s, dpnt); 1160 if (cmd->stop_src == TRIG_COUNT) 1161 devpriv->count--; 1162 } 1163 1164 return; 1165} 1166 1167static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 1168{ 1169 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ 1170 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ 1171 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ 1172 if (devpriv->dma0) 1173 disable_dma(devpriv->dma0); 1174 if (devpriv->dma1) 1175 disable_dma(devpriv->dma1); 1176 return 0; 1177} 1178 1179/* test analog input cmd */ 1180static int das1800_ai_do_cmdtest(struct comedi_device *dev, 1181 struct comedi_subdevice *s, 1182 struct comedi_cmd *cmd) 1183{ 1184 int err = 0; 1185 int tmp; 1186 unsigned int tmp_arg; 1187 int i; 1188 int unipolar; 1189 1190 /* step 1: make sure trigger sources are trivially valid */ 1191 1192 tmp = cmd->start_src; 1193 cmd->start_src &= TRIG_NOW | TRIG_EXT; 1194 if (!cmd->start_src || tmp != cmd->start_src) 1195 err++; 1196 1197 tmp = cmd->scan_begin_src; 1198 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 1199 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 1200 err++; 1201 1202 tmp = cmd->convert_src; 1203 cmd->convert_src &= TRIG_TIMER | TRIG_EXT; 1204 if (!cmd->convert_src || tmp != cmd->convert_src) 1205 err++; 1206 1207 tmp = cmd->scan_end_src; 1208 cmd->scan_end_src &= TRIG_COUNT; 1209 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 1210 err++; 1211 1212 tmp = cmd->stop_src; 1213 cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE; 1214 if (!cmd->stop_src || tmp != cmd->stop_src) 1215 err++; 1216 1217 if (err) 1218 return 1; 1219 1220 /* step 2: make sure trigger sources are unique and mutually compatible */ 1221 1222 /* uniqueness check */ 1223 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 1224 err++; 1225 if (cmd->scan_begin_src != TRIG_FOLLOW && 1226 cmd->scan_begin_src != TRIG_TIMER && 1227 cmd->scan_begin_src != TRIG_EXT) 1228 err++; 1229 if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT) 1230 err++; 1231 if (cmd->stop_src != TRIG_COUNT && 1232 cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT) 1233 err++; 1234 /* compatibility check */ 1235 if (cmd->scan_begin_src != TRIG_FOLLOW && 1236 cmd->convert_src != TRIG_TIMER) 1237 err++; 1238 1239 if (err) 1240 return 2; 1241 1242 /* step 3: make sure arguments are trivially compatible */ 1243 1244 if (cmd->start_arg != 0) { 1245 cmd->start_arg = 0; 1246 err++; 1247 } 1248 if (cmd->convert_src == TRIG_TIMER) { 1249 if (cmd->convert_arg < thisboard->ai_speed) { 1250 cmd->convert_arg = thisboard->ai_speed; 1251 err++; 1252 } 1253 } 1254 if (!cmd->chanlist_len) { 1255 cmd->chanlist_len = 1; 1256 err++; 1257 } 1258 if (cmd->scan_end_arg != cmd->chanlist_len) { 1259 cmd->scan_end_arg = cmd->chanlist_len; 1260 err++; 1261 } 1262 1263 switch (cmd->stop_src) { 1264 case TRIG_COUNT: 1265 if (!cmd->stop_arg) { 1266 cmd->stop_arg = 1; 1267 err++; 1268 } 1269 break; 1270 case TRIG_NONE: 1271 if (cmd->stop_arg != 0) { 1272 cmd->stop_arg = 0; 1273 err++; 1274 } 1275 break; 1276 default: 1277 break; 1278 } 1279 1280 if (err) 1281 return 3; 1282 1283 /* step 4: fix up any arguments */ 1284 1285 if (cmd->convert_src == TRIG_TIMER) { 1286 /* if we are not in burst mode */ 1287 if (cmd->scan_begin_src == TRIG_FOLLOW) { 1288 tmp_arg = cmd->convert_arg; 1289 /* calculate counter values that give desired timing */ 1290 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1291 &(devpriv->divisor1), 1292 &(devpriv->divisor2), 1293 &(cmd->convert_arg), 1294 cmd-> 1295 flags & TRIG_ROUND_MASK); 1296 if (tmp_arg != cmd->convert_arg) 1297 err++; 1298 } 1299 /* if we are in burst mode */ 1300 else { 1301 /* check that convert_arg is compatible */ 1302 tmp_arg = cmd->convert_arg; 1303 cmd->convert_arg = 1304 burst_convert_arg(cmd->convert_arg, 1305 cmd->flags & TRIG_ROUND_MASK); 1306 if (tmp_arg != cmd->convert_arg) 1307 err++; 1308 1309 if (cmd->scan_begin_src == TRIG_TIMER) { 1310 /* if scans are timed faster than conversion rate allows */ 1311 if (cmd->convert_arg * cmd->chanlist_len > 1312 cmd->scan_begin_arg) { 1313 cmd->scan_begin_arg = 1314 cmd->convert_arg * 1315 cmd->chanlist_len; 1316 err++; 1317 } 1318 tmp_arg = cmd->scan_begin_arg; 1319 /* calculate counter values that give desired timing */ 1320 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1321 &(devpriv-> 1322 divisor1), 1323 &(devpriv-> 1324 divisor2), 1325 &(cmd-> 1326 scan_begin_arg), 1327 cmd-> 1328 flags & 1329 TRIG_ROUND_MASK); 1330 if (tmp_arg != cmd->scan_begin_arg) 1331 err++; 1332 } 1333 } 1334 } 1335 1336 if (err) 1337 return 4; 1338 1339 /* make sure user is not trying to mix unipolar and bipolar ranges */ 1340 if (cmd->chanlist) { 1341 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR; 1342 for (i = 1; i < cmd->chanlist_len; i++) { 1343 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) { 1344 comedi_error(dev, 1345 "unipolar and bipolar ranges cannot be mixed in the chanlist"); 1346 err++; 1347 break; 1348 } 1349 } 1350 } 1351 1352 if (err) 1353 return 5; 1354 1355 return 0; 1356} 1357 1358/* analog input cmd interface */ 1359 1360/* first, some utility functions used in the main ai_do_cmd() */ 1361 1362/* returns appropriate bits for control register a, depending on command */ 1363static int control_a_bits(struct comedi_cmd cmd) 1364{ 1365 int control_a; 1366 1367 control_a = FFEN; /* enable fifo */ 1368 if (cmd.stop_src == TRIG_EXT) 1369 control_a |= ATEN; 1370 switch (cmd.start_src) { 1371 case TRIG_EXT: 1372 control_a |= TGEN | CGSL; 1373 break; 1374 case TRIG_NOW: 1375 control_a |= CGEN; 1376 break; 1377 default: 1378 break; 1379 } 1380 1381 return control_a; 1382} 1383 1384/* returns appropriate bits for control register c, depending on command */ 1385static int control_c_bits(struct comedi_cmd cmd) 1386{ 1387 int control_c; 1388 int aref; 1389 1390 /* set clock source to internal or external, select analog reference, 1391 * select unipolar / bipolar 1392 */ 1393 aref = CR_AREF(cmd.chanlist[0]); 1394 control_c = UQEN; /* enable upper qram addresses */ 1395 if (aref != AREF_DIFF) 1396 control_c |= SD; 1397 if (aref == AREF_COMMON) 1398 control_c |= CMEN; 1399 /* if a unipolar range was selected */ 1400 if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR) 1401 control_c |= UB; 1402 switch (cmd.scan_begin_src) { 1403 case TRIG_FOLLOW: /* not in burst mode */ 1404 switch (cmd.convert_src) { 1405 case TRIG_TIMER: 1406 /* trig on cascaded counters */ 1407 control_c |= IPCLK; 1408 break; 1409 case TRIG_EXT: 1410 /* trig on falling edge of external trigger */ 1411 control_c |= XPCLK; 1412 break; 1413 default: 1414 break; 1415 } 1416 break; 1417 case TRIG_TIMER: 1418 /* burst mode with internal pacer clock */ 1419 control_c |= BMDE | IPCLK; 1420 break; 1421 case TRIG_EXT: 1422 /* burst mode with external trigger */ 1423 control_c |= BMDE | XPCLK; 1424 break; 1425 default: 1426 break; 1427 } 1428 1429 return control_c; 1430} 1431 1432/* sets up counters */ 1433static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) 1434{ 1435 /* setup cascaded counters for conversion/scan frequency */ 1436 switch (cmd.scan_begin_src) { 1437 case TRIG_FOLLOW: /* not in burst mode */ 1438 if (cmd.convert_src == TRIG_TIMER) { 1439 /* set conversion frequency */ 1440 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1441 &(devpriv->divisor1), 1442 &(devpriv->divisor2), 1443 &(cmd.convert_arg), 1444 cmd. 1445 flags & TRIG_ROUND_MASK); 1446 if (das1800_set_frequency(dev) < 0) 1447 return -1; 1448 } 1449 break; 1450 case TRIG_TIMER: /* in burst mode */ 1451 /* set scan frequency */ 1452 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), 1453 &(devpriv->divisor2), 1454 &(cmd.scan_begin_arg), 1455 cmd.flags & TRIG_ROUND_MASK); 1456 if (das1800_set_frequency(dev) < 0) 1457 return -1; 1458 break; 1459 default: 1460 break; 1461 } 1462 1463 /* setup counter 0 for 'about triggering' */ 1464 if (cmd.stop_src == TRIG_EXT) { 1465 /* load counter 0 in mode 0 */ 1466 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0); 1467 } 1468 1469 return 0; 1470} 1471 1472/* sets up dma */ 1473static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd) 1474{ 1475 unsigned long lock_flags; 1476 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1477 1478 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) 1479 return; 1480 1481 /* determine a reasonable dma transfer size */ 1482 devpriv->dma_transfer_size = suggest_transfer_size(&cmd); 1483 lock_flags = claim_dma_lock(); 1484 disable_dma(devpriv->dma0); 1485 /* clear flip-flop to make sure 2-byte registers for 1486 * count and address get set correctly */ 1487 clear_dma_ff(devpriv->dma0); 1488 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0)); 1489 /* set appropriate size of transfer */ 1490 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size); 1491 devpriv->dma_current = devpriv->dma0; 1492 devpriv->dma_current_buf = devpriv->ai_buf0; 1493 enable_dma(devpriv->dma0); 1494 /* set up dual dma if appropriate */ 1495 if (dual_dma) { 1496 disable_dma(devpriv->dma1); 1497 /* clear flip-flop to make sure 2-byte registers for 1498 * count and address get set correctly */ 1499 clear_dma_ff(devpriv->dma1); 1500 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1)); 1501 /* set appropriate size of transfer */ 1502 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size); 1503 enable_dma(devpriv->dma1); 1504 } 1505 release_dma_lock(lock_flags); 1506 1507 return; 1508} 1509 1510/* programs channel/gain list into card */ 1511static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd) 1512{ 1513 int i, n, chan_range; 1514 unsigned long irq_flags; 1515 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */ 1516 const int range_bitshift = 8; 1517 1518 n = cmd.chanlist_len; 1519 /* spinlock protects indirect addressing */ 1520 spin_lock_irqsave(&dev->spinlock, irq_flags); 1521 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1522 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */ 1523 /* make channel / gain list */ 1524 for (i = 0; i < n; i++) { 1525 chan_range = 1526 CR_CHAN(cmd. 1527 chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) & 1528 range_mask) << range_bitshift); 1529 outw(chan_range, dev->iobase + DAS1800_QRAM); 1530 } 1531 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1532 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1533 1534 return; 1535} 1536 1537/* analog input do_cmd */ 1538static int das1800_ai_do_cmd(struct comedi_device *dev, 1539 struct comedi_subdevice *s) 1540{ 1541 int ret; 1542 int control_a, control_c; 1543 struct comedi_async *async = s->async; 1544 struct comedi_cmd cmd = async->cmd; 1545 1546 if (!dev->irq) { 1547 comedi_error(dev, 1548 "no irq assigned for das-1800, cannot do hardware conversions"); 1549 return -1; 1550 } 1551 1552 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT 1553 * (because dma in handler is unsafe at hard real-time priority) */ 1554 if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) 1555 devpriv->irq_dma_bits &= ~DMA_ENABLED; 1556 else 1557 devpriv->irq_dma_bits |= devpriv->dma_bits; 1558 /* interrupt on end of conversion for TRIG_WAKE_EOS */ 1559 if (cmd.flags & TRIG_WAKE_EOS) { 1560 /* interrupt fifo not empty */ 1561 devpriv->irq_dma_bits &= ~FIMD; 1562 } else { 1563 /* interrupt fifo half full */ 1564 devpriv->irq_dma_bits |= FIMD; 1565 } 1566 /* determine how many conversions we need */ 1567 if (cmd.stop_src == TRIG_COUNT) 1568 devpriv->count = cmd.stop_arg * cmd.chanlist_len; 1569 1570 das1800_cancel(dev, s); 1571 1572 /* determine proper bits for control registers */ 1573 control_a = control_a_bits(cmd); 1574 control_c = control_c_bits(cmd); 1575 1576 /* setup card and start */ 1577 program_chanlist(dev, cmd); 1578 ret = setup_counters(dev, cmd); 1579 if (ret < 0) { 1580 comedi_error(dev, "Error setting up counters"); 1581 return ret; 1582 } 1583 setup_dma(dev, cmd); 1584 outb(control_c, dev->iobase + DAS1800_CONTROL_C); 1585 /* set conversion rate and length for burst mode */ 1586 if (control_c & BMDE) { 1587 /* program conversion period with number of microseconds minus 1 */ 1588 outb(cmd.convert_arg / 1000 - 1, 1589 dev->iobase + DAS1800_BURST_RATE); 1590 outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); 1591 } 1592 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */ 1593 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */ 1594 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1595 1596 return 0; 1597} 1598 1599/* read analog input */ 1600static int das1800_ai_rinsn(struct comedi_device *dev, 1601 struct comedi_subdevice *s, 1602 struct comedi_insn *insn, unsigned int *data) 1603{ 1604 int i, n; 1605 int chan, range, aref, chan_range; 1606 int timeout = 1000; 1607 short dpnt; 1608 int conv_flags = 0; 1609 unsigned long irq_flags; 1610 1611 /* set up analog reference and unipolar / bipolar mode */ 1612 aref = CR_AREF(insn->chanspec); 1613 conv_flags |= UQEN; 1614 if (aref != AREF_DIFF) 1615 conv_flags |= SD; 1616 if (aref == AREF_COMMON) 1617 conv_flags |= CMEN; 1618 /* if a unipolar range was selected */ 1619 if (CR_RANGE(insn->chanspec) & UNIPOLAR) 1620 conv_flags |= UB; 1621 1622 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */ 1623 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1624 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */ 1625 outb(FFEN, dev->iobase + DAS1800_CONTROL_A); 1626 1627 chan = CR_CHAN(insn->chanspec); 1628 /* mask of unipolar/bipolar bit from range */ 1629 range = CR_RANGE(insn->chanspec) & 0x3; 1630 chan_range = chan | (range << 8); 1631 spin_lock_irqsave(&dev->spinlock, irq_flags); 1632 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1633 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */ 1634 outw(chan_range, dev->iobase + DAS1800_QRAM); 1635 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1636 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */ 1637 1638 for (n = 0; n < insn->n; n++) { 1639 /* trigger conversion */ 1640 outb(0, dev->iobase + DAS1800_FIFO); 1641 for (i = 0; i < timeout; i++) { 1642 if (inb(dev->iobase + DAS1800_STATUS) & FNE) 1643 break; 1644 } 1645 if (i == timeout) { 1646 comedi_error(dev, "timeout"); 1647 n = -ETIME; 1648 goto exit; 1649 } 1650 dpnt = inw(dev->iobase + DAS1800_FIFO); 1651 /* shift data to offset binary for bipolar ranges */ 1652 if ((conv_flags & UB) == 0) 1653 dpnt += 1 << (thisboard->resolution - 1); 1654 data[n] = dpnt; 1655 } 1656exit: 1657 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1658 1659 return n; 1660} 1661 1662/* writes to an analog output channel */ 1663static int das1800_ao_winsn(struct comedi_device *dev, 1664 struct comedi_subdevice *s, 1665 struct comedi_insn *insn, unsigned int *data) 1666{ 1667 int chan = CR_CHAN(insn->chanspec); 1668/* int range = CR_RANGE(insn->chanspec); */ 1669 int update_chan = thisboard->ao_n_chan - 1; 1670 short output; 1671 unsigned long irq_flags; 1672 1673 /* card expects two's complement data */ 1674 output = data[0] - (1 << (thisboard->resolution - 1)); 1675 /* if the write is to the 'update' channel, we need to remember its value */ 1676 if (chan == update_chan) 1677 devpriv->ao_update_bits = output; 1678 /* write to channel */ 1679 spin_lock_irqsave(&dev->spinlock, irq_flags); 1680 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */ 1681 outw(output, dev->iobase + DAS1800_DAC); 1682 /* now we need to write to 'update' channel to update all dac channels */ 1683 if (chan != update_chan) { 1684 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */ 1685 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1686 } 1687 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1688 1689 return 1; 1690} 1691 1692/* reads from digital input channels */ 1693static int das1800_di_rbits(struct comedi_device *dev, 1694 struct comedi_subdevice *s, 1695 struct comedi_insn *insn, unsigned int *data) 1696{ 1697 1698 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; 1699 data[0] = 0; 1700 1701 return 2; 1702} 1703 1704/* writes to digital output channels */ 1705static int das1800_do_wbits(struct comedi_device *dev, 1706 struct comedi_subdevice *s, 1707 struct comedi_insn *insn, unsigned int *data) 1708{ 1709 unsigned int wbits; 1710 1711 /* only set bits that have been masked */ 1712 data[0] &= (1 << s->n_chan) - 1; 1713 wbits = devpriv->do_bits; 1714 wbits &= ~data[0]; 1715 wbits |= data[0] & data[1]; 1716 devpriv->do_bits = wbits; 1717 1718 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 1719 1720 data[1] = devpriv->do_bits; 1721 1722 return 2; 1723} 1724 1725/* loads counters with divisor1, divisor2 from private structure */ 1726static int das1800_set_frequency(struct comedi_device *dev) 1727{ 1728 int err = 0; 1729 1730 /* counter 1, mode 2 */ 1731 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1, 1732 2)) 1733 err++; 1734 /* counter 2, mode 2 */ 1735 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2, 1736 2)) 1737 err++; 1738 if (err) 1739 return -1; 1740 1741 return 0; 1742} 1743 1744/* converts requested conversion timing to timing compatible with 1745 * hardware, used only when card is in 'burst mode' 1746 */ 1747static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode) 1748{ 1749 unsigned int micro_sec; 1750 1751 /* in burst mode, the maximum conversion time is 64 microseconds */ 1752 if (convert_arg > 64000) 1753 convert_arg = 64000; 1754 1755 /* the conversion time must be an integral number of microseconds */ 1756 switch (round_mode) { 1757 case TRIG_ROUND_NEAREST: 1758 default: 1759 micro_sec = (convert_arg + 500) / 1000; 1760 break; 1761 case TRIG_ROUND_DOWN: 1762 micro_sec = convert_arg / 1000; 1763 break; 1764 case TRIG_ROUND_UP: 1765 micro_sec = (convert_arg - 1) / 1000 + 1; 1766 break; 1767 } 1768 1769 /* return number of nanoseconds */ 1770 return micro_sec * 1000; 1771} 1772 1773/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ 1774static unsigned int suggest_transfer_size(struct comedi_cmd *cmd) 1775{ 1776 unsigned int size = DMA_BUF_SIZE; 1777 static const int sample_size = 2; /* size in bytes of one sample from board */ 1778 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ 1779 unsigned int max_size; /* maximum size we will allow for a transfer */ 1780 1781 /* make dma buffer fill in 0.3 seconds for timed modes */ 1782 switch (cmd->scan_begin_src) { 1783 case TRIG_FOLLOW: /* not in burst mode */ 1784 if (cmd->convert_src == TRIG_TIMER) 1785 size = (fill_time / cmd->convert_arg) * sample_size; 1786 break; 1787 case TRIG_TIMER: 1788 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * 1789 sample_size; 1790 break; 1791 default: 1792 size = DMA_BUF_SIZE; 1793 break; 1794 } 1795 1796 /* set a minimum and maximum size allowed */ 1797 max_size = DMA_BUF_SIZE; 1798 /* if we are taking limited number of conversions, limit transfer size to that */ 1799 if (cmd->stop_src == TRIG_COUNT && 1800 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) 1801 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; 1802 1803 if (size > max_size) 1804 size = max_size; 1805 if (size < sample_size) 1806 size = sample_size; 1807 1808 return size; 1809} 1810 1811MODULE_AUTHOR("Comedi http://www.comedi.org"); 1812MODULE_DESCRIPTION("Comedi low-level driver"); 1813MODULE_LICENSE("GPL"); 1814