das1800.c revision c9695093017d71a0571df7140feacfbf5ef4cdd4
1/* 2 comedi/drivers/das1800.c 3 Driver for Keitley das1700/das1800 series boards 4 Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net> 5 6 COMEDI - Linux Control and Measurement Device Interface 7 Copyright (C) 2000 David A. Schleef <ds@schleef.org> 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18*/ 19/* 20Driver: das1800 21Description: Keithley Metrabyte DAS1800 (& compatibles) 22Author: Frank Mori Hess <fmhess@users.sourceforge.net> 23Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st), 24 DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao), 25 DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da), 26 DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da), 27 DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st), 28 DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc), 29 DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st), 30 DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr), 31 DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc), 32 DAS-1802AO (das-1802ao) 33Status: works 34 35The waveform analog output on the 'ao' cards is not supported. 36If you need it, send me (Frank Hess) an email. 37 38Configuration options: 39 [0] - I/O port base address 40 [1] - IRQ (optional, required for timed or externally triggered conversions) 41 [2] - DMA0 (optional, requires irq) 42 [3] - DMA1 (optional, requires irq and dma0) 43*/ 44/* 45 46This driver supports the following Keithley boards: 47 48das-1701st 49das-1701st-da 50das-1701ao 51das-1702st 52das-1702st-da 53das-1702hr 54das-1702hr-da 55das-1702ao 56das-1801st 57das-1801st-da 58das-1801hc 59das-1801ao 60das-1802st 61das-1802st-da 62das-1802hr 63das-1802hr-da 64das-1802hc 65das-1802ao 66 67Options: 68 [0] - base io address 69 [1] - irq (optional, required for timed or externally triggered conversions) 70 [2] - dma0 (optional, requires irq) 71 [3] - dma1 (optional, requires irq and dma0) 72 73irq can be omitted, although the cmd interface will not work without it. 74 75analog input cmd triggers supported: 76 start_src: TRIG_NOW | TRIG_EXT 77 scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT 78 scan_end_src: TRIG_COUNT 79 convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW) 80 stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE 81 82scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's 83'burst mode' which limits the valid conversion time to 64 microseconds 84(convert_arg <= 64000). This limitation does not apply if scan_begin_src 85is TRIG_FOLLOW. 86 87NOTES: 88Only the DAS-1801ST has been tested by me. 89Unipolar and bipolar ranges cannot be mixed in the channel/gain list. 90 91TODO: 92 Make it automatically allocate irq and dma channels if they are not specified 93 Add support for analog out on 'ao' cards 94 read insn for analog out 95*/ 96 97#include <linux/module.h> 98#include <linux/interrupt.h> 99#include <linux/slab.h> 100#include <linux/io.h> 101#include "../comedidev.h" 102 103#include <asm/dma.h> 104 105#include "8253.h" 106#include "comedi_fc.h" 107 108/* misc. defines */ 109#define DAS1800_SIZE 16 /* uses 16 io addresses */ 110#define FIFO_SIZE 1024 /* 1024 sample fifo */ 111#define UNIPOLAR 0x4 /* bit that determines whether input range is uni/bipolar */ 112#define DMA_BUF_SIZE 0x1ff00 /* size in bytes of dma buffers */ 113 114/* Registers for the das1800 */ 115#define DAS1800_FIFO 0x0 116#define DAS1800_QRAM 0x0 117#define DAS1800_DAC 0x0 118#define DAS1800_SELECT 0x2 119#define ADC 0x0 120#define QRAM 0x1 121#define DAC(a) (0x2 + a) 122#define DAS1800_DIGITAL 0x3 123#define DAS1800_CONTROL_A 0x4 124#define FFEN 0x1 125#define CGEN 0x4 126#define CGSL 0x8 127#define TGEN 0x10 128#define TGSL 0x20 129#define ATEN 0x80 130#define DAS1800_CONTROL_B 0x5 131#define DMA_CH5 0x1 132#define DMA_CH6 0x2 133#define DMA_CH7 0x3 134#define DMA_CH5_CH6 0x5 135#define DMA_CH6_CH7 0x6 136#define DMA_CH7_CH5 0x7 137#define DMA_ENABLED 0x3 /* mask used to determine if dma is enabled */ 138#define DMA_DUAL 0x4 139#define IRQ3 0x8 140#define IRQ5 0x10 141#define IRQ7 0x18 142#define IRQ10 0x28 143#define IRQ11 0x30 144#define IRQ15 0x38 145#define FIMD 0x40 146#define DAS1800_CONTROL_C 0X6 147#define IPCLK 0x1 148#define XPCLK 0x3 149#define BMDE 0x4 150#define CMEN 0x8 151#define UQEN 0x10 152#define SD 0x40 153#define UB 0x80 154#define DAS1800_STATUS 0x7 155/* bits that prevent interrupt status bits (and CVEN) from being cleared on write */ 156#define CLEAR_INTR_MASK (CVEN_MASK | 0x1f) 157#define INT 0x1 158#define DMATC 0x2 159#define CT0TC 0x8 160#define OVF 0x10 161#define FHF 0x20 162#define FNE 0x40 163#define CVEN_MASK 0x40 /* masks CVEN on write */ 164#define CVEN 0x80 165#define DAS1800_BURST_LENGTH 0x8 166#define DAS1800_BURST_RATE 0x9 167#define DAS1800_QRAM_ADDRESS 0xa 168#define DAS1800_COUNTER 0xc 169 170#define IOBASE2 0x400 /* offset of additional ioports used on 'ao' cards */ 171 172enum { 173 das1701st, das1701st_da, das1702st, das1702st_da, das1702hr, 174 das1702hr_da, 175 das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da, 176 das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao 177}; 178 179/* analog input ranges */ 180static const struct comedi_lrange range_ai_das1801 = { 181 8, { 182 BIP_RANGE(5), 183 BIP_RANGE(1), 184 BIP_RANGE(0.1), 185 BIP_RANGE(0.02), 186 UNI_RANGE(5), 187 UNI_RANGE(1), 188 UNI_RANGE(0.1), 189 UNI_RANGE(0.02) 190 } 191}; 192 193static const struct comedi_lrange range_ai_das1802 = { 194 8, { 195 BIP_RANGE(10), 196 BIP_RANGE(5), 197 BIP_RANGE(2.5), 198 BIP_RANGE(1.25), 199 UNI_RANGE(10), 200 UNI_RANGE(5), 201 UNI_RANGE(2.5), 202 UNI_RANGE(1.25) 203 } 204}; 205 206struct das1800_board { 207 const char *name; 208 int ai_speed; /* max conversion period in nanoseconds */ 209 int resolution; /* bits of ai resolution */ 210 int qram_len; /* length of card's channel / gain queue */ 211 int common; /* supports AREF_COMMON flag */ 212 int do_n_chan; /* number of digital output channels */ 213 int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */ 214 int ao_n_chan; /* number of analog out channels */ 215 const struct comedi_lrange *range_ai; /* available input ranges */ 216}; 217 218/* Warning: the maximum conversion speeds listed below are 219 * not always achievable depending on board setup (see 220 * user manual.) 221 */ 222static const struct das1800_board das1800_boards[] = { 223 { 224 .name = "das-1701st", 225 .ai_speed = 6250, 226 .resolution = 12, 227 .qram_len = 256, 228 .common = 1, 229 .do_n_chan = 4, 230 .ao_ability = 0, 231 .ao_n_chan = 0, 232 .range_ai = &range_ai_das1801, 233 }, 234 { 235 .name = "das-1701st-da", 236 .ai_speed = 6250, 237 .resolution = 12, 238 .qram_len = 256, 239 .common = 1, 240 .do_n_chan = 4, 241 .ao_ability = 1, 242 .ao_n_chan = 4, 243 .range_ai = &range_ai_das1801, 244 }, 245 { 246 .name = "das-1702st", 247 .ai_speed = 6250, 248 .resolution = 12, 249 .qram_len = 256, 250 .common = 1, 251 .do_n_chan = 4, 252 .ao_ability = 0, 253 .ao_n_chan = 0, 254 .range_ai = &range_ai_das1802, 255 }, 256 { 257 .name = "das-1702st-da", 258 .ai_speed = 6250, 259 .resolution = 12, 260 .qram_len = 256, 261 .common = 1, 262 .do_n_chan = 4, 263 .ao_ability = 1, 264 .ao_n_chan = 4, 265 .range_ai = &range_ai_das1802, 266 }, 267 { 268 .name = "das-1702hr", 269 .ai_speed = 20000, 270 .resolution = 16, 271 .qram_len = 256, 272 .common = 1, 273 .do_n_chan = 4, 274 .ao_ability = 0, 275 .ao_n_chan = 0, 276 .range_ai = &range_ai_das1802, 277 }, 278 { 279 .name = "das-1702hr-da", 280 .ai_speed = 20000, 281 .resolution = 16, 282 .qram_len = 256, 283 .common = 1, 284 .do_n_chan = 4, 285 .ao_ability = 1, 286 .ao_n_chan = 2, 287 .range_ai = &range_ai_das1802, 288 }, 289 { 290 .name = "das-1701ao", 291 .ai_speed = 6250, 292 .resolution = 12, 293 .qram_len = 256, 294 .common = 1, 295 .do_n_chan = 4, 296 .ao_ability = 2, 297 .ao_n_chan = 2, 298 .range_ai = &range_ai_das1801, 299 }, 300 { 301 .name = "das-1702ao", 302 .ai_speed = 6250, 303 .resolution = 12, 304 .qram_len = 256, 305 .common = 1, 306 .do_n_chan = 4, 307 .ao_ability = 2, 308 .ao_n_chan = 2, 309 .range_ai = &range_ai_das1802, 310 }, 311 { 312 .name = "das-1801st", 313 .ai_speed = 3000, 314 .resolution = 12, 315 .qram_len = 256, 316 .common = 1, 317 .do_n_chan = 4, 318 .ao_ability = 0, 319 .ao_n_chan = 0, 320 .range_ai = &range_ai_das1801, 321 }, 322 { 323 .name = "das-1801st-da", 324 .ai_speed = 3000, 325 .resolution = 12, 326 .qram_len = 256, 327 .common = 1, 328 .do_n_chan = 4, 329 .ao_ability = 0, 330 .ao_n_chan = 4, 331 .range_ai = &range_ai_das1801, 332 }, 333 { 334 .name = "das-1802st", 335 .ai_speed = 3000, 336 .resolution = 12, 337 .qram_len = 256, 338 .common = 1, 339 .do_n_chan = 4, 340 .ao_ability = 0, 341 .ao_n_chan = 0, 342 .range_ai = &range_ai_das1802, 343 }, 344 { 345 .name = "das-1802st-da", 346 .ai_speed = 3000, 347 .resolution = 12, 348 .qram_len = 256, 349 .common = 1, 350 .do_n_chan = 4, 351 .ao_ability = 1, 352 .ao_n_chan = 4, 353 .range_ai = &range_ai_das1802, 354 }, 355 { 356 .name = "das-1802hr", 357 .ai_speed = 10000, 358 .resolution = 16, 359 .qram_len = 256, 360 .common = 1, 361 .do_n_chan = 4, 362 .ao_ability = 0, 363 .ao_n_chan = 0, 364 .range_ai = &range_ai_das1802, 365 }, 366 { 367 .name = "das-1802hr-da", 368 .ai_speed = 10000, 369 .resolution = 16, 370 .qram_len = 256, 371 .common = 1, 372 .do_n_chan = 4, 373 .ao_ability = 1, 374 .ao_n_chan = 2, 375 .range_ai = &range_ai_das1802, 376 }, 377 { 378 .name = "das-1801hc", 379 .ai_speed = 3000, 380 .resolution = 12, 381 .qram_len = 64, 382 .common = 0, 383 .do_n_chan = 8, 384 .ao_ability = 1, 385 .ao_n_chan = 2, 386 .range_ai = &range_ai_das1801, 387 }, 388 { 389 .name = "das-1802hc", 390 .ai_speed = 3000, 391 .resolution = 12, 392 .qram_len = 64, 393 .common = 0, 394 .do_n_chan = 8, 395 .ao_ability = 1, 396 .ao_n_chan = 2, 397 .range_ai = &range_ai_das1802, 398 }, 399 { 400 .name = "das-1801ao", 401 .ai_speed = 3000, 402 .resolution = 12, 403 .qram_len = 256, 404 .common = 1, 405 .do_n_chan = 4, 406 .ao_ability = 2, 407 .ao_n_chan = 2, 408 .range_ai = &range_ai_das1801, 409 }, 410 { 411 .name = "das-1802ao", 412 .ai_speed = 3000, 413 .resolution = 12, 414 .qram_len = 256, 415 .common = 1, 416 .do_n_chan = 4, 417 .ao_ability = 2, 418 .ao_n_chan = 2, 419 .range_ai = &range_ai_das1802, 420 }, 421}; 422 423struct das1800_private { 424 volatile unsigned int count; /* number of data points left to be taken */ 425 unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */ 426 unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */ 427 int irq_dma_bits; /* bits for control register b */ 428 /* dma bits for control register b, stored so that dma can be 429 * turned on and off */ 430 int dma_bits; 431 unsigned int dma0; /* dma channels used */ 432 unsigned int dma1; 433 volatile unsigned int dma_current; /* dma channel currently in use */ 434 uint16_t *ai_buf0; /* pointers to dma buffers */ 435 uint16_t *ai_buf1; 436 uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */ 437 unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */ 438 unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */ 439 unsigned short ao_update_bits; /* remembers the last write to the 440 * 'update' dac */ 441}; 442 443/* analog out range for 'ao' boards */ 444/* 445static const struct comedi_lrange range_ao_2 = { 446 2, { 447 BIP_RANGE(10), 448 BIP_RANGE(5) 449 } 450}; 451*/ 452 453static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, 454 uint16_t sample) 455{ 456 const struct das1800_board *thisboard = comedi_board(dev); 457 458 sample += 1 << (thisboard->resolution - 1); 459 return sample; 460} 461 462static void munge_data(struct comedi_device *dev, uint16_t *array, 463 unsigned int num_elements) 464{ 465 unsigned int i; 466 int unipolar; 467 468 /* see if card is using a unipolar or bipolar range so we can munge data correctly */ 469 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 470 471 /* convert to unsigned type if we are in a bipolar mode */ 472 if (!unipolar) { 473 for (i = 0; i < num_elements; i++) 474 array[i] = munge_bipolar_sample(dev, array[i]); 475 } 476} 477 478static void das1800_handle_fifo_half_full(struct comedi_device *dev, 479 struct comedi_subdevice *s) 480{ 481 struct das1800_private *devpriv = dev->private; 482 int numPoints = 0; /* number of points to read */ 483 struct comedi_cmd *cmd = &s->async->cmd; 484 485 numPoints = FIFO_SIZE / 2; 486 /* if we only need some of the points */ 487 if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints) 488 numPoints = devpriv->count; 489 insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints); 490 munge_data(dev, devpriv->ai_buf0, numPoints); 491 cfc_write_array_to_buffer(s, devpriv->ai_buf0, 492 numPoints * sizeof(devpriv->ai_buf0[0])); 493 if (cmd->stop_src == TRIG_COUNT) 494 devpriv->count -= numPoints; 495 return; 496} 497 498static void das1800_handle_fifo_not_empty(struct comedi_device *dev, 499 struct comedi_subdevice *s) 500{ 501 struct das1800_private *devpriv = dev->private; 502 unsigned short dpnt; 503 int unipolar; 504 struct comedi_cmd *cmd = &s->async->cmd; 505 506 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 507 508 while (inb(dev->iobase + DAS1800_STATUS) & FNE) { 509 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) 510 break; 511 dpnt = inw(dev->iobase + DAS1800_FIFO); 512 /* convert to unsigned type if we are in a bipolar mode */ 513 if (!unipolar) 514 ; 515 dpnt = munge_bipolar_sample(dev, dpnt); 516 cfc_write_to_buffer(s, dpnt); 517 if (cmd->stop_src == TRIG_COUNT) 518 devpriv->count--; 519 } 520 521 return; 522} 523 524/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). 525 * Assumes dma lock is held */ 526static void das1800_flush_dma_channel(struct comedi_device *dev, 527 struct comedi_subdevice *s, 528 unsigned int channel, uint16_t *buffer) 529{ 530 struct das1800_private *devpriv = dev->private; 531 unsigned int num_bytes, num_samples; 532 struct comedi_cmd *cmd = &s->async->cmd; 533 534 disable_dma(channel); 535 536 /* clear flip-flop to make sure 2-byte registers 537 * get set correctly */ 538 clear_dma_ff(channel); 539 540 /* figure out how many points to read */ 541 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); 542 num_samples = num_bytes / sizeof(short); 543 544 /* if we only need some of the points */ 545 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) 546 num_samples = devpriv->count; 547 548 munge_data(dev, buffer, num_samples); 549 cfc_write_array_to_buffer(s, buffer, num_bytes); 550 if (s->async->cmd.stop_src == TRIG_COUNT) 551 devpriv->count -= num_samples; 552 553 return; 554} 555 556/* flushes remaining data from board when external trigger has stopped acquisition 557 * and we are using dma transfers */ 558static void das1800_flush_dma(struct comedi_device *dev, 559 struct comedi_subdevice *s) 560{ 561 struct das1800_private *devpriv = dev->private; 562 unsigned long flags; 563 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 564 565 flags = claim_dma_lock(); 566 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 567 devpriv->dma_current_buf); 568 569 if (dual_dma) { 570 /* switch to other channel and flush it */ 571 if (devpriv->dma_current == devpriv->dma0) { 572 devpriv->dma_current = devpriv->dma1; 573 devpriv->dma_current_buf = devpriv->ai_buf1; 574 } else { 575 devpriv->dma_current = devpriv->dma0; 576 devpriv->dma_current_buf = devpriv->ai_buf0; 577 } 578 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 579 devpriv->dma_current_buf); 580 } 581 582 release_dma_lock(flags); 583 584 /* get any remaining samples in fifo */ 585 das1800_handle_fifo_not_empty(dev, s); 586 587 return; 588} 589 590static void das1800_handle_dma(struct comedi_device *dev, 591 struct comedi_subdevice *s, unsigned int status) 592{ 593 struct das1800_private *devpriv = dev->private; 594 unsigned long flags; 595 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 596 597 flags = claim_dma_lock(); 598 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 599 devpriv->dma_current_buf); 600 /* re-enable dma channel */ 601 set_dma_addr(devpriv->dma_current, 602 virt_to_bus(devpriv->dma_current_buf)); 603 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); 604 enable_dma(devpriv->dma_current); 605 release_dma_lock(flags); 606 607 if (status & DMATC) { 608 /* clear DMATC interrupt bit */ 609 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); 610 /* switch dma channels for next time, if appropriate */ 611 if (dual_dma) { 612 /* read data from the other channel next time */ 613 if (devpriv->dma_current == devpriv->dma0) { 614 devpriv->dma_current = devpriv->dma1; 615 devpriv->dma_current_buf = devpriv->ai_buf1; 616 } else { 617 devpriv->dma_current = devpriv->dma0; 618 devpriv->dma_current_buf = devpriv->ai_buf0; 619 } 620 } 621 } 622 623 return; 624} 625 626static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 627{ 628 struct das1800_private *devpriv = dev->private; 629 630 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ 631 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ 632 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ 633 if (devpriv->dma0) 634 disable_dma(devpriv->dma0); 635 if (devpriv->dma1) 636 disable_dma(devpriv->dma1); 637 return 0; 638} 639 640/* the guts of the interrupt handler, that is shared with das1800_ai_poll */ 641static void das1800_ai_handler(struct comedi_device *dev) 642{ 643 struct das1800_private *devpriv = dev->private; 644 struct comedi_subdevice *s = dev->read_subdev; 645 struct comedi_async *async = s->async; 646 struct comedi_cmd *cmd = &async->cmd; 647 unsigned int status = inb(dev->iobase + DAS1800_STATUS); 648 649 async->events = 0; 650 /* select adc for base address + 0 */ 651 outb(ADC, dev->iobase + DAS1800_SELECT); 652 /* dma buffer full */ 653 if (devpriv->irq_dma_bits & DMA_ENABLED) { 654 /* look for data from dma transfer even if dma terminal count hasn't happened yet */ 655 das1800_handle_dma(dev, s, status); 656 } else if (status & FHF) { /* if fifo half full */ 657 das1800_handle_fifo_half_full(dev, s); 658 } else if (status & FNE) { /* if fifo not empty */ 659 das1800_handle_fifo_not_empty(dev, s); 660 } 661 662 async->events |= COMEDI_CB_BLOCK; 663 /* if the card's fifo has overflowed */ 664 if (status & OVF) { 665 /* clear OVF interrupt bit */ 666 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); 667 comedi_error(dev, "DAS1800 FIFO overflow"); 668 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 669 cfc_handle_events(dev, s); 670 return; 671 } 672 /* stop taking data if appropriate */ 673 /* stop_src TRIG_EXT */ 674 if (status & CT0TC) { 675 /* clear CT0TC interrupt bit */ 676 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS); 677 /* make sure we get all remaining data from board before quitting */ 678 if (devpriv->irq_dma_bits & DMA_ENABLED) 679 das1800_flush_dma(dev, s); 680 else 681 das1800_handle_fifo_not_empty(dev, s); 682 async->events |= COMEDI_CB_EOA; 683 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */ 684 async->events |= COMEDI_CB_EOA; 685 } 686 687 cfc_handle_events(dev, s); 688} 689 690static int das1800_ai_poll(struct comedi_device *dev, 691 struct comedi_subdevice *s) 692{ 693 unsigned long flags; 694 695 /* prevent race with interrupt handler */ 696 spin_lock_irqsave(&dev->spinlock, flags); 697 das1800_ai_handler(dev); 698 spin_unlock_irqrestore(&dev->spinlock, flags); 699 700 return s->async->buf_write_count - s->async->buf_read_count; 701} 702 703static irqreturn_t das1800_interrupt(int irq, void *d) 704{ 705 struct comedi_device *dev = d; 706 unsigned int status; 707 708 if (!dev->attached) { 709 comedi_error(dev, "premature interrupt"); 710 return IRQ_HANDLED; 711 } 712 713 /* Prevent race with das1800_ai_poll() on multi processor systems. 714 * Also protects indirect addressing in das1800_ai_handler */ 715 spin_lock(&dev->spinlock); 716 status = inb(dev->iobase + DAS1800_STATUS); 717 718 /* if interrupt was not caused by das-1800 */ 719 if (!(status & INT)) { 720 spin_unlock(&dev->spinlock); 721 return IRQ_NONE; 722 } 723 /* clear the interrupt status bit INT */ 724 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); 725 /* handle interrupt */ 726 das1800_ai_handler(dev); 727 728 spin_unlock(&dev->spinlock); 729 return IRQ_HANDLED; 730} 731 732/* converts requested conversion timing to timing compatible with 733 * hardware, used only when card is in 'burst mode' 734 */ 735static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode) 736{ 737 unsigned int micro_sec; 738 739 /* in burst mode, the maximum conversion time is 64 microseconds */ 740 if (convert_arg > 64000) 741 convert_arg = 64000; 742 743 /* the conversion time must be an integral number of microseconds */ 744 switch (round_mode) { 745 case TRIG_ROUND_NEAREST: 746 default: 747 micro_sec = (convert_arg + 500) / 1000; 748 break; 749 case TRIG_ROUND_DOWN: 750 micro_sec = convert_arg / 1000; 751 break; 752 case TRIG_ROUND_UP: 753 micro_sec = (convert_arg - 1) / 1000 + 1; 754 break; 755 } 756 757 /* return number of nanoseconds */ 758 return micro_sec * 1000; 759} 760 761/* test analog input cmd */ 762static int das1800_ai_do_cmdtest(struct comedi_device *dev, 763 struct comedi_subdevice *s, 764 struct comedi_cmd *cmd) 765{ 766 const struct das1800_board *thisboard = comedi_board(dev); 767 struct das1800_private *devpriv = dev->private; 768 int err = 0; 769 unsigned int tmp_arg; 770 int i; 771 int unipolar; 772 773 /* Step 1 : check if triggers are trivially valid */ 774 775 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); 776 err |= cfc_check_trigger_src(&cmd->scan_begin_src, 777 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT); 778 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); 779 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 780 err |= cfc_check_trigger_src(&cmd->stop_src, 781 TRIG_COUNT | TRIG_EXT | TRIG_NONE); 782 783 if (err) 784 return 1; 785 786 /* Step 2a : make sure trigger sources are unique */ 787 788 err |= cfc_check_trigger_is_unique(cmd->start_src); 789 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); 790 err |= cfc_check_trigger_is_unique(cmd->convert_src); 791 err |= cfc_check_trigger_is_unique(cmd->stop_src); 792 793 /* Step 2b : and mutually compatible */ 794 795 if (cmd->scan_begin_src != TRIG_FOLLOW && 796 cmd->convert_src != TRIG_TIMER) 797 err |= -EINVAL; 798 799 if (err) 800 return 2; 801 802 /* Step 3: check if arguments are trivially valid */ 803 804 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 805 806 if (cmd->convert_src == TRIG_TIMER) 807 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 808 thisboard->ai_speed); 809 810 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); 811 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 812 813 switch (cmd->stop_src) { 814 case TRIG_COUNT: 815 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); 816 break; 817 case TRIG_NONE: 818 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 819 break; 820 default: 821 break; 822 } 823 824 if (err) 825 return 3; 826 827 /* step 4: fix up any arguments */ 828 829 if (cmd->convert_src == TRIG_TIMER) { 830 /* if we are not in burst mode */ 831 if (cmd->scan_begin_src == TRIG_FOLLOW) { 832 tmp_arg = cmd->convert_arg; 833 /* calculate counter values that give desired timing */ 834 i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ, 835 &devpriv->divisor1, 836 &devpriv->divisor2, 837 &cmd->convert_arg, 838 cmd->flags); 839 if (tmp_arg != cmd->convert_arg) 840 err++; 841 } 842 /* if we are in burst mode */ 843 else { 844 /* check that convert_arg is compatible */ 845 tmp_arg = cmd->convert_arg; 846 cmd->convert_arg = 847 burst_convert_arg(cmd->convert_arg, 848 cmd->flags & TRIG_ROUND_MASK); 849 if (tmp_arg != cmd->convert_arg) 850 err++; 851 852 if (cmd->scan_begin_src == TRIG_TIMER) { 853 /* if scans are timed faster than conversion rate allows */ 854 if (cmd->convert_arg * cmd->chanlist_len > 855 cmd->scan_begin_arg) { 856 cmd->scan_begin_arg = 857 cmd->convert_arg * 858 cmd->chanlist_len; 859 err++; 860 } 861 tmp_arg = cmd->scan_begin_arg; 862 /* calculate counter values that give desired timing */ 863 i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ, 864 &devpriv->divisor1, 865 &devpriv->divisor2, 866 &cmd->scan_begin_arg, 867 cmd->flags); 868 if (tmp_arg != cmd->scan_begin_arg) 869 err++; 870 } 871 } 872 } 873 874 if (err) 875 return 4; 876 877 /* make sure user is not trying to mix unipolar and bipolar ranges */ 878 if (cmd->chanlist) { 879 unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR; 880 for (i = 1; i < cmd->chanlist_len; i++) { 881 if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) { 882 comedi_error(dev, 883 "unipolar and bipolar ranges cannot be mixed in the chanlist"); 884 err++; 885 break; 886 } 887 } 888 } 889 890 if (err) 891 return 5; 892 893 return 0; 894} 895 896/* returns appropriate bits for control register a, depending on command */ 897static int control_a_bits(const struct comedi_cmd *cmd) 898{ 899 int control_a; 900 901 control_a = FFEN; /* enable fifo */ 902 if (cmd->stop_src == TRIG_EXT) 903 control_a |= ATEN; 904 switch (cmd->start_src) { 905 case TRIG_EXT: 906 control_a |= TGEN | CGSL; 907 break; 908 case TRIG_NOW: 909 control_a |= CGEN; 910 break; 911 default: 912 break; 913 } 914 915 return control_a; 916} 917 918/* returns appropriate bits for control register c, depending on command */ 919static int control_c_bits(const struct comedi_cmd *cmd) 920{ 921 int control_c; 922 int aref; 923 924 /* set clock source to internal or external, select analog reference, 925 * select unipolar / bipolar 926 */ 927 aref = CR_AREF(cmd->chanlist[0]); 928 control_c = UQEN; /* enable upper qram addresses */ 929 if (aref != AREF_DIFF) 930 control_c |= SD; 931 if (aref == AREF_COMMON) 932 control_c |= CMEN; 933 /* if a unipolar range was selected */ 934 if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR) 935 control_c |= UB; 936 switch (cmd->scan_begin_src) { 937 case TRIG_FOLLOW: /* not in burst mode */ 938 switch (cmd->convert_src) { 939 case TRIG_TIMER: 940 /* trig on cascaded counters */ 941 control_c |= IPCLK; 942 break; 943 case TRIG_EXT: 944 /* trig on falling edge of external trigger */ 945 control_c |= XPCLK; 946 break; 947 default: 948 break; 949 } 950 break; 951 case TRIG_TIMER: 952 /* burst mode with internal pacer clock */ 953 control_c |= BMDE | IPCLK; 954 break; 955 case TRIG_EXT: 956 /* burst mode with external trigger */ 957 control_c |= BMDE | XPCLK; 958 break; 959 default: 960 break; 961 } 962 963 return control_c; 964} 965 966/* loads counters with divisor1, divisor2 from private structure */ 967static int das1800_set_frequency(struct comedi_device *dev) 968{ 969 struct das1800_private *devpriv = dev->private; 970 int err = 0; 971 972 /* counter 1, mode 2 */ 973 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1, 974 2)) 975 err++; 976 /* counter 2, mode 2 */ 977 if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2, 978 2)) 979 err++; 980 if (err) 981 return -1; 982 983 return 0; 984} 985 986/* sets up counters */ 987static int setup_counters(struct comedi_device *dev, 988 const struct comedi_cmd *cmd) 989{ 990 struct das1800_private *devpriv = dev->private; 991 unsigned int period; 992 993 /* setup cascaded counters for conversion/scan frequency */ 994 switch (cmd->scan_begin_src) { 995 case TRIG_FOLLOW: /* not in burst mode */ 996 if (cmd->convert_src == TRIG_TIMER) { 997 /* set conversion frequency */ 998 period = cmd->convert_arg; 999 i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ, 1000 &devpriv->divisor1, 1001 &devpriv->divisor2, 1002 &period, cmd->flags); 1003 if (das1800_set_frequency(dev) < 0) 1004 return -1; 1005 } 1006 break; 1007 case TRIG_TIMER: /* in burst mode */ 1008 /* set scan frequency */ 1009 period = cmd->scan_begin_arg; 1010 i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ, 1011 &devpriv->divisor1, 1012 &devpriv->divisor2, 1013 &period, cmd->flags); 1014 if (das1800_set_frequency(dev) < 0) 1015 return -1; 1016 break; 1017 default: 1018 break; 1019 } 1020 1021 /* setup counter 0 for 'about triggering' */ 1022 if (cmd->stop_src == TRIG_EXT) { 1023 /* load counter 0 in mode 0 */ 1024 i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0); 1025 } 1026 1027 return 0; 1028} 1029 1030/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ 1031static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd) 1032{ 1033 unsigned int size = DMA_BUF_SIZE; 1034 static const int sample_size = 2; /* size in bytes of one sample from board */ 1035 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ 1036 unsigned int max_size; /* maximum size we will allow for a transfer */ 1037 1038 /* make dma buffer fill in 0.3 seconds for timed modes */ 1039 switch (cmd->scan_begin_src) { 1040 case TRIG_FOLLOW: /* not in burst mode */ 1041 if (cmd->convert_src == TRIG_TIMER) 1042 size = (fill_time / cmd->convert_arg) * sample_size; 1043 break; 1044 case TRIG_TIMER: 1045 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * 1046 sample_size; 1047 break; 1048 default: 1049 size = DMA_BUF_SIZE; 1050 break; 1051 } 1052 1053 /* set a minimum and maximum size allowed */ 1054 max_size = DMA_BUF_SIZE; 1055 /* if we are taking limited number of conversions, limit transfer size to that */ 1056 if (cmd->stop_src == TRIG_COUNT && 1057 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) 1058 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; 1059 1060 if (size > max_size) 1061 size = max_size; 1062 if (size < sample_size) 1063 size = sample_size; 1064 1065 return size; 1066} 1067 1068/* sets up dma */ 1069static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) 1070{ 1071 struct das1800_private *devpriv = dev->private; 1072 unsigned long lock_flags; 1073 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1074 1075 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) 1076 return; 1077 1078 /* determine a reasonable dma transfer size */ 1079 devpriv->dma_transfer_size = suggest_transfer_size(cmd); 1080 lock_flags = claim_dma_lock(); 1081 disable_dma(devpriv->dma0); 1082 /* clear flip-flop to make sure 2-byte registers for 1083 * count and address get set correctly */ 1084 clear_dma_ff(devpriv->dma0); 1085 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0)); 1086 /* set appropriate size of transfer */ 1087 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size); 1088 devpriv->dma_current = devpriv->dma0; 1089 devpriv->dma_current_buf = devpriv->ai_buf0; 1090 enable_dma(devpriv->dma0); 1091 /* set up dual dma if appropriate */ 1092 if (dual_dma) { 1093 disable_dma(devpriv->dma1); 1094 /* clear flip-flop to make sure 2-byte registers for 1095 * count and address get set correctly */ 1096 clear_dma_ff(devpriv->dma1); 1097 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1)); 1098 /* set appropriate size of transfer */ 1099 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size); 1100 enable_dma(devpriv->dma1); 1101 } 1102 release_dma_lock(lock_flags); 1103 1104 return; 1105} 1106 1107/* programs channel/gain list into card */ 1108static void program_chanlist(struct comedi_device *dev, 1109 const struct comedi_cmd *cmd) 1110{ 1111 int i, n, chan_range; 1112 unsigned long irq_flags; 1113 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */ 1114 const int range_bitshift = 8; 1115 1116 n = cmd->chanlist_len; 1117 /* spinlock protects indirect addressing */ 1118 spin_lock_irqsave(&dev->spinlock, irq_flags); 1119 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1120 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */ 1121 /* make channel / gain list */ 1122 for (i = 0; i < n; i++) { 1123 chan_range = 1124 CR_CHAN(cmd->chanlist[i]) | 1125 ((CR_RANGE(cmd->chanlist[i]) & range_mask) << 1126 range_bitshift); 1127 outw(chan_range, dev->iobase + DAS1800_QRAM); 1128 } 1129 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1130 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1131 1132 return; 1133} 1134 1135/* analog input do_cmd */ 1136static int das1800_ai_do_cmd(struct comedi_device *dev, 1137 struct comedi_subdevice *s) 1138{ 1139 struct das1800_private *devpriv = dev->private; 1140 int ret; 1141 int control_a, control_c; 1142 struct comedi_async *async = s->async; 1143 const struct comedi_cmd *cmd = &async->cmd; 1144 1145 /* disable dma on TRIG_WAKE_EOS, or TRIG_RT 1146 * (because dma in handler is unsafe at hard real-time priority) */ 1147 if (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) 1148 devpriv->irq_dma_bits &= ~DMA_ENABLED; 1149 else 1150 devpriv->irq_dma_bits |= devpriv->dma_bits; 1151 /* interrupt on end of conversion for TRIG_WAKE_EOS */ 1152 if (cmd->flags & TRIG_WAKE_EOS) { 1153 /* interrupt fifo not empty */ 1154 devpriv->irq_dma_bits &= ~FIMD; 1155 } else { 1156 /* interrupt fifo half full */ 1157 devpriv->irq_dma_bits |= FIMD; 1158 } 1159 /* determine how many conversions we need */ 1160 if (cmd->stop_src == TRIG_COUNT) 1161 devpriv->count = cmd->stop_arg * cmd->chanlist_len; 1162 1163 das1800_cancel(dev, s); 1164 1165 /* determine proper bits for control registers */ 1166 control_a = control_a_bits(cmd); 1167 control_c = control_c_bits(cmd); 1168 1169 /* setup card and start */ 1170 program_chanlist(dev, cmd); 1171 ret = setup_counters(dev, cmd); 1172 if (ret < 0) { 1173 comedi_error(dev, "Error setting up counters"); 1174 return ret; 1175 } 1176 setup_dma(dev, cmd); 1177 outb(control_c, dev->iobase + DAS1800_CONTROL_C); 1178 /* set conversion rate and length for burst mode */ 1179 if (control_c & BMDE) { 1180 /* program conversion period with number of microseconds minus 1 */ 1181 outb(cmd->convert_arg / 1000 - 1, 1182 dev->iobase + DAS1800_BURST_RATE); 1183 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); 1184 } 1185 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */ 1186 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */ 1187 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1188 1189 return 0; 1190} 1191 1192/* read analog input */ 1193static int das1800_ai_rinsn(struct comedi_device *dev, 1194 struct comedi_subdevice *s, 1195 struct comedi_insn *insn, unsigned int *data) 1196{ 1197 const struct das1800_board *thisboard = comedi_board(dev); 1198 int i, n; 1199 int chan, range, aref, chan_range; 1200 int timeout = 1000; 1201 unsigned short dpnt; 1202 int conv_flags = 0; 1203 unsigned long irq_flags; 1204 1205 /* set up analog reference and unipolar / bipolar mode */ 1206 aref = CR_AREF(insn->chanspec); 1207 conv_flags |= UQEN; 1208 if (aref != AREF_DIFF) 1209 conv_flags |= SD; 1210 if (aref == AREF_COMMON) 1211 conv_flags |= CMEN; 1212 /* if a unipolar range was selected */ 1213 if (CR_RANGE(insn->chanspec) & UNIPOLAR) 1214 conv_flags |= UB; 1215 1216 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */ 1217 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1218 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */ 1219 outb(FFEN, dev->iobase + DAS1800_CONTROL_A); 1220 1221 chan = CR_CHAN(insn->chanspec); 1222 /* mask of unipolar/bipolar bit from range */ 1223 range = CR_RANGE(insn->chanspec) & 0x3; 1224 chan_range = chan | (range << 8); 1225 spin_lock_irqsave(&dev->spinlock, irq_flags); 1226 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1227 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */ 1228 outw(chan_range, dev->iobase + DAS1800_QRAM); 1229 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1230 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */ 1231 1232 for (n = 0; n < insn->n; n++) { 1233 /* trigger conversion */ 1234 outb(0, dev->iobase + DAS1800_FIFO); 1235 for (i = 0; i < timeout; i++) { 1236 if (inb(dev->iobase + DAS1800_STATUS) & FNE) 1237 break; 1238 } 1239 if (i == timeout) { 1240 comedi_error(dev, "timeout"); 1241 n = -ETIME; 1242 goto exit; 1243 } 1244 dpnt = inw(dev->iobase + DAS1800_FIFO); 1245 /* shift data to offset binary for bipolar ranges */ 1246 if ((conv_flags & UB) == 0) 1247 dpnt += 1 << (thisboard->resolution - 1); 1248 data[n] = dpnt; 1249 } 1250exit: 1251 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1252 1253 return n; 1254} 1255 1256/* writes to an analog output channel */ 1257static int das1800_ao_winsn(struct comedi_device *dev, 1258 struct comedi_subdevice *s, 1259 struct comedi_insn *insn, unsigned int *data) 1260{ 1261 const struct das1800_board *thisboard = comedi_board(dev); 1262 struct das1800_private *devpriv = dev->private; 1263 int chan = CR_CHAN(insn->chanspec); 1264/* int range = CR_RANGE(insn->chanspec); */ 1265 int update_chan = thisboard->ao_n_chan - 1; 1266 unsigned short output; 1267 unsigned long irq_flags; 1268 1269 /* card expects two's complement data */ 1270 output = data[0] - (1 << (thisboard->resolution - 1)); 1271 /* if the write is to the 'update' channel, we need to remember its value */ 1272 if (chan == update_chan) 1273 devpriv->ao_update_bits = output; 1274 /* write to channel */ 1275 spin_lock_irqsave(&dev->spinlock, irq_flags); 1276 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */ 1277 outw(output, dev->iobase + DAS1800_DAC); 1278 /* now we need to write to 'update' channel to update all dac channels */ 1279 if (chan != update_chan) { 1280 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */ 1281 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1282 } 1283 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1284 1285 return 1; 1286} 1287 1288/* reads from digital input channels */ 1289static int das1800_di_rbits(struct comedi_device *dev, 1290 struct comedi_subdevice *s, 1291 struct comedi_insn *insn, unsigned int *data) 1292{ 1293 1294 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; 1295 data[0] = 0; 1296 1297 return insn->n; 1298} 1299 1300static int das1800_do_wbits(struct comedi_device *dev, 1301 struct comedi_subdevice *s, 1302 struct comedi_insn *insn, 1303 unsigned int *data) 1304{ 1305 if (comedi_dio_update_state(s, data)) 1306 outb(s->state, dev->iobase + DAS1800_DIGITAL); 1307 1308 data[1] = s->state; 1309 1310 return insn->n; 1311} 1312 1313static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, 1314 unsigned int dma1) 1315{ 1316 struct das1800_private *devpriv = dev->private; 1317 unsigned long flags; 1318 1319 /* need an irq to do dma */ 1320 if (dev->irq && dma0) { 1321 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ 1322 switch ((dma0 & 0x7) | (dma1 << 4)) { 1323 case 0x5: /* dma0 == 5 */ 1324 devpriv->dma_bits |= DMA_CH5; 1325 break; 1326 case 0x6: /* dma0 == 6 */ 1327 devpriv->dma_bits |= DMA_CH6; 1328 break; 1329 case 0x7: /* dma0 == 7 */ 1330 devpriv->dma_bits |= DMA_CH7; 1331 break; 1332 case 0x65: /* dma0 == 5, dma1 == 6 */ 1333 devpriv->dma_bits |= DMA_CH5_CH6; 1334 break; 1335 case 0x76: /* dma0 == 6, dma1 == 7 */ 1336 devpriv->dma_bits |= DMA_CH6_CH7; 1337 break; 1338 case 0x57: /* dma0 == 7, dma1 == 5 */ 1339 devpriv->dma_bits |= DMA_CH7_CH5; 1340 break; 1341 default: 1342 dev_err(dev->class_dev, 1343 "only supports dma channels 5 through 7\n"); 1344 dev_err(dev->class_dev, 1345 "Dual dma only allows the following combinations:\n"); 1346 dev_err(dev->class_dev, 1347 "dma 5,6 / 6,7 / or 7,5\n"); 1348 return -EINVAL; 1349 break; 1350 } 1351 if (request_dma(dma0, dev->driver->driver_name)) { 1352 dev_err(dev->class_dev, 1353 "failed to allocate dma channel %i\n", dma0); 1354 return -EINVAL; 1355 } 1356 devpriv->dma0 = dma0; 1357 devpriv->dma_current = dma0; 1358 if (dma1) { 1359 if (request_dma(dma1, dev->driver->driver_name)) { 1360 dev_err(dev->class_dev, 1361 "failed to allocate dma channel %i\n", 1362 dma1); 1363 return -EINVAL; 1364 } 1365 devpriv->dma1 = dma1; 1366 } 1367 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 1368 if (devpriv->ai_buf0 == NULL) 1369 return -ENOMEM; 1370 devpriv->dma_current_buf = devpriv->ai_buf0; 1371 if (dma1) { 1372 devpriv->ai_buf1 = 1373 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 1374 if (devpriv->ai_buf1 == NULL) 1375 return -ENOMEM; 1376 } 1377 flags = claim_dma_lock(); 1378 disable_dma(devpriv->dma0); 1379 set_dma_mode(devpriv->dma0, DMA_MODE_READ); 1380 if (dma1) { 1381 disable_dma(devpriv->dma1); 1382 set_dma_mode(devpriv->dma1, DMA_MODE_READ); 1383 } 1384 release_dma_lock(flags); 1385 } 1386 return 0; 1387} 1388 1389static int das1800_probe(struct comedi_device *dev) 1390{ 1391 int id; 1392 int board; 1393 1394 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */ 1395 board = ((struct das1800_board *)dev->board_ptr) - das1800_boards; 1396 1397 switch (id) { 1398 case 0x3: 1399 if (board == das1801st_da || board == das1802st_da || 1400 board == das1701st_da || board == das1702st_da) { 1401 dev_dbg(dev->class_dev, "Board model: %s\n", 1402 das1800_boards[board].name); 1403 return board; 1404 } 1405 printk 1406 (" Board model (probed, not recommended): das-1800st-da series\n"); 1407 return das1801st; 1408 break; 1409 case 0x4: 1410 if (board == das1802hr_da || board == das1702hr_da) { 1411 dev_dbg(dev->class_dev, "Board model: %s\n", 1412 das1800_boards[board].name); 1413 return board; 1414 } 1415 printk 1416 (" Board model (probed, not recommended): das-1802hr-da\n"); 1417 return das1802hr; 1418 break; 1419 case 0x5: 1420 if (board == das1801ao || board == das1802ao || 1421 board == das1701ao || board == das1702ao) { 1422 dev_dbg(dev->class_dev, "Board model: %s\n", 1423 das1800_boards[board].name); 1424 return board; 1425 } 1426 printk 1427 (" Board model (probed, not recommended): das-1800ao series\n"); 1428 return das1801ao; 1429 break; 1430 case 0x6: 1431 if (board == das1802hr || board == das1702hr) { 1432 dev_dbg(dev->class_dev, "Board model: %s\n", 1433 das1800_boards[board].name); 1434 return board; 1435 } 1436 printk 1437 (" Board model (probed, not recommended): das-1802hr\n"); 1438 return das1802hr; 1439 break; 1440 case 0x7: 1441 if (board == das1801st || board == das1802st || 1442 board == das1701st || board == das1702st) { 1443 dev_dbg(dev->class_dev, "Board model: %s\n", 1444 das1800_boards[board].name); 1445 return board; 1446 } 1447 printk 1448 (" Board model (probed, not recommended): das-1800st series\n"); 1449 return das1801st; 1450 break; 1451 case 0x8: 1452 if (board == das1801hc || board == das1802hc) { 1453 dev_dbg(dev->class_dev, "Board model: %s\n", 1454 das1800_boards[board].name); 1455 return board; 1456 } 1457 printk 1458 (" Board model (probed, not recommended): das-1800hc series\n"); 1459 return das1801hc; 1460 break; 1461 default: 1462 printk 1463 (" Board model: probe returned 0x%x (unknown, please report)\n", 1464 id); 1465 return board; 1466 break; 1467 } 1468 return -1; 1469} 1470 1471static int das1800_attach(struct comedi_device *dev, 1472 struct comedi_devconfig *it) 1473{ 1474 const struct das1800_board *thisboard = comedi_board(dev); 1475 struct das1800_private *devpriv; 1476 struct comedi_subdevice *s; 1477 unsigned int irq = it->options[1]; 1478 unsigned int dma0 = it->options[2]; 1479 unsigned int dma1 = it->options[3]; 1480 int board; 1481 int ret; 1482 1483 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1484 if (!devpriv) 1485 return -ENOMEM; 1486 1487 ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE); 1488 if (ret) 1489 return ret; 1490 1491 board = das1800_probe(dev); 1492 if (board < 0) { 1493 dev_err(dev->class_dev, "unable to determine board type\n"); 1494 return -ENODEV; 1495 } 1496 1497 dev->board_ptr = das1800_boards + board; 1498 thisboard = comedi_board(dev); 1499 dev->board_name = thisboard->name; 1500 1501 /* if it is an 'ao' board with fancy analog out then we need extra io ports */ 1502 if (thisboard->ao_ability == 2) { 1503 unsigned long iobase2 = dev->iobase + IOBASE2; 1504 1505 ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE); 1506 if (ret) 1507 return ret; 1508 devpriv->iobase2 = iobase2; 1509 } 1510 1511 if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 || 1512 irq == 15) { 1513 ret = request_irq(irq, das1800_interrupt, 0, 1514 dev->board_name, dev); 1515 if (ret == 0) { 1516 dev->irq = irq; 1517 1518 switch (irq) { 1519 case 3: 1520 devpriv->irq_dma_bits |= 0x8; 1521 break; 1522 case 5: 1523 devpriv->irq_dma_bits |= 0x10; 1524 break; 1525 case 7: 1526 devpriv->irq_dma_bits |= 0x18; 1527 break; 1528 case 10: 1529 devpriv->irq_dma_bits |= 0x28; 1530 break; 1531 case 11: 1532 devpriv->irq_dma_bits |= 0x30; 1533 break; 1534 case 15: 1535 devpriv->irq_dma_bits |= 0x38; 1536 break; 1537 } 1538 } 1539 } 1540 1541 ret = das1800_init_dma(dev, dma0, dma1); 1542 if (ret < 0) 1543 return ret; 1544 1545 if (devpriv->ai_buf0 == NULL) { 1546 devpriv->ai_buf0 = 1547 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); 1548 if (devpriv->ai_buf0 == NULL) 1549 return -ENOMEM; 1550 } 1551 1552 ret = comedi_alloc_subdevices(dev, 4); 1553 if (ret) 1554 return ret; 1555 1556 /* analog input subdevice */ 1557 s = &dev->subdevices[0]; 1558 s->type = COMEDI_SUBD_AI; 1559 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; 1560 if (thisboard->common) 1561 s->subdev_flags |= SDF_COMMON; 1562 s->n_chan = thisboard->qram_len; 1563 s->maxdata = (1 << thisboard->resolution) - 1; 1564 s->range_table = thisboard->range_ai; 1565 s->insn_read = das1800_ai_rinsn; 1566 if (dev->irq) { 1567 dev->read_subdev = s; 1568 s->subdev_flags |= SDF_CMD_READ; 1569 s->len_chanlist = s->n_chan; 1570 s->do_cmd = das1800_ai_do_cmd; 1571 s->do_cmdtest = das1800_ai_do_cmdtest; 1572 s->poll = das1800_ai_poll; 1573 s->cancel = das1800_cancel; 1574 } 1575 1576 /* analog out */ 1577 s = &dev->subdevices[1]; 1578 if (thisboard->ao_ability == 1) { 1579 s->type = COMEDI_SUBD_AO; 1580 s->subdev_flags = SDF_WRITABLE; 1581 s->n_chan = thisboard->ao_n_chan; 1582 s->maxdata = (1 << thisboard->resolution) - 1; 1583 s->range_table = &range_bipolar10; 1584 s->insn_write = das1800_ao_winsn; 1585 } else { 1586 s->type = COMEDI_SUBD_UNUSED; 1587 } 1588 1589 /* di */ 1590 s = &dev->subdevices[2]; 1591 s->type = COMEDI_SUBD_DI; 1592 s->subdev_flags = SDF_READABLE; 1593 s->n_chan = 4; 1594 s->maxdata = 1; 1595 s->range_table = &range_digital; 1596 s->insn_bits = das1800_di_rbits; 1597 1598 /* do */ 1599 s = &dev->subdevices[3]; 1600 s->type = COMEDI_SUBD_DO; 1601 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 1602 s->n_chan = thisboard->do_n_chan; 1603 s->maxdata = 1; 1604 s->range_table = &range_digital; 1605 s->insn_bits = das1800_do_wbits; 1606 1607 das1800_cancel(dev, dev->read_subdev); 1608 1609 /* initialize digital out channels */ 1610 outb(0, dev->iobase + DAS1800_DIGITAL); 1611 1612 /* initialize analog out channels */ 1613 if (thisboard->ao_ability == 1) { 1614 /* select 'update' dac channel for baseAddress + 0x0 */ 1615 outb(DAC(thisboard->ao_n_chan - 1), 1616 dev->iobase + DAS1800_SELECT); 1617 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1618 } 1619 1620 return 0; 1621}; 1622 1623static void das1800_detach(struct comedi_device *dev) 1624{ 1625 struct das1800_private *devpriv = dev->private; 1626 1627 if (devpriv) { 1628 if (devpriv->dma0) 1629 free_dma(devpriv->dma0); 1630 if (devpriv->dma1) 1631 free_dma(devpriv->dma1); 1632 kfree(devpriv->ai_buf0); 1633 kfree(devpriv->ai_buf1); 1634 if (devpriv->iobase2) 1635 release_region(devpriv->iobase2, DAS1800_SIZE); 1636 } 1637 comedi_legacy_detach(dev); 1638} 1639 1640static struct comedi_driver das1800_driver = { 1641 .driver_name = "das1800", 1642 .module = THIS_MODULE, 1643 .attach = das1800_attach, 1644 .detach = das1800_detach, 1645 .num_names = ARRAY_SIZE(das1800_boards), 1646 .board_name = &das1800_boards[0].name, 1647 .offset = sizeof(struct das1800_board), 1648}; 1649module_comedi_driver(das1800_driver); 1650 1651MODULE_AUTHOR("Comedi http://www.comedi.org"); 1652MODULE_DESCRIPTION("Comedi low-level driver"); 1653MODULE_LICENSE("GPL"); 1654