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