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