das16.c revision 5a0e3ad6af8660be21ca98a971cd00f331318c05
1/* 2 comedi/drivers/das16.c 3 DAS16 driver 4 5 COMEDI - Linux Control and Measurement Device Interface 6 Copyright (C) 2000 David A. Schleef <ds@schleef.org> 7 Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com> 8 Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net> 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 2 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program; if not, write to the Free Software 22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23 24************************************************************************ 25*/ 26/* 27Driver: das16 28Description: DAS16 compatible boards 29Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze 30Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g), 31 DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202), 32 DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601), 33 DAS-1602 (das-1602), 34 [ComputerBoards] PC104-DAS16/JR (pc104-das16jr), 35 PC104-DAS16JR/16 (pc104-das16jr/16), 36 CIO-DAS16JR/16 (cio-das16jr/16), 37 CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12), 38 CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16), 39 CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12), 40 CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330) 41Status: works 42Updated: 2003-10-12 43 44A rewrite of the das16 and das1600 drivers. 45Options: 46 [0] - base io address 47 [1] - irq (does nothing, irq is not used anymore) 48 [2] - dma (optional, required for comedi_command support) 49 [3] - master clock speed in MHz (optional, 1 or 10, ignored if 50 board can probe clock, defaults to 1) 51 [4] - analog input range lowest voltage in microvolts (optional, 52 only useful if your board does not have software 53 programmable gain) 54 [5] - analog input range highest voltage in microvolts (optional, 55 only useful if board does not have software programmable 56 gain) 57 [6] - analog output range lowest voltage in microvolts (optional) 58 [7] - analog output range highest voltage in microvolts (optional) 59 [8] - use timer mode for DMA. Timer mode is needed e.g. for 60 buggy DMA controllers in NS CS5530A (Geode Companion), and for 61 'jr' cards that lack a hardware fifo. This option is no 62 longer needed, since timer mode is _always_ used. 63 64Passing a zero for an option is the same as leaving it unspecified. 65 66*/ 67/* 68 69Testing and debugging help provided by Daniel Koch. 70 71Keithley Manuals: 72 2309.PDF (das16) 73 4919.PDF (das1400, 1600) 74 4922.PDF (das-1400) 75 4923.PDF (das1200, 1400, 1600) 76 77Computer boards manuals also available from their website www.measurementcomputing.com 78 79*/ 80 81#include <linux/pci.h> 82#include <linux/slab.h> 83#include <linux/interrupt.h> 84#include <asm/dma.h> 85#include "../comedidev.h" 86 87#include "8253.h" 88#include "8255.h" 89#include "comedi_fc.h" 90 91#undef DEBUG 92/* #define DEBUG */ 93 94#ifdef DEBUG 95#define DEBUG_PRINT(format, args...) printk("das16: " format, ## args) 96#else 97#define DEBUG_PRINT(format, args...) 98#endif 99 100#define DAS16_SIZE 20 /* number of ioports */ 101#define DAS16_DMA_SIZE 0xff00 /* size in bytes of allocated dma buffer */ 102 103/* 104 cio-das16.pdf 105 106 "das16" 107 "das16/f" 108 109 0 a/d bits 0-3 start 12 bit 110 1 a/d bits 4-11 unused 111 2 mux read mux set 112 3 di 4 bit do 4 bit 113 4 unused ao0_lsb 114 5 unused ao0_msb 115 6 unused ao1_lsb 116 7 unused ao1_msb 117 8 status eoc uni/bip interrupt reset 118 9 dma, int, trig ctrl set dma, int 119 a pacer control unused 120 b reserved reserved 121 cdef 8254 122 0123 8255 123 124*/ 125 126/* 127 cio-das16jr.pdf 128 129 "das16jr" 130 131 0 a/d bits 0-3 start 12 bit 132 1 a/d bits 4-11 unused 133 2 mux read mux set 134 3 di 4 bit do 4 bit 135 4567 unused unused 136 8 status eoc uni/bip interrupt reset 137 9 dma, int, trig ctrl set dma, int 138 a pacer control unused 139 b gain status gain control 140 cdef 8254 141 142*/ 143 144/* 145 cio-das16jr_16.pdf 146 147 "das16jr_16" 148 149 0 a/d bits 0-7 start 16 bit 150 1 a/d bits 8-15 unused 151 2 mux read mux set 152 3 di 4 bit do 4 bit 153 4567 unused unused 154 8 status eoc uni/bip interrupt reset 155 9 dma, int, trig ctrl set dma, int 156 a pacer control unused 157 b gain status gain control 158 cdef 8254 159 160*/ 161/* 162 cio-das160x-1x.pdf 163 164 "das1601/12" 165 "das1602/12" 166 "das1602/16" 167 168 0 a/d bits 0-3 start 12 bit 169 1 a/d bits 4-11 unused 170 2 mux read mux set 171 3 di 4 bit do 4 bit 172 4 unused ao0_lsb 173 5 unused ao0_msb 174 6 unused ao1_lsb 175 7 unused ao1_msb 176 8 status eoc uni/bip interrupt reset 177 9 dma, int, trig ctrl set dma, int 178 a pacer control unused 179 b gain status gain control 180 cdef 8254 181 400 8255 182 404 unused conversion enable 183 405 unused burst enable 184 406 unused das1600 enable 185 407 status 186 187*/ 188 189static const int sample_size = 2; /* size in bytes of a sample from board */ 190 191#define DAS16_TRIG 0 192#define DAS16_AI_LSB 0 193#define DAS16_AI_MSB 1 194#define DAS16_MUX 2 195#define DAS16_DIO 3 196#define DAS16_AO_LSB(x) ((x)?6:4) 197#define DAS16_AO_MSB(x) ((x)?7:5) 198#define DAS16_STATUS 8 199#define BUSY (1<<7) 200#define UNIPOLAR (1<<6) 201#define DAS16_MUXBIT (1<<5) 202#define DAS16_INT (1<<4) 203#define DAS16_CONTROL 9 204#define DAS16_INTE (1<<7) 205#define DAS16_IRQ(x) (((x) & 0x7) << 4) 206#define DMA_ENABLE (1<<2) 207#define PACING_MASK 0x3 208#define INT_PACER 0x03 209#define EXT_PACER 0x02 210#define DAS16_SOFT 0x00 211#define DAS16_PACER 0x0A 212#define DAS16_CTR0 (1<<1) 213#define DAS16_TRIG0 (1<<0) 214#define BURST_LEN_BITS(x) (((x) & 0xf) << 4) 215#define DAS16_GAIN 0x0B 216#define DAS16_CNTR0_DATA 0x0C 217#define DAS16_CNTR1_DATA 0x0D 218#define DAS16_CNTR2_DATA 0x0E 219#define DAS16_CNTR_CONTROL 0x0F 220#define DAS16_TERM_CNT 0x00 221#define DAS16_ONE_SHOT 0x02 222#define DAS16_RATE_GEN 0x04 223#define DAS16_CNTR_LSB_MSB 0x30 224#define DAS16_CNTR0 0x00 225#define DAS16_CNTR1 0x40 226#define DAS16_CNTR2 0x80 227 228#define DAS1600_CONV 0x404 229#define DAS1600_CONV_DISABLE 0x40 230#define DAS1600_BURST 0x405 231#define DAS1600_BURST_VAL 0x40 232#define DAS1600_ENABLE 0x406 233#define DAS1600_ENABLE_VAL 0x40 234#define DAS1600_STATUS_B 0x407 235#define DAS1600_BME 0x40 236#define DAS1600_ME 0x20 237#define DAS1600_CD 0x10 238#define DAS1600_WS 0x02 239#define DAS1600_CLK_10MHZ 0x01 240 241static const struct comedi_lrange range_das1x01_bip = { 4, { 242 BIP_RANGE(10), 243 BIP_RANGE(1), 244 BIP_RANGE(0.1), 245 BIP_RANGE(0.01), 246 } 247}; 248 249static const struct comedi_lrange range_das1x01_unip = { 4, { 250 UNI_RANGE(10), 251 UNI_RANGE(1), 252 UNI_RANGE(0.1), 253 UNI_RANGE(0.01), 254 } 255}; 256 257static const struct comedi_lrange range_das1x02_bip = { 4, { 258 BIP_RANGE(10), 259 BIP_RANGE(5), 260 BIP_RANGE(2.5), 261 BIP_RANGE(1.25), 262 } 263}; 264 265static const struct comedi_lrange range_das1x02_unip = { 4, { 266 UNI_RANGE(10), 267 UNI_RANGE(5), 268 UNI_RANGE(2.5), 269 UNI_RANGE(1.25), 270 } 271}; 272 273static const struct comedi_lrange range_das16jr = { 9, { 274 /* also used by 16/330 */ 275 BIP_RANGE(10), 276 BIP_RANGE(5), 277 BIP_RANGE(2.5), 278 BIP_RANGE(1.25), 279 BIP_RANGE(0.625), 280 UNI_RANGE(10), 281 UNI_RANGE(5), 282 UNI_RANGE(2.5), 283 UNI_RANGE(1.25), 284 } 285}; 286 287static const struct comedi_lrange range_das16jr_16 = { 8, { 288 BIP_RANGE(10), 289 BIP_RANGE(5), 290 BIP_RANGE(2.5), 291 BIP_RANGE(1.25), 292 UNI_RANGE(10), 293 UNI_RANGE(5), 294 UNI_RANGE(2.5), 295 UNI_RANGE(1.25), 296 } 297}; 298 299static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 }; 300static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; 301static const int das1600_gainlist[] = { 0, 1, 2, 3 }; 302 303enum { 304 das16_pg_none = 0, 305 das16_pg_16jr, 306 das16_pg_16jr_16, 307 das16_pg_1601, 308 das16_pg_1602, 309}; 310static const int *const das16_gainlists[] = { 311 NULL, 312 das16jr_gainlist, 313 das16jr_16_gainlist, 314 das1600_gainlist, 315 das1600_gainlist, 316}; 317 318static const struct comedi_lrange *const das16_ai_uni_lranges[] = { 319 &range_unknown, 320 &range_das16jr, 321 &range_das16jr_16, 322 &range_das1x01_unip, 323 &range_das1x02_unip, 324}; 325 326static const struct comedi_lrange *const das16_ai_bip_lranges[] = { 327 &range_unknown, 328 &range_das16jr, 329 &range_das16jr_16, 330 &range_das1x01_bip, 331 &range_das1x02_bip, 332}; 333 334struct munge_info { 335 uint8_t byte; 336 unsigned have_byte:1; 337}; 338 339static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, 340 struct comedi_insn *insn, unsigned int *data); 341static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, 342 struct comedi_insn *insn, unsigned int *data); 343static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, 344 struct comedi_insn *insn, unsigned int *data); 345static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, 346 struct comedi_insn *insn, unsigned int *data); 347 348static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, 349 struct comedi_cmd *cmd); 350static int das16_cmd_exec(struct comedi_device *dev, 351 struct comedi_subdevice *s); 352static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s); 353static void das16_ai_munge(struct comedi_device *dev, 354 struct comedi_subdevice *s, void *array, 355 unsigned int num_bytes, 356 unsigned int start_chan_index); 357 358static void das16_reset(struct comedi_device *dev); 359static irqreturn_t das16_dma_interrupt(int irq, void *d); 360static void das16_timer_interrupt(unsigned long arg); 361static void das16_interrupt(struct comedi_device *dev); 362 363static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, 364 int flags); 365static int das1600_mode_detect(struct comedi_device *dev); 366static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, 367 struct comedi_cmd cmd); 368 369static void reg_dump(struct comedi_device *dev); 370 371struct das16_board { 372 const char *name; 373 void *ai; 374 unsigned int ai_nbits; 375 unsigned int ai_speed; /* max conversion speed in nanosec */ 376 unsigned int ai_pg; 377 void *ao; 378 unsigned int ao_nbits; 379 void *di; 380 void *do_; 381 382 unsigned int i8255_offset; 383 unsigned int i8254_offset; 384 385 unsigned int size; 386 unsigned int id; 387}; 388 389static const struct das16_board das16_boards[] = { 390 { 391 .name = "das-16", 392 .ai = das16_ai_rinsn, 393 .ai_nbits = 12, 394 .ai_speed = 15000, 395 .ai_pg = das16_pg_none, 396 .ao = das16_ao_winsn, 397 .ao_nbits = 12, 398 .di = das16_di_rbits, 399 .do_ = das16_do_wbits, 400 .i8255_offset = 0x10, 401 .i8254_offset = 0x0c, 402 .size = 0x14, 403 .id = 0x00, 404 }, 405 { 406 .name = "das-16g", 407 .ai = das16_ai_rinsn, 408 .ai_nbits = 12, 409 .ai_speed = 15000, 410 .ai_pg = das16_pg_none, 411 .ao = das16_ao_winsn, 412 .ao_nbits = 12, 413 .di = das16_di_rbits, 414 .do_ = das16_do_wbits, 415 .i8255_offset = 0x10, 416 .i8254_offset = 0x0c, 417 .size = 0x14, 418 .id = 0x00, 419 }, 420 { 421 .name = "das-16f", 422 .ai = das16_ai_rinsn, 423 .ai_nbits = 12, 424 .ai_speed = 8500, 425 .ai_pg = das16_pg_none, 426 .ao = das16_ao_winsn, 427 .ao_nbits = 12, 428 .di = das16_di_rbits, 429 .do_ = das16_do_wbits, 430 .i8255_offset = 0x10, 431 .i8254_offset = 0x0c, 432 .size = 0x14, 433 .id = 0x00, 434 }, 435 { 436 .name = "cio-das16", /* cio-das16.pdf */ 437 .ai = das16_ai_rinsn, 438 .ai_nbits = 12, 439 .ai_speed = 20000, 440 .ai_pg = das16_pg_none, 441 .ao = das16_ao_winsn, 442 .ao_nbits = 12, 443 .di = das16_di_rbits, 444 .do_ = das16_do_wbits, 445 .i8255_offset = 0x10, 446 .i8254_offset = 0x0c, 447 .size = 0x14, 448 .id = 0x80, 449 }, 450 { 451 .name = "cio-das16/f", /* das16.pdf */ 452 .ai = das16_ai_rinsn, 453 .ai_nbits = 12, 454 .ai_speed = 10000, 455 .ai_pg = das16_pg_none, 456 .ao = das16_ao_winsn, 457 .ao_nbits = 12, 458 .di = das16_di_rbits, 459 .do_ = das16_do_wbits, 460 .i8255_offset = 0x10, 461 .i8254_offset = 0x0c, 462 .size = 0x14, 463 .id = 0x80, 464 }, 465 { 466 .name = "cio-das16/jr", /* cio-das16jr.pdf */ 467 .ai = das16_ai_rinsn, 468 .ai_nbits = 12, 469 .ai_speed = 7692, 470 .ai_pg = das16_pg_16jr, 471 .ao = NULL, 472 .di = das16_di_rbits, 473 .do_ = das16_do_wbits, 474 .i8255_offset = 0, 475 .i8254_offset = 0x0c, 476 .size = 0x10, 477 .id = 0x00, 478 }, 479 { 480 .name = "pc104-das16jr", /* pc104-das16jr_xx.pdf */ 481 .ai = das16_ai_rinsn, 482 .ai_nbits = 12, 483 .ai_speed = 3300, 484 .ai_pg = das16_pg_16jr, 485 .ao = NULL, 486 .di = das16_di_rbits, 487 .do_ = das16_do_wbits, 488 .i8255_offset = 0, 489 .i8254_offset = 0x0c, 490 .size = 0x10, 491 .id = 0x00, 492 }, 493 { 494 .name = "cio-das16jr/16", /* cio-das16jr_16.pdf */ 495 .ai = das16_ai_rinsn, 496 .ai_nbits = 16, 497 .ai_speed = 10000, 498 .ai_pg = das16_pg_16jr_16, 499 .ao = NULL, 500 .di = das16_di_rbits, 501 .do_ = das16_do_wbits, 502 .i8255_offset = 0, 503 .i8254_offset = 0x0c, 504 .size = 0x10, 505 .id = 0x00, 506 }, 507 { 508 .name = "pc104-das16jr/16", /* pc104-das16jr_xx.pdf */ 509 .ai = das16_ai_rinsn, 510 .ai_nbits = 16, 511 .ai_speed = 10000, 512 .ai_pg = das16_pg_16jr_16, 513 .ao = NULL, 514 .di = das16_di_rbits, 515 .do_ = das16_do_wbits, 516 .i8255_offset = 0, 517 .i8254_offset = 0x0c, 518 .size = 0x10, 519 .id = 0x00, 520 }, 521 { 522 .name = "das-1201", /* 4924.pdf (keithley user's manual) */ 523 .ai = das16_ai_rinsn, 524 .ai_nbits = 12, 525 .ai_speed = 20000, 526 .ai_pg = das16_pg_none, 527 .ao = NULL, 528 .di = das16_di_rbits, 529 .do_ = das16_do_wbits, 530 .i8255_offset = 0x400, 531 .i8254_offset = 0x0c, 532 .size = 0x408, 533 .id = 0x20, 534 }, 535 { 536 .name = "das-1202", /* 4924.pdf (keithley user's manual) */ 537 .ai = das16_ai_rinsn, 538 .ai_nbits = 12, 539 .ai_speed = 10000, 540 .ai_pg = das16_pg_none, 541 .ao = NULL, 542 .di = das16_di_rbits, 543 .do_ = das16_do_wbits, 544 .i8255_offset = 0x400, 545 .i8254_offset = 0x0c, 546 .size = 0x408, 547 .id = 0x20, 548 }, 549 { 550 .name = "das-1401", /* 4919.pdf and 4922.pdf (keithley user's manual) */ 551 .ai = das16_ai_rinsn, 552 .ai_nbits = 12, 553 .ai_speed = 10000, 554 .ai_pg = das16_pg_1601, 555 .ao = NULL, 556 .di = das16_di_rbits, 557 .do_ = das16_do_wbits, 558 .i8255_offset = 0x0, 559 .i8254_offset = 0x0c, 560 .size = 0x408, 561 .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */ 562 }, 563 { 564 .name = "das-1402", /* 4919.pdf and 4922.pdf (keithley user's manual) */ 565 .ai = das16_ai_rinsn, 566 .ai_nbits = 12, 567 .ai_speed = 10000, 568 .ai_pg = das16_pg_1602, 569 .ao = NULL, 570 .di = das16_di_rbits, 571 .do_ = das16_do_wbits, 572 .i8255_offset = 0x0, 573 .i8254_offset = 0x0c, 574 .size = 0x408, 575 .id = 0xc0 /* 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0 */ 576 }, 577 { 578 .name = "das-1601", /* 4919.pdf */ 579 .ai = das16_ai_rinsn, 580 .ai_nbits = 12, 581 .ai_speed = 10000, 582 .ai_pg = das16_pg_1601, 583 .ao = das16_ao_winsn, 584 .ao_nbits = 12, 585 .di = das16_di_rbits, 586 .do_ = das16_do_wbits, 587 .i8255_offset = 0x400, 588 .i8254_offset = 0x0c, 589 .size = 0x408, 590 .id = 0xc0}, 591 { 592 .name = "das-1602", /* 4919.pdf */ 593 .ai = das16_ai_rinsn, 594 .ai_nbits = 12, 595 .ai_speed = 10000, 596 .ai_pg = das16_pg_1602, 597 .ao = das16_ao_winsn, 598 .ao_nbits = 12, 599 .di = das16_di_rbits, 600 .do_ = das16_do_wbits, 601 .i8255_offset = 0x400, 602 .i8254_offset = 0x0c, 603 .size = 0x408, 604 .id = 0xc0}, 605 { 606 .name = "cio-das1401/12", /* cio-das1400_series.pdf */ 607 .ai = das16_ai_rinsn, 608 .ai_nbits = 12, 609 .ai_speed = 6250, 610 .ai_pg = das16_pg_1601, 611 .ao = NULL, 612 .di = das16_di_rbits, 613 .do_ = das16_do_wbits, 614 .i8255_offset = 0, 615 .i8254_offset = 0x0c, 616 .size = 0x408, 617 .id = 0xc0}, 618 { 619 .name = "cio-das1402/12", /* cio-das1400_series.pdf */ 620 .ai = das16_ai_rinsn, 621 .ai_nbits = 12, 622 .ai_speed = 6250, 623 .ai_pg = das16_pg_1602, 624 .ao = NULL, 625 .di = das16_di_rbits, 626 .do_ = das16_do_wbits, 627 .i8255_offset = 0, 628 .i8254_offset = 0x0c, 629 .size = 0x408, 630 .id = 0xc0}, 631 { 632 .name = "cio-das1402/16", /* cio-das1400_series.pdf */ 633 .ai = das16_ai_rinsn, 634 .ai_nbits = 16, 635 .ai_speed = 10000, 636 .ai_pg = das16_pg_1602, 637 .ao = NULL, 638 .di = das16_di_rbits, 639 .do_ = das16_do_wbits, 640 .i8255_offset = 0, 641 .i8254_offset = 0x0c, 642 .size = 0x408, 643 .id = 0xc0}, 644 { 645 .name = "cio-das1601/12", /* cio-das160x-1x.pdf */ 646 .ai = das16_ai_rinsn, 647 .ai_nbits = 12, 648 .ai_speed = 6250, 649 .ai_pg = das16_pg_1601, 650 .ao = das16_ao_winsn, 651 .ao_nbits = 12, 652 .di = das16_di_rbits, 653 .do_ = das16_do_wbits, 654 .i8255_offset = 0x400, 655 .i8254_offset = 0x0c, 656 .size = 0x408, 657 .id = 0xc0}, 658 { 659 .name = "cio-das1602/12", /* cio-das160x-1x.pdf */ 660 .ai = das16_ai_rinsn, 661 .ai_nbits = 12, 662 .ai_speed = 10000, 663 .ai_pg = das16_pg_1602, 664 .ao = das16_ao_winsn, 665 .ao_nbits = 12, 666 .di = das16_di_rbits, 667 .do_ = das16_do_wbits, 668 .i8255_offset = 0x400, 669 .i8254_offset = 0x0c, 670 .size = 0x408, 671 .id = 0xc0}, 672 { 673 .name = "cio-das1602/16", /* cio-das160x-1x.pdf */ 674 .ai = das16_ai_rinsn, 675 .ai_nbits = 16, 676 .ai_speed = 10000, 677 .ai_pg = das16_pg_1602, 678 .ao = das16_ao_winsn, 679 .ao_nbits = 12, 680 .di = das16_di_rbits, 681 .do_ = das16_do_wbits, 682 .i8255_offset = 0x400, 683 .i8254_offset = 0x0c, 684 .size = 0x408, 685 .id = 0xc0}, 686 { 687 .name = "cio-das16/330", /* ? */ 688 .ai = das16_ai_rinsn, 689 .ai_nbits = 12, 690 .ai_speed = 3030, 691 .ai_pg = das16_pg_16jr, 692 .ao = NULL, 693 .di = das16_di_rbits, 694 .do_ = das16_do_wbits, 695 .i8255_offset = 0, 696 .i8254_offset = 0x0c, 697 .size = 0x14, 698 .id = 0xf0}, 699#if 0 700 { 701 .name = "das16/330i", /* ? */ 702 }, 703 { 704 .name = "das16/jr/ctr5", /* ? */ 705 }, 706 { 707 .name = "cio-das16/m1/16", /* cio-das16_m1_16.pdf, this board is a bit quirky, no dma */ 708 }, 709#endif 710}; 711 712static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it); 713static int das16_detach(struct comedi_device *dev); 714static struct comedi_driver driver_das16 = { 715 .driver_name = "das16", 716 .module = THIS_MODULE, 717 .attach = das16_attach, 718 .detach = das16_detach, 719 .board_name = &das16_boards[0].name, 720 .num_names = ARRAY_SIZE(das16_boards), 721 .offset = sizeof(das16_boards[0]), 722}; 723 724#define DAS16_TIMEOUT 1000 725 726/* Period for timer interrupt in jiffies. It's a function 727 * to deal with possibility of dynamic HZ patches */ 728static inline int timer_period(void) 729{ 730 return HZ / 20; 731} 732 733struct das16_private_struct { 734 unsigned int ai_unipolar; /* unipolar flag */ 735 unsigned int ai_singleended; /* single ended flag */ 736 unsigned int clockbase; /* master clock speed in ns */ 737 volatile unsigned int control_state; /* dma, interrupt and trigger control bits */ 738 volatile unsigned long adc_byte_count; /* number of bytes remaining */ 739 unsigned int divisor1; /* divisor dividing master clock to get conversion frequency */ 740 unsigned int divisor2; /* divisor dividing master clock to get conversion frequency */ 741 unsigned int dma_chan; /* dma channel */ 742 uint16_t *dma_buffer[2]; 743 dma_addr_t dma_buffer_addr[2]; 744 unsigned int current_buffer; 745 volatile unsigned int dma_transfer_size; /* target number of bytes to transfer per dma shot */ 746 /* user-defined analog input and output ranges defined from config options */ 747 struct comedi_lrange *user_ai_range_table; 748 struct comedi_lrange *user_ao_range_table; 749 750 struct timer_list timer; /* for timed interrupt */ 751 volatile short timer_running; 752 volatile short timer_mode; /* true if using timer mode */ 753}; 754#define devpriv ((struct das16_private_struct *)(dev->private)) 755#define thisboard ((struct das16_board *)(dev->board_ptr)) 756 757static int das16_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s, 758 struct comedi_cmd *cmd) 759{ 760 int err = 0, tmp; 761 int gain, start_chan, i; 762 int mask; 763 764 /* make sure triggers are valid */ 765 tmp = cmd->start_src; 766 cmd->start_src &= TRIG_NOW; 767 if (!cmd->start_src || tmp != cmd->start_src) 768 err++; 769 770 tmp = cmd->scan_begin_src; 771 mask = TRIG_FOLLOW; 772 /* if board supports burst mode */ 773 if (thisboard->size > 0x400) 774 mask |= TRIG_TIMER | TRIG_EXT; 775 cmd->scan_begin_src &= mask; 776 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 777 err++; 778 779 tmp = cmd->convert_src; 780 mask = TRIG_TIMER | TRIG_EXT; 781 /* if board supports burst mode */ 782 if (thisboard->size > 0x400) 783 mask |= TRIG_NOW; 784 cmd->convert_src &= mask; 785 if (!cmd->convert_src || tmp != cmd->convert_src) 786 err++; 787 788 tmp = cmd->scan_end_src; 789 cmd->scan_end_src &= TRIG_COUNT; 790 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 791 err++; 792 793 tmp = cmd->stop_src; 794 cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 795 if (!cmd->stop_src || tmp != cmd->stop_src) 796 err++; 797 798 if (err) 799 return 1; 800 801 /* step 2: make sure trigger sources are unique and mutually compatible */ 802 if (cmd->scan_begin_src != TRIG_TIMER && 803 cmd->scan_begin_src != TRIG_EXT && 804 cmd->scan_begin_src != TRIG_FOLLOW) 805 err++; 806 if (cmd->convert_src != TRIG_TIMER && 807 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) 808 err++; 809 if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT) 810 err++; 811 812 /* make sure scan_begin_src and convert_src dont conflict */ 813 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) 814 err++; 815 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) 816 err++; 817 818 if (err) 819 return 2; 820 821 /* step 3: make sure arguments are trivially compatible */ 822 if (cmd->start_arg != 0) { 823 cmd->start_arg = 0; 824 err++; 825 } 826 827 if (cmd->scan_begin_src == TRIG_FOLLOW) { 828 /* internal trigger */ 829 if (cmd->scan_begin_arg != 0) { 830 cmd->scan_begin_arg = 0; 831 err++; 832 } 833 } 834 835 if (cmd->scan_end_arg != cmd->chanlist_len) { 836 cmd->scan_end_arg = cmd->chanlist_len; 837 err++; 838 } 839 /* check against maximum frequency */ 840 if (cmd->scan_begin_src == TRIG_TIMER) { 841 if (cmd->scan_begin_arg < 842 thisboard->ai_speed * cmd->chanlist_len) { 843 cmd->scan_begin_arg = 844 thisboard->ai_speed * cmd->chanlist_len; 845 err++; 846 } 847 } 848 if (cmd->convert_src == TRIG_TIMER) { 849 if (cmd->convert_arg < thisboard->ai_speed) { 850 cmd->convert_arg = thisboard->ai_speed; 851 err++; 852 } 853 } 854 855 if (cmd->stop_src == TRIG_NONE) { 856 if (cmd->stop_arg != 0) { 857 cmd->stop_arg = 0; 858 err++; 859 } 860 } 861 if (err) 862 return 3; 863 864 /* step 4: fix up arguments */ 865 if (cmd->scan_begin_src == TRIG_TIMER) { 866 unsigned int tmp = cmd->scan_begin_arg; 867 /* set divisors, correct timing arguments */ 868 i8253_cascade_ns_to_timer_2div(devpriv->clockbase, 869 &(devpriv->divisor1), 870 &(devpriv->divisor2), 871 &(cmd->scan_begin_arg), 872 cmd->flags & TRIG_ROUND_MASK); 873 err += (tmp != cmd->scan_begin_arg); 874 } 875 if (cmd->convert_src == TRIG_TIMER) { 876 unsigned int tmp = cmd->convert_arg; 877 /* set divisors, correct timing arguments */ 878 i8253_cascade_ns_to_timer_2div(devpriv->clockbase, 879 &(devpriv->divisor1), 880 &(devpriv->divisor2), 881 &(cmd->convert_arg), 882 cmd->flags & TRIG_ROUND_MASK); 883 err += (tmp != cmd->convert_arg); 884 } 885 if (err) 886 return 4; 887 888 /* check channel/gain list against card's limitations */ 889 if (cmd->chanlist) { 890 gain = CR_RANGE(cmd->chanlist[0]); 891 start_chan = CR_CHAN(cmd->chanlist[0]); 892 for (i = 1; i < cmd->chanlist_len; i++) { 893 if (CR_CHAN(cmd->chanlist[i]) != 894 (start_chan + i) % s->n_chan) { 895 comedi_error(dev, 896 "entries in chanlist must be consecutive channels, counting upwards\n"); 897 err++; 898 } 899 if (CR_RANGE(cmd->chanlist[i]) != gain) { 900 comedi_error(dev, 901 "entries in chanlist must all have the same gain\n"); 902 err++; 903 } 904 } 905 } 906 if (err) 907 return 5; 908 909 return 0; 910} 911 912static int das16_cmd_exec(struct comedi_device *dev, struct comedi_subdevice *s) 913{ 914 struct comedi_async *async = s->async; 915 struct comedi_cmd *cmd = &async->cmd; 916 unsigned int byte; 917 unsigned long flags; 918 int range; 919 920 if (devpriv->dma_chan == 0 || (dev->irq == 0 921 && devpriv->timer_mode == 0)) { 922 comedi_error(dev, 923 "irq (or use of 'timer mode') dma required to execute comedi_cmd"); 924 return -1; 925 } 926 if (cmd->flags & TRIG_RT) { 927 comedi_error(dev, 928 "isa dma transfers cannot be performed with TRIG_RT, aborting"); 929 return -1; 930 } 931 932 devpriv->adc_byte_count = 933 cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t); 934 935 /* disable conversions for das1600 mode */ 936 if (thisboard->size > 0x400) { 937 outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV); 938 } 939 /* set scan limits */ 940 byte = CR_CHAN(cmd->chanlist[0]); 941 byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4; 942 outb(byte, dev->iobase + DAS16_MUX); 943 944 /* set gain (this is also burst rate register but according to 945 * computer boards manual, burst rate does nothing, even on keithley cards) */ 946 if (thisboard->ai_pg != das16_pg_none) { 947 range = CR_RANGE(cmd->chanlist[0]); 948 outb((das16_gainlists[thisboard->ai_pg])[range], 949 dev->iobase + DAS16_GAIN); 950 } 951 952 /* set counter mode and counts */ 953 cmd->convert_arg = 954 das16_set_pacer(dev, cmd->convert_arg, 955 cmd->flags & TRIG_ROUND_MASK); 956 DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg); 957 958 /* enable counters */ 959 byte = 0; 960 /* Enable burst mode if appropriate. */ 961 if (thisboard->size > 0x400) { 962 if (cmd->convert_src == TRIG_NOW) { 963 outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST); 964 /* set burst length */ 965 byte |= BURST_LEN_BITS(cmd->chanlist_len - 1); 966 } else { 967 outb(0, dev->iobase + DAS1600_BURST); 968 } 969 } 970 outb(byte, dev->iobase + DAS16_PACER); 971 972 /* set up dma transfer */ 973 flags = claim_dma_lock(); 974 disable_dma(devpriv->dma_chan); 975 /* clear flip-flop to make sure 2-byte registers for 976 * count and address get set correctly */ 977 clear_dma_ff(devpriv->dma_chan); 978 devpriv->current_buffer = 0; 979 set_dma_addr(devpriv->dma_chan, 980 devpriv->dma_buffer_addr[devpriv->current_buffer]); 981 /* set appropriate size of transfer */ 982 devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd); 983 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); 984 enable_dma(devpriv->dma_chan); 985 release_dma_lock(flags); 986 987 /* set up interrupt */ 988 if (devpriv->timer_mode) { 989 devpriv->timer_running = 1; 990 devpriv->timer.expires = jiffies + timer_period(); 991 add_timer(&devpriv->timer); 992 devpriv->control_state &= ~DAS16_INTE; 993 } else { 994 /* clear interrupt bit */ 995 outb(0x00, dev->iobase + DAS16_STATUS); 996 /* enable interrupts */ 997 devpriv->control_state |= DAS16_INTE; 998 } 999 devpriv->control_state |= DMA_ENABLE; 1000 devpriv->control_state &= ~PACING_MASK; 1001 if (cmd->convert_src == TRIG_EXT) 1002 devpriv->control_state |= EXT_PACER; 1003 else 1004 devpriv->control_state |= INT_PACER; 1005 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL); 1006 1007 /* Enable conversions if using das1600 mode */ 1008 if (thisboard->size > 0x400) { 1009 outb(0, dev->iobase + DAS1600_CONV); 1010 } 1011 1012 return 0; 1013} 1014 1015static int das16_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 1016{ 1017 unsigned long flags; 1018 1019 spin_lock_irqsave(&dev->spinlock, flags); 1020 /* disable interrupts, dma and pacer clocked conversions */ 1021 devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE; 1022 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL); 1023 if (devpriv->dma_chan) 1024 disable_dma(devpriv->dma_chan); 1025 1026 /* disable SW timer */ 1027 if (devpriv->timer_mode && devpriv->timer_running) { 1028 devpriv->timer_running = 0; 1029 del_timer(&devpriv->timer); 1030 } 1031 1032 /* disable burst mode */ 1033 if (thisboard->size > 0x400) { 1034 outb(0, dev->iobase + DAS1600_BURST); 1035 } 1036 1037 spin_unlock_irqrestore(&dev->spinlock, flags); 1038 1039 return 0; 1040} 1041 1042static void das16_reset(struct comedi_device *dev) 1043{ 1044 outb(0, dev->iobase + DAS16_STATUS); 1045 outb(0, dev->iobase + DAS16_CONTROL); 1046 outb(0, dev->iobase + DAS16_PACER); 1047 outb(0, dev->iobase + DAS16_CNTR_CONTROL); 1048} 1049 1050static int das16_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, 1051 struct comedi_insn *insn, unsigned int *data) 1052{ 1053 int i, n; 1054 int range; 1055 int chan; 1056 int msb, lsb; 1057 1058 /* disable interrupts and pacing */ 1059 devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK; 1060 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL); 1061 1062 /* set multiplexer */ 1063 chan = CR_CHAN(insn->chanspec); 1064 chan |= CR_CHAN(insn->chanspec) << 4; 1065 outb(chan, dev->iobase + DAS16_MUX); 1066 1067 /* set gain */ 1068 if (thisboard->ai_pg != das16_pg_none) { 1069 range = CR_RANGE(insn->chanspec); 1070 outb((das16_gainlists[thisboard->ai_pg])[range], 1071 dev->iobase + DAS16_GAIN); 1072 } 1073 1074 for (n = 0; n < insn->n; n++) { 1075 /* trigger conversion */ 1076 outb_p(0, dev->iobase + DAS16_TRIG); 1077 1078 for (i = 0; i < DAS16_TIMEOUT; i++) { 1079 if (!(inb(dev->iobase + DAS16_STATUS) & BUSY)) 1080 break; 1081 } 1082 if (i == DAS16_TIMEOUT) { 1083 printk("das16: timeout\n"); 1084 return -ETIME; 1085 } 1086 msb = inb(dev->iobase + DAS16_AI_MSB); 1087 lsb = inb(dev->iobase + DAS16_AI_LSB); 1088 if (thisboard->ai_nbits == 12) { 1089 data[n] = ((lsb >> 4) & 0xf) | (msb << 4); 1090 } else { 1091 data[n] = lsb | (msb << 8); 1092 } 1093 } 1094 1095 return n; 1096} 1097 1098static int das16_di_rbits(struct comedi_device *dev, struct comedi_subdevice *s, 1099 struct comedi_insn *insn, unsigned int *data) 1100{ 1101 unsigned int bits; 1102 1103 bits = inb(dev->iobase + DAS16_DIO) & 0xf; 1104 data[1] = bits; 1105 data[0] = 0; 1106 1107 return 2; 1108} 1109 1110static int das16_do_wbits(struct comedi_device *dev, struct comedi_subdevice *s, 1111 struct comedi_insn *insn, unsigned int *data) 1112{ 1113 unsigned int wbits; 1114 1115 /* only set bits that have been masked */ 1116 data[0] &= 0xf; 1117 wbits = s->state; 1118 /* zero bits that have been masked */ 1119 wbits &= ~data[0]; 1120 /* set masked bits */ 1121 wbits |= data[0] & data[1]; 1122 s->state = wbits; 1123 data[1] = wbits; 1124 1125 outb(s->state, dev->iobase + DAS16_DIO); 1126 1127 return 2; 1128} 1129 1130static int das16_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, 1131 struct comedi_insn *insn, unsigned int *data) 1132{ 1133 int i; 1134 int lsb, msb; 1135 int chan; 1136 1137 chan = CR_CHAN(insn->chanspec); 1138 1139 for (i = 0; i < insn->n; i++) { 1140 if (thisboard->ao_nbits == 12) { 1141 lsb = (data[i] << 4) & 0xff; 1142 msb = (data[i] >> 4) & 0xff; 1143 } else { 1144 lsb = data[i] & 0xff; 1145 msb = (data[i] >> 8) & 0xff; 1146 } 1147 outb(lsb, dev->iobase + DAS16_AO_LSB(chan)); 1148 outb(msb, dev->iobase + DAS16_AO_MSB(chan)); 1149 } 1150 1151 return i; 1152} 1153 1154static irqreturn_t das16_dma_interrupt(int irq, void *d) 1155{ 1156 int status; 1157 struct comedi_device *dev = d; 1158 1159 status = inb(dev->iobase + DAS16_STATUS); 1160 1161 if ((status & DAS16_INT) == 0) { 1162 DEBUG_PRINT("spurious interrupt\n"); 1163 return IRQ_NONE; 1164 } 1165 1166 /* clear interrupt */ 1167 outb(0x00, dev->iobase + DAS16_STATUS); 1168 das16_interrupt(dev); 1169 return IRQ_HANDLED; 1170} 1171 1172static void das16_timer_interrupt(unsigned long arg) 1173{ 1174 struct comedi_device *dev = (struct comedi_device *)arg; 1175 1176 das16_interrupt(dev); 1177 1178 if (devpriv->timer_running) 1179 mod_timer(&devpriv->timer, jiffies + timer_period()); 1180} 1181 1182/* the pc104-das16jr (at least) has problems if the dma 1183 transfer is interrupted in the middle of transferring 1184 a 16 bit sample, so this function takes care to get 1185 an even transfer count after disabling dma 1186 channel. 1187*/ 1188static int disable_dma_on_even(struct comedi_device *dev) 1189{ 1190 int residue; 1191 int i; 1192 static const int disable_limit = 100; 1193 static const int enable_timeout = 100; 1194 disable_dma(devpriv->dma_chan); 1195 residue = get_dma_residue(devpriv->dma_chan); 1196 for (i = 0; i < disable_limit && (residue % 2); ++i) { 1197 int j; 1198 enable_dma(devpriv->dma_chan); 1199 for (j = 0; j < enable_timeout; ++j) { 1200 int new_residue; 1201 udelay(2); 1202 new_residue = get_dma_residue(devpriv->dma_chan); 1203 if (new_residue != residue) 1204 break; 1205 } 1206 disable_dma(devpriv->dma_chan); 1207 residue = get_dma_residue(devpriv->dma_chan); 1208 } 1209 if (i == disable_limit) { 1210 comedi_error(dev, 1211 "failed to get an even dma transfer, could be trouble."); 1212 } 1213 return residue; 1214} 1215 1216static void das16_interrupt(struct comedi_device *dev) 1217{ 1218 unsigned long dma_flags, spin_flags; 1219 struct comedi_subdevice *s = dev->read_subdev; 1220 struct comedi_async *async; 1221 struct comedi_cmd *cmd; 1222 int num_bytes, residue; 1223 int buffer_index; 1224 1225 if (dev->attached == 0) { 1226 comedi_error(dev, "premature interrupt"); 1227 return; 1228 } 1229 /* initialize async here to make sure it is not NULL */ 1230 async = s->async; 1231 cmd = &async->cmd; 1232 1233 if (devpriv->dma_chan == 0) { 1234 comedi_error(dev, "interrupt with no dma channel?"); 1235 return; 1236 } 1237 1238 spin_lock_irqsave(&dev->spinlock, spin_flags); 1239 if ((devpriv->control_state & DMA_ENABLE) == 0) { 1240 spin_unlock_irqrestore(&dev->spinlock, spin_flags); 1241 DEBUG_PRINT("interrupt while dma disabled?\n"); 1242 return; 1243 } 1244 1245 dma_flags = claim_dma_lock(); 1246 clear_dma_ff(devpriv->dma_chan); 1247 residue = disable_dma_on_even(dev); 1248 1249 /* figure out how many points to read */ 1250 if (residue > devpriv->dma_transfer_size) { 1251 comedi_error(dev, "residue > transfer size!\n"); 1252 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 1253 num_bytes = 0; 1254 } else 1255 num_bytes = devpriv->dma_transfer_size - residue; 1256 1257 if (cmd->stop_src == TRIG_COUNT && num_bytes >= devpriv->adc_byte_count) { 1258 num_bytes = devpriv->adc_byte_count; 1259 async->events |= COMEDI_CB_EOA; 1260 } 1261 1262 buffer_index = devpriv->current_buffer; 1263 devpriv->current_buffer = (devpriv->current_buffer + 1) % 2; 1264 devpriv->adc_byte_count -= num_bytes; 1265 1266 /* figure out how many bytes for next transfer */ 1267 if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 && 1268 devpriv->dma_transfer_size > devpriv->adc_byte_count) 1269 devpriv->dma_transfer_size = devpriv->adc_byte_count; 1270 1271 /* re-enable dma */ 1272 if ((async->events & COMEDI_CB_EOA) == 0) { 1273 set_dma_addr(devpriv->dma_chan, 1274 devpriv->dma_buffer_addr[devpriv->current_buffer]); 1275 set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size); 1276 enable_dma(devpriv->dma_chan); 1277 /* reenable conversions for das1600 mode, (stupid hardware) */ 1278 if (thisboard->size > 0x400 && devpriv->timer_mode == 0) { 1279 outb(0x00, dev->iobase + DAS1600_CONV); 1280 } 1281 } 1282 release_dma_lock(dma_flags); 1283 1284 spin_unlock_irqrestore(&dev->spinlock, spin_flags); 1285 1286 cfc_write_array_to_buffer(s, 1287 devpriv->dma_buffer[buffer_index], num_bytes); 1288 1289 cfc_handle_events(dev, s); 1290} 1291 1292static unsigned int das16_set_pacer(struct comedi_device *dev, unsigned int ns, 1293 int rounding_flags) 1294{ 1295 i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1), 1296 &(devpriv->divisor2), &ns, 1297 rounding_flags & TRIG_ROUND_MASK); 1298 1299 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 1300 i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2); 1301 i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2); 1302 1303 return ns; 1304} 1305 1306static void reg_dump(struct comedi_device *dev) 1307{ 1308 DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n"); 1309 DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX)); 1310 DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO)); 1311 DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS)); 1312 DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL)); 1313 DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER)); 1314 DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN)); 1315 DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n", 1316 inb(dev->iobase + DAS16_CNTR_CONTROL)); 1317 DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV)); 1318 DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST)); 1319 DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE)); 1320 DEBUG_PRINT("DAS1600_STATUS_B: %x\n", 1321 inb(dev->iobase + DAS1600_STATUS_B)); 1322} 1323 1324static int das16_probe(struct comedi_device *dev, struct comedi_devconfig *it) 1325{ 1326 int status; 1327 int diobits; 1328 1329 /* status is available on all boards */ 1330 1331 status = inb(dev->iobase + DAS16_STATUS); 1332 1333 if ((status & UNIPOLAR)) { 1334 devpriv->ai_unipolar = 1; 1335 } else { 1336 devpriv->ai_unipolar = 0; 1337 } 1338 1339 if ((status & DAS16_MUXBIT)) { 1340 devpriv->ai_singleended = 1; 1341 } else { 1342 devpriv->ai_singleended = 0; 1343 } 1344 1345 /* diobits indicates boards */ 1346 1347 diobits = inb(dev->iobase + DAS16_DIO) & 0xf0; 1348 1349 printk(" id bits are 0x%02x\n", diobits); 1350 if (thisboard->id != diobits) { 1351 printk(" requested board's id bits are 0x%x (ignore)\n", 1352 thisboard->id); 1353 } 1354 1355 return 0; 1356} 1357 1358static int das1600_mode_detect(struct comedi_device *dev) 1359{ 1360 int status = 0; 1361 1362 status = inb(dev->iobase + DAS1600_STATUS_B); 1363 1364 if (status & DAS1600_CLK_10MHZ) { 1365 devpriv->clockbase = 100; 1366 printk(" 10MHz pacer clock\n"); 1367 } else { 1368 devpriv->clockbase = 1000; 1369 printk(" 1MHz pacer clock\n"); 1370 } 1371 1372 reg_dump(dev); 1373 1374 return 0; 1375} 1376 1377/* 1378 * 1379 * Options list: 1380 * 0 I/O base 1381 * 1 IRQ 1382 * 2 DMA 1383 * 3 Clock speed (in MHz) 1384 */ 1385 1386static int das16_attach(struct comedi_device *dev, struct comedi_devconfig *it) 1387{ 1388 struct comedi_subdevice *s; 1389 int ret; 1390 unsigned int irq; 1391 unsigned long iobase; 1392 unsigned int dma_chan; 1393 int timer_mode; 1394 unsigned long flags; 1395 struct comedi_krange *user_ai_range, *user_ao_range; 1396 1397 iobase = it->options[0]; 1398#if 0 1399 irq = it->options[1]; 1400 timer_mode = it->options[8]; 1401#endif 1402 /* always use time_mode since using irq can drop samples while 1403 * waiting for dma done interrupt (due to hardware limitations) */ 1404 irq = 0; 1405 timer_mode = 1; 1406 if (timer_mode) 1407 irq = 0; 1408 1409 printk("comedi%d: das16:", dev->minor); 1410 1411 /* check that clock setting is valid */ 1412 if (it->options[3]) { 1413 if (it->options[3] != 0 && 1414 it->options[3] != 1 && it->options[3] != 10) { 1415 printk 1416 ("\n Invalid option. Master clock must be set to 1 or 10 (MHz)\n"); 1417 return -EINVAL; 1418 } 1419 } 1420 1421 ret = alloc_private(dev, sizeof(struct das16_private_struct)); 1422 if (ret < 0) 1423 return ret; 1424 1425 if (thisboard->size < 0x400) { 1426 printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size); 1427 if (!request_region(iobase, thisboard->size, "das16")) { 1428 printk(" I/O port conflict\n"); 1429 return -EIO; 1430 } 1431 } else { 1432 printk(" 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n", 1433 iobase, iobase + 0x0f, 1434 iobase + 0x400, 1435 iobase + 0x400 + (thisboard->size & 0x3ff)); 1436 if (!request_region(iobase, 0x10, "das16")) { 1437 printk(" I/O port conflict: 0x%04lx-0x%04lx\n", 1438 iobase, iobase + 0x0f); 1439 return -EIO; 1440 } 1441 if (!request_region(iobase + 0x400, thisboard->size & 0x3ff, 1442 "das16")) { 1443 release_region(iobase, 0x10); 1444 printk(" I/O port conflict: 0x%04lx-0x%04lx\n", 1445 iobase + 0x400, 1446 iobase + 0x400 + (thisboard->size & 0x3ff)); 1447 return -EIO; 1448 } 1449 } 1450 1451 dev->iobase = iobase; 1452 1453 /* probe id bits to make sure they are consistent */ 1454 if (das16_probe(dev, it)) { 1455 printk(" id bits do not match selected board, aborting\n"); 1456 return -EINVAL; 1457 } 1458 dev->board_name = thisboard->name; 1459 1460 /* get master clock speed */ 1461 if (thisboard->size < 0x400) { 1462 if (it->options[3]) 1463 devpriv->clockbase = 1000 / it->options[3]; 1464 else 1465 devpriv->clockbase = 1000; /* 1 MHz default */ 1466 } else { 1467 das1600_mode_detect(dev); 1468 } 1469 1470 /* now for the irq */ 1471 if (irq > 1 && irq < 8) { 1472 ret = request_irq(irq, das16_dma_interrupt, 0, "das16", dev); 1473 1474 if (ret < 0) 1475 return ret; 1476 dev->irq = irq; 1477 printk(" ( irq = %u )", irq); 1478 } else if (irq == 0) { 1479 printk(" ( no irq )"); 1480 } else { 1481 printk(" invalid irq\n"); 1482 return -EINVAL; 1483 } 1484 1485 /* initialize dma */ 1486 dma_chan = it->options[2]; 1487 if (dma_chan == 1 || dma_chan == 3) { 1488 /* allocate dma buffers */ 1489 int i; 1490 for (i = 0; i < 2; i++) { 1491 devpriv->dma_buffer[i] = pci_alloc_consistent(NULL, 1492 DAS16_DMA_SIZE, 1493 &devpriv-> 1494 dma_buffer_addr 1495 [i]); 1496 if (devpriv->dma_buffer[i] == NULL) 1497 return -ENOMEM; 1498 } 1499 if (request_dma(dma_chan, "das16")) { 1500 printk(" failed to allocate dma channel %i\n", 1501 dma_chan); 1502 return -EINVAL; 1503 } 1504 devpriv->dma_chan = dma_chan; 1505 flags = claim_dma_lock(); 1506 disable_dma(devpriv->dma_chan); 1507 set_dma_mode(devpriv->dma_chan, DMA_MODE_READ); 1508 release_dma_lock(flags); 1509 printk(" ( dma = %u)\n", dma_chan); 1510 } else if (dma_chan == 0) { 1511 printk(" ( no dma )\n"); 1512 } else { 1513 printk(" invalid dma channel\n"); 1514 return -EINVAL; 1515 } 1516 1517 /* get any user-defined input range */ 1518 if (thisboard->ai_pg == das16_pg_none && 1519 (it->options[4] || it->options[5])) { 1520 /* allocate single-range range table */ 1521 devpriv->user_ai_range_table = 1522 kmalloc(sizeof(struct comedi_lrange) + 1523 sizeof(struct comedi_krange), GFP_KERNEL); 1524 /* initialize ai range */ 1525 devpriv->user_ai_range_table->length = 1; 1526 user_ai_range = devpriv->user_ai_range_table->range; 1527 user_ai_range->min = it->options[4]; 1528 user_ai_range->max = it->options[5]; 1529 user_ai_range->flags = UNIT_volt; 1530 } 1531 /* get any user-defined output range */ 1532 if (it->options[6] || it->options[7]) { 1533 /* allocate single-range range table */ 1534 devpriv->user_ao_range_table = 1535 kmalloc(sizeof(struct comedi_lrange) + 1536 sizeof(struct comedi_krange), GFP_KERNEL); 1537 /* initialize ao range */ 1538 devpriv->user_ao_range_table->length = 1; 1539 user_ao_range = devpriv->user_ao_range_table->range; 1540 user_ao_range->min = it->options[6]; 1541 user_ao_range->max = it->options[7]; 1542 user_ao_range->flags = UNIT_volt; 1543 } 1544 1545 if (timer_mode) { 1546 init_timer(&(devpriv->timer)); 1547 devpriv->timer.function = das16_timer_interrupt; 1548 devpriv->timer.data = (unsigned long)dev; 1549 } 1550 devpriv->timer_mode = timer_mode ? 1 : 0; 1551 1552 ret = alloc_subdevices(dev, 5); 1553 if (ret < 0) 1554 return ret; 1555 1556 s = dev->subdevices + 0; 1557 dev->read_subdev = s; 1558 /* ai */ 1559 if (thisboard->ai) { 1560 s->type = COMEDI_SUBD_AI; 1561 s->subdev_flags = SDF_READABLE | SDF_CMD_READ; 1562 if (devpriv->ai_singleended) { 1563 s->n_chan = 16; 1564 s->len_chanlist = 16; 1565 s->subdev_flags |= SDF_GROUND; 1566 } else { 1567 s->n_chan = 8; 1568 s->len_chanlist = 8; 1569 s->subdev_flags |= SDF_DIFF; 1570 } 1571 s->maxdata = (1 << thisboard->ai_nbits) - 1; 1572 if (devpriv->user_ai_range_table) { /* user defined ai range */ 1573 s->range_table = devpriv->user_ai_range_table; 1574 } else if (devpriv->ai_unipolar) { 1575 s->range_table = das16_ai_uni_lranges[thisboard->ai_pg]; 1576 } else { 1577 s->range_table = das16_ai_bip_lranges[thisboard->ai_pg]; 1578 } 1579 s->insn_read = thisboard->ai; 1580 s->do_cmdtest = das16_cmd_test; 1581 s->do_cmd = das16_cmd_exec; 1582 s->cancel = das16_cancel; 1583 s->munge = das16_ai_munge; 1584 } else { 1585 s->type = COMEDI_SUBD_UNUSED; 1586 } 1587 1588 s = dev->subdevices + 1; 1589 /* ao */ 1590 if (thisboard->ao) { 1591 s->type = COMEDI_SUBD_AO; 1592 s->subdev_flags = SDF_WRITABLE; 1593 s->n_chan = 2; 1594 s->maxdata = (1 << thisboard->ao_nbits) - 1; 1595 if (devpriv->user_ao_range_table) { /* user defined ao range */ 1596 s->range_table = devpriv->user_ao_range_table; 1597 } else { 1598 s->range_table = &range_unknown; 1599 } 1600 s->insn_write = thisboard->ao; 1601 } else { 1602 s->type = COMEDI_SUBD_UNUSED; 1603 } 1604 1605 s = dev->subdevices + 2; 1606 /* di */ 1607 if (thisboard->di) { 1608 s->type = COMEDI_SUBD_DI; 1609 s->subdev_flags = SDF_READABLE; 1610 s->n_chan = 4; 1611 s->maxdata = 1; 1612 s->range_table = &range_digital; 1613 s->insn_bits = thisboard->di; 1614 } else { 1615 s->type = COMEDI_SUBD_UNUSED; 1616 } 1617 1618 s = dev->subdevices + 3; 1619 /* do */ 1620 if (thisboard->do_) { 1621 s->type = COMEDI_SUBD_DO; 1622 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 1623 s->n_chan = 4; 1624 s->maxdata = 1; 1625 s->range_table = &range_digital; 1626 s->insn_bits = thisboard->do_; 1627 /* initialize digital output lines */ 1628 outb(s->state, dev->iobase + DAS16_DIO); 1629 } else { 1630 s->type = COMEDI_SUBD_UNUSED; 1631 } 1632 1633 s = dev->subdevices + 4; 1634 /* 8255 */ 1635 if (thisboard->i8255_offset != 0) { 1636 subdev_8255_init(dev, s, NULL, (dev->iobase + 1637 thisboard->i8255_offset)); 1638 } else { 1639 s->type = COMEDI_SUBD_UNUSED; 1640 } 1641 1642 das16_reset(dev); 1643 /* set the interrupt level */ 1644 devpriv->control_state = DAS16_IRQ(dev->irq); 1645 outb(devpriv->control_state, dev->iobase + DAS16_CONTROL); 1646 1647 /* turn on das1600 mode if available */ 1648 if (thisboard->size > 0x400) { 1649 outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE); 1650 outb(0, dev->iobase + DAS1600_CONV); 1651 outb(0, dev->iobase + DAS1600_BURST); 1652 } 1653 1654 return 0; 1655} 1656 1657static int das16_detach(struct comedi_device *dev) 1658{ 1659 printk("comedi%d: das16: remove\n", dev->minor); 1660 1661 das16_reset(dev); 1662 1663 if (dev->subdevices) 1664 subdev_8255_cleanup(dev, dev->subdevices + 4); 1665 1666 if (devpriv) { 1667 int i; 1668 for (i = 0; i < 2; i++) { 1669 if (devpriv->dma_buffer[i]) 1670 pci_free_consistent(NULL, DAS16_DMA_SIZE, 1671 devpriv->dma_buffer[i], 1672 devpriv-> 1673 dma_buffer_addr[i]); 1674 } 1675 if (devpriv->dma_chan) 1676 free_dma(devpriv->dma_chan); 1677 if (devpriv->user_ai_range_table) 1678 kfree(devpriv->user_ai_range_table); 1679 if (devpriv->user_ao_range_table) 1680 kfree(devpriv->user_ao_range_table); 1681 } 1682 1683 if (dev->irq) 1684 free_irq(dev->irq, dev); 1685 1686 if (dev->iobase) { 1687 if (thisboard->size < 0x400) { 1688 release_region(dev->iobase, thisboard->size); 1689 } else { 1690 release_region(dev->iobase, 0x10); 1691 release_region(dev->iobase + 0x400, 1692 thisboard->size & 0x3ff); 1693 } 1694 } 1695 1696 return 0; 1697} 1698 1699COMEDI_INITCLEANUP(driver_das16); 1700 1701/* utility function that suggests a dma transfer size in bytes */ 1702static unsigned int das16_suggest_transfer_size(struct comedi_device *dev, 1703 struct comedi_cmd cmd) 1704{ 1705 unsigned int size; 1706 unsigned int freq; 1707 1708 /* if we are using timer interrupt, we don't care how long it 1709 * will take to complete transfer since it will be interrupted 1710 * by timer interrupt */ 1711 if (devpriv->timer_mode) 1712 return DAS16_DMA_SIZE; 1713 1714 /* otherwise, we are relying on dma terminal count interrupt, 1715 * so pick a reasonable size */ 1716 if (cmd.convert_src == TRIG_TIMER) 1717 freq = 1000000000 / cmd.convert_arg; 1718 else if (cmd.scan_begin_src == TRIG_TIMER) 1719 freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len; 1720 /* return some default value */ 1721 else 1722 freq = 0xffffffff; 1723 1724 if (cmd.flags & TRIG_WAKE_EOS) { 1725 size = sample_size * cmd.chanlist_len; 1726 } else { 1727 /* make buffer fill in no more than 1/3 second */ 1728 size = (freq / 3) * sample_size; 1729 } 1730 1731 /* set a minimum and maximum size allowed */ 1732 if (size > DAS16_DMA_SIZE) 1733 size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size; 1734 else if (size < sample_size) 1735 size = sample_size; 1736 1737 if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count) 1738 size = devpriv->adc_byte_count; 1739 1740 return size; 1741} 1742 1743static void das16_ai_munge(struct comedi_device *dev, 1744 struct comedi_subdevice *s, void *array, 1745 unsigned int num_bytes, 1746 unsigned int start_chan_index) 1747{ 1748 unsigned int i, num_samples = num_bytes / sizeof(short); 1749 short *data = array; 1750 1751 for (i = 0; i < num_samples; i++) { 1752 data[i] = le16_to_cpu(data[i]); 1753 if (thisboard->ai_nbits == 12) { 1754 data[i] = (data[i] >> 4) & 0xfff; 1755 } 1756 } 1757} 1758