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