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