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