das1800.c revision 845d131e2b363717d8ac8db2c6b4417de8cf10b5
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 1060/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). 1061 * Assumes dma lock is held */ 1062static void das1800_flush_dma_channel(struct comedi_device *dev, 1063 struct comedi_subdevice *s, 1064 unsigned int channel, uint16_t * buffer) 1065{ 1066 unsigned int num_bytes, num_samples; 1067 struct comedi_cmd *cmd = &s->async->cmd; 1068 1069 disable_dma(channel); 1070 1071 /* clear flip-flop to make sure 2-byte registers 1072 * get set correctly */ 1073 clear_dma_ff(channel); 1074 1075 /* figure out how many points to read */ 1076 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); 1077 num_samples = num_bytes / sizeof(short); 1078 1079 /* if we only need some of the points */ 1080 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) 1081 num_samples = devpriv->count; 1082 1083 munge_data(dev, buffer, num_samples); 1084 cfc_write_array_to_buffer(s, buffer, num_bytes); 1085 if (s->async->cmd.stop_src == TRIG_COUNT) 1086 devpriv->count -= num_samples; 1087 1088 return; 1089} 1090 1091/* flushes remaining data from board when external trigger has stopped acquisition 1092 * and we are using dma transfers */ 1093static void das1800_flush_dma(struct comedi_device *dev, 1094 struct comedi_subdevice *s) 1095{ 1096 unsigned long flags; 1097 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1098 1099 flags = claim_dma_lock(); 1100 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1101 devpriv->dma_current_buf); 1102 1103 if (dual_dma) { 1104 /* switch to other channel and flush it */ 1105 if (devpriv->dma_current == devpriv->dma0) { 1106 devpriv->dma_current = devpriv->dma1; 1107 devpriv->dma_current_buf = devpriv->ai_buf1; 1108 } else { 1109 devpriv->dma_current = devpriv->dma0; 1110 devpriv->dma_current_buf = devpriv->ai_buf0; 1111 } 1112 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 1113 devpriv->dma_current_buf); 1114 } 1115 1116 release_dma_lock(flags); 1117 1118 /* get any remaining samples in fifo */ 1119 das1800_handle_fifo_not_empty(dev, s); 1120 1121 return; 1122} 1123 1124static void das1800_handle_fifo_half_full(struct comedi_device *dev, 1125 struct comedi_subdevice *s) 1126{ 1127 int numPoints = 0; /* number of points to read */ 1128 struct comedi_cmd *cmd = &s->async->cmd; 1129 1130 numPoints = FIFO_SIZE / 2; 1131 /* if we only need some of the points */ 1132 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) 1133 numPoints = devpriv->count; 1134 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); 1135 munge_data(dev, devpriv->ai_buf0, numPoints); 1136 cfc_write_array_to_buffer(s, devpriv->ai_buf0, 1137 numPoints * sizeof(devpriv->ai_buf0[0])); 1138 if (cmd->stop_src == TRIG_COUNT) 1139 devpriv->count -= numPoints; 1140 return; 1141} 1142 1143static void das1800_handle_fifo_not_empty(struct comedi_device *dev, 1144 struct comedi_subdevice *s) 1145{ 1146 short dpnt; 1147 int unipolar; 1148 struct comedi_cmd *cmd = &s->async->cmd; 1149 1150 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 1151 1152 while (inb(dev->iobase + DAS1800_STATUS) & FNE) { 1153 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) 1154 break; 1155 dpnt = inw(dev->iobase + DAS1800_FIFO); 1156 /* convert to unsigned type if we are in a bipolar mode */ 1157 if (!unipolar) ; 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 } 1371 switch (cmd.start_src) { 1372 case TRIG_EXT: 1373 control_a |= TGEN | CGSL; 1374 break; 1375 case TRIG_NOW: 1376 control_a |= CGEN; 1377 break; 1378 default: 1379 break; 1380 } 1381 1382 return control_a; 1383} 1384 1385/* returns appropriate bits for control register c, depending on command */ 1386static int control_c_bits(struct comedi_cmd cmd) 1387{ 1388 int control_c; 1389 int aref; 1390 1391 /* set clock source to internal or external, select analog reference, 1392 * select unipolar / bipolar 1393 */ 1394 aref = CR_AREF(cmd.chanlist[0]); 1395 control_c = UQEN; /* enable upper qram addresses */ 1396 if (aref != AREF_DIFF) 1397 control_c |= SD; 1398 if (aref == AREF_COMMON) 1399 control_c |= CMEN; 1400 /* if a unipolar range was selected */ 1401 if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR) 1402 control_c |= UB; 1403 switch (cmd.scan_begin_src) { 1404 case TRIG_FOLLOW: /* not in burst mode */ 1405 switch (cmd.convert_src) { 1406 case TRIG_TIMER: 1407 /* trig on cascaded counters */ 1408 control_c |= IPCLK; 1409 break; 1410 case TRIG_EXT: 1411 /* trig on falling edge of external trigger */ 1412 control_c |= XPCLK; 1413 break; 1414 default: 1415 break; 1416 } 1417 break; 1418 case TRIG_TIMER: 1419 /* burst mode with internal pacer clock */ 1420 control_c |= BMDE | IPCLK; 1421 break; 1422 case TRIG_EXT: 1423 /* burst mode with external trigger */ 1424 control_c |= BMDE | XPCLK; 1425 break; 1426 default: 1427 break; 1428 } 1429 1430 return control_c; 1431} 1432 1433/* sets up counters */ 1434static int setup_counters(struct comedi_device *dev, struct comedi_cmd cmd) 1435{ 1436 /* setup cascaded counters for conversion/scan frequency */ 1437 switch (cmd.scan_begin_src) { 1438 case TRIG_FOLLOW: /* not in burst mode */ 1439 if (cmd.convert_src == TRIG_TIMER) { 1440 /* set conversion frequency */ 1441 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1442 &(devpriv->divisor1), 1443 &(devpriv->divisor2), 1444 &(cmd.convert_arg), 1445 cmd. 1446 flags & TRIG_ROUND_MASK); 1447 if (das1800_set_frequency(dev) < 0) { 1448 return -1; 1449 } 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 } 1461 break; 1462 default: 1463 break; 1464 } 1465 1466 /* setup counter 0 for 'about triggering' */ 1467 if (cmd.stop_src == TRIG_EXT) { 1468 /* load counter 0 in mode 0 */ 1469 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0); 1470 } 1471 1472 return 0; 1473} 1474 1475/* sets up dma */ 1476static void setup_dma(struct comedi_device *dev, struct comedi_cmd cmd) 1477{ 1478 unsigned long lock_flags; 1479 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1480 1481 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) 1482 return; 1483 1484 /* determine a reasonable dma transfer size */ 1485 devpriv->dma_transfer_size = suggest_transfer_size(&cmd); 1486 lock_flags = claim_dma_lock(); 1487 disable_dma(devpriv->dma0); 1488 /* clear flip-flop to make sure 2-byte registers for 1489 * count and address get set correctly */ 1490 clear_dma_ff(devpriv->dma0); 1491 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0)); 1492 /* set appropriate size of transfer */ 1493 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size); 1494 devpriv->dma_current = devpriv->dma0; 1495 devpriv->dma_current_buf = devpriv->ai_buf0; 1496 enable_dma(devpriv->dma0); 1497 /* set up dual dma if appropriate */ 1498 if (dual_dma) { 1499 disable_dma(devpriv->dma1); 1500 /* clear flip-flop to make sure 2-byte registers for 1501 * count and address get set correctly */ 1502 clear_dma_ff(devpriv->dma1); 1503 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1)); 1504 /* set appropriate size of transfer */ 1505 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size); 1506 enable_dma(devpriv->dma1); 1507 } 1508 release_dma_lock(lock_flags); 1509 1510 return; 1511} 1512 1513/* programs channel/gain list into card */ 1514static void program_chanlist(struct comedi_device *dev, struct comedi_cmd cmd) 1515{ 1516 int i, n, chan_range; 1517 unsigned long irq_flags; 1518 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */ 1519 const int range_bitshift = 8; 1520 1521 n = cmd.chanlist_len; 1522 /* spinlock protects indirect addressing */ 1523 spin_lock_irqsave(&dev->spinlock, irq_flags); 1524 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1525 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */ 1526 /* make channel / gain list */ 1527 for (i = 0; i < n; i++) { 1528 chan_range = 1529 CR_CHAN(cmd. 1530 chanlist[i]) | ((CR_RANGE(cmd.chanlist[i]) & 1531 range_mask) << range_bitshift); 1532 outw(chan_range, dev->iobase + DAS1800_QRAM); 1533 } 1534 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1535 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1536 1537 return; 1538} 1539 1540/* analog input do_cmd */ 1541static int das1800_ai_do_cmd(struct comedi_device *dev, 1542 struct comedi_subdevice *s) 1543{ 1544 int ret; 1545 int control_a, control_c; 1546 struct comedi_async *async = s->async; 1547 struct comedi_cmd cmd = async->cmd; 1548 1549 if (!dev->irq) { 1550 comedi_error(dev, 1551 "no irq assigned for das-1800, cannot do hardware conversions"); 1552 return -1; 1553 } 1554 1555 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT 1556 * (because dma in handler is unsafe at hard real-time priority) */ 1557 if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) { 1558 devpriv->irq_dma_bits &= ~DMA_ENABLED; 1559 } else { 1560 devpriv->irq_dma_bits |= devpriv->dma_bits; 1561 } 1562 /* interrupt on end of conversion for TRIG_WAKE_EOS */ 1563 if (cmd.flags & TRIG_WAKE_EOS) { 1564 /* interrupt fifo not empty */ 1565 devpriv->irq_dma_bits &= ~FIMD; 1566 } else { 1567 /* interrupt fifo half full */ 1568 devpriv->irq_dma_bits |= FIMD; 1569 } 1570 /* determine how many conversions we need */ 1571 if (cmd.stop_src == TRIG_COUNT) { 1572 devpriv->count = cmd.stop_arg * cmd.chanlist_len; 1573 } 1574 1575 das1800_cancel(dev, s); 1576 1577 /* determine proper bits for control registers */ 1578 control_a = control_a_bits(cmd); 1579 control_c = control_c_bits(cmd); 1580 1581 /* setup card and start */ 1582 program_chanlist(dev, cmd); 1583 ret = setup_counters(dev, cmd); 1584 if (ret < 0) { 1585 comedi_error(dev, "Error setting up counters"); 1586 return ret; 1587 } 1588 setup_dma(dev, cmd); 1589 outb(control_c, dev->iobase + DAS1800_CONTROL_C); 1590 /* set conversion rate and length for burst mode */ 1591 if (control_c & BMDE) { 1592 /* program conversion period with number of microseconds minus 1 */ 1593 outb(cmd.convert_arg / 1000 - 1, 1594 dev->iobase + DAS1800_BURST_RATE); 1595 outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); 1596 } 1597 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */ 1598 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */ 1599 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1600 1601 return 0; 1602} 1603 1604/* read analog input */ 1605static int das1800_ai_rinsn(struct comedi_device *dev, 1606 struct comedi_subdevice *s, 1607 struct comedi_insn *insn, unsigned int *data) 1608{ 1609 int i, n; 1610 int chan, range, aref, chan_range; 1611 int timeout = 1000; 1612 short dpnt; 1613 int conv_flags = 0; 1614 unsigned long irq_flags; 1615 1616 /* set up analog reference and unipolar / bipolar mode */ 1617 aref = CR_AREF(insn->chanspec); 1618 conv_flags |= UQEN; 1619 if (aref != AREF_DIFF) 1620 conv_flags |= SD; 1621 if (aref == AREF_COMMON) 1622 conv_flags |= CMEN; 1623 /* if a unipolar range was selected */ 1624 if (CR_RANGE(insn->chanspec) & UNIPOLAR) 1625 conv_flags |= UB; 1626 1627 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */ 1628 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1629 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */ 1630 outb(FFEN, dev->iobase + DAS1800_CONTROL_A); 1631 1632 chan = CR_CHAN(insn->chanspec); 1633 /* mask of unipolar/bipolar bit from range */ 1634 range = CR_RANGE(insn->chanspec) & 0x3; 1635 chan_range = chan | (range << 8); 1636 spin_lock_irqsave(&dev->spinlock, irq_flags); 1637 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1638 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */ 1639 outw(chan_range, dev->iobase + DAS1800_QRAM); 1640 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1641 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */ 1642 1643 for (n = 0; n < insn->n; n++) { 1644 /* trigger conversion */ 1645 outb(0, dev->iobase + DAS1800_FIFO); 1646 for (i = 0; i < timeout; i++) { 1647 if (inb(dev->iobase + DAS1800_STATUS) & FNE) 1648 break; 1649 } 1650 if (i == timeout) { 1651 comedi_error(dev, "timeout"); 1652 n = -ETIME; 1653 goto exit; 1654 } 1655 dpnt = inw(dev->iobase + DAS1800_FIFO); 1656 /* shift data to offset binary for bipolar ranges */ 1657 if ((conv_flags & UB) == 0) 1658 dpnt += 1 << (thisboard->resolution - 1); 1659 data[n] = dpnt; 1660 } 1661exit: 1662 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1663 1664 return n; 1665} 1666 1667/* writes to an analog output channel */ 1668static int das1800_ao_winsn(struct comedi_device *dev, 1669 struct comedi_subdevice *s, 1670 struct comedi_insn *insn, unsigned int *data) 1671{ 1672 int chan = CR_CHAN(insn->chanspec); 1673/* int range = CR_RANGE(insn->chanspec); */ 1674 int update_chan = thisboard->ao_n_chan - 1; 1675 short output; 1676 unsigned long irq_flags; 1677 1678 /* card expects two's complement data */ 1679 output = data[0] - (1 << (thisboard->resolution - 1)); 1680 /* if the write is to the 'update' channel, we need to remember its value */ 1681 if (chan == update_chan) 1682 devpriv->ao_update_bits = output; 1683 /* write to channel */ 1684 spin_lock_irqsave(&dev->spinlock, irq_flags); 1685 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */ 1686 outw(output, dev->iobase + DAS1800_DAC); 1687 /* now we need to write to 'update' channel to update all dac channels */ 1688 if (chan != update_chan) { 1689 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */ 1690 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1691 } 1692 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1693 1694 return 1; 1695} 1696 1697/* reads from digital input channels */ 1698static int das1800_di_rbits(struct comedi_device *dev, 1699 struct comedi_subdevice *s, 1700 struct comedi_insn *insn, unsigned int *data) 1701{ 1702 1703 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; 1704 data[0] = 0; 1705 1706 return 2; 1707} 1708 1709/* writes to digital output channels */ 1710static int das1800_do_wbits(struct comedi_device *dev, 1711 struct comedi_subdevice *s, 1712 struct comedi_insn *insn, unsigned int *data) 1713{ 1714 unsigned int wbits; 1715 1716 /* only set bits that have been masked */ 1717 data[0] &= (1 << s->n_chan) - 1; 1718 wbits = devpriv->do_bits; 1719 wbits &= ~data[0]; 1720 wbits |= data[0] & data[1]; 1721 devpriv->do_bits = wbits; 1722 1723 outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL); 1724 1725 data[1] = devpriv->do_bits; 1726 1727 return 2; 1728} 1729 1730/* loads counters with divisor1, divisor2 from private structure */ 1731static int das1800_set_frequency(struct comedi_device *dev) 1732{ 1733 int err = 0; 1734 1735 /* counter 1, mode 2 */ 1736 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1, 1737 2)) 1738 err++; 1739 /* counter 2, mode 2 */ 1740 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2, 1741 2)) 1742 err++; 1743 if (err) 1744 return -1; 1745 1746 return 0; 1747} 1748 1749/* converts requested conversion timing to timing compatible with 1750 * hardware, used only when card is in 'burst mode' 1751 */ 1752static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode) 1753{ 1754 unsigned int micro_sec; 1755 1756 /* in burst mode, the maximum conversion time is 64 microseconds */ 1757 if (convert_arg > 64000) 1758 convert_arg = 64000; 1759 1760 /* the conversion time must be an integral number of microseconds */ 1761 switch (round_mode) { 1762 case TRIG_ROUND_NEAREST: 1763 default: 1764 micro_sec = (convert_arg + 500) / 1000; 1765 break; 1766 case TRIG_ROUND_DOWN: 1767 micro_sec = convert_arg / 1000; 1768 break; 1769 case TRIG_ROUND_UP: 1770 micro_sec = (convert_arg - 1) / 1000 + 1; 1771 break; 1772 } 1773 1774 /* return number of nanoseconds */ 1775 return micro_sec * 1000; 1776} 1777 1778/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ 1779static unsigned int suggest_transfer_size(struct comedi_cmd *cmd) 1780{ 1781 unsigned int size = DMA_BUF_SIZE; 1782 static const int sample_size = 2; /* size in bytes of one sample from board */ 1783 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ 1784 unsigned int max_size; /* maximum size we will allow for a transfer */ 1785 1786 /* make dma buffer fill in 0.3 seconds for timed modes */ 1787 switch (cmd->scan_begin_src) { 1788 case TRIG_FOLLOW: /* not in burst mode */ 1789 if (cmd->convert_src == TRIG_TIMER) 1790 size = (fill_time / cmd->convert_arg) * sample_size; 1791 break; 1792 case TRIG_TIMER: 1793 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * 1794 sample_size; 1795 break; 1796 default: 1797 size = DMA_BUF_SIZE; 1798 break; 1799 } 1800 1801 /* set a minimum and maximum size allowed */ 1802 max_size = DMA_BUF_SIZE; 1803 /* if we are taking limited number of conversions, limit transfer size to that */ 1804 if (cmd->stop_src == TRIG_COUNT && 1805 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) 1806 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; 1807 1808 if (size > max_size) 1809 size = max_size; 1810 if (size < sample_size) 1811 size = sample_size; 1812 1813 return size; 1814} 1815 1816MODULE_AUTHOR("Comedi http://www.comedi.org"); 1817MODULE_DESCRIPTION("Comedi low-level driver"); 1818MODULE_LICENSE("GPL"); 1819