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 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 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 = dev->board_ptr; 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} 496 497static void das1800_handle_fifo_not_empty(struct comedi_device *dev, 498 struct comedi_subdevice *s) 499{ 500 struct das1800_private *devpriv = dev->private; 501 unsigned short dpnt; 502 int unipolar; 503 struct comedi_cmd *cmd = &s->async->cmd; 504 505 unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB; 506 507 while (inb(dev->iobase + DAS1800_STATUS) & FNE) { 508 if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) 509 break; 510 dpnt = inw(dev->iobase + DAS1800_FIFO); 511 /* convert to unsigned type if we are in a bipolar mode */ 512 if (!unipolar) 513 ; 514 dpnt = munge_bipolar_sample(dev, dpnt); 515 cfc_write_to_buffer(s, dpnt); 516 if (cmd->stop_src == TRIG_COUNT) 517 devpriv->count--; 518 } 519} 520 521/* Utility function used by das1800_flush_dma() and das1800_handle_dma(). 522 * Assumes dma lock is held */ 523static void das1800_flush_dma_channel(struct comedi_device *dev, 524 struct comedi_subdevice *s, 525 unsigned int channel, uint16_t *buffer) 526{ 527 struct das1800_private *devpriv = dev->private; 528 unsigned int num_bytes, num_samples; 529 struct comedi_cmd *cmd = &s->async->cmd; 530 531 disable_dma(channel); 532 533 /* clear flip-flop to make sure 2-byte registers 534 * get set correctly */ 535 clear_dma_ff(channel); 536 537 /* figure out how many points to read */ 538 num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel); 539 num_samples = num_bytes / sizeof(short); 540 541 /* if we only need some of the points */ 542 if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples) 543 num_samples = devpriv->count; 544 545 munge_data(dev, buffer, num_samples); 546 cfc_write_array_to_buffer(s, buffer, num_bytes); 547 if (cmd->stop_src == TRIG_COUNT) 548 devpriv->count -= num_samples; 549} 550 551/* flushes remaining data from board when external trigger has stopped acquisition 552 * and we are using dma transfers */ 553static void das1800_flush_dma(struct comedi_device *dev, 554 struct comedi_subdevice *s) 555{ 556 struct das1800_private *devpriv = dev->private; 557 unsigned long flags; 558 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 559 560 flags = claim_dma_lock(); 561 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 562 devpriv->dma_current_buf); 563 564 if (dual_dma) { 565 /* switch to other channel and flush it */ 566 if (devpriv->dma_current == devpriv->dma0) { 567 devpriv->dma_current = devpriv->dma1; 568 devpriv->dma_current_buf = devpriv->ai_buf1; 569 } else { 570 devpriv->dma_current = devpriv->dma0; 571 devpriv->dma_current_buf = devpriv->ai_buf0; 572 } 573 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 574 devpriv->dma_current_buf); 575 } 576 577 release_dma_lock(flags); 578 579 /* get any remaining samples in fifo */ 580 das1800_handle_fifo_not_empty(dev, s); 581} 582 583static void das1800_handle_dma(struct comedi_device *dev, 584 struct comedi_subdevice *s, unsigned int status) 585{ 586 struct das1800_private *devpriv = dev->private; 587 unsigned long flags; 588 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 589 590 flags = claim_dma_lock(); 591 das1800_flush_dma_channel(dev, s, devpriv->dma_current, 592 devpriv->dma_current_buf); 593 /* re-enable dma channel */ 594 set_dma_addr(devpriv->dma_current, 595 virt_to_bus(devpriv->dma_current_buf)); 596 set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size); 597 enable_dma(devpriv->dma_current); 598 release_dma_lock(flags); 599 600 if (status & DMATC) { 601 /* clear DMATC interrupt bit */ 602 outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS); 603 /* switch dma channels for next time, if appropriate */ 604 if (dual_dma) { 605 /* read data from the other channel next time */ 606 if (devpriv->dma_current == devpriv->dma0) { 607 devpriv->dma_current = devpriv->dma1; 608 devpriv->dma_current_buf = devpriv->ai_buf1; 609 } else { 610 devpriv->dma_current = devpriv->dma0; 611 devpriv->dma_current_buf = devpriv->ai_buf0; 612 } 613 } 614 } 615} 616 617static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 618{ 619 struct das1800_private *devpriv = dev->private; 620 621 outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */ 622 outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */ 623 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */ 624 if (devpriv->dma0) 625 disable_dma(devpriv->dma0); 626 if (devpriv->dma1) 627 disable_dma(devpriv->dma1); 628 return 0; 629} 630 631/* the guts of the interrupt handler, that is shared with das1800_ai_poll */ 632static void das1800_ai_handler(struct comedi_device *dev) 633{ 634 struct das1800_private *devpriv = dev->private; 635 struct comedi_subdevice *s = dev->read_subdev; 636 struct comedi_async *async = s->async; 637 struct comedi_cmd *cmd = &async->cmd; 638 unsigned int status = inb(dev->iobase + DAS1800_STATUS); 639 640 /* select adc for base address + 0 */ 641 outb(ADC, dev->iobase + DAS1800_SELECT); 642 /* dma buffer full */ 643 if (devpriv->irq_dma_bits & DMA_ENABLED) { 644 /* look for data from dma transfer even if dma terminal count hasn't happened yet */ 645 das1800_handle_dma(dev, s, status); 646 } else if (status & FHF) { /* if fifo half full */ 647 das1800_handle_fifo_half_full(dev, s); 648 } else if (status & FNE) { /* if fifo not empty */ 649 das1800_handle_fifo_not_empty(dev, s); 650 } 651 652 async->events |= COMEDI_CB_BLOCK; 653 /* if the card's fifo has overflowed */ 654 if (status & OVF) { 655 /* clear OVF interrupt bit */ 656 outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS); 657 dev_err(dev->class_dev, "FIFO overflow\n"); 658 async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA; 659 cfc_handle_events(dev, s); 660 return; 661 } 662 /* stop taking data if appropriate */ 663 /* stop_src TRIG_EXT */ 664 if (status & CT0TC) { 665 /* clear CT0TC interrupt bit */ 666 outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS); 667 /* make sure we get all remaining data from board before quitting */ 668 if (devpriv->irq_dma_bits & DMA_ENABLED) 669 das1800_flush_dma(dev, s); 670 else 671 das1800_handle_fifo_not_empty(dev, s); 672 async->events |= COMEDI_CB_EOA; 673 } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { /* stop_src TRIG_COUNT */ 674 async->events |= COMEDI_CB_EOA; 675 } 676 677 cfc_handle_events(dev, s); 678} 679 680static int das1800_ai_poll(struct comedi_device *dev, 681 struct comedi_subdevice *s) 682{ 683 unsigned long flags; 684 685 /* prevent race with interrupt handler */ 686 spin_lock_irqsave(&dev->spinlock, flags); 687 das1800_ai_handler(dev); 688 spin_unlock_irqrestore(&dev->spinlock, flags); 689 690 return comedi_buf_n_bytes_ready(s); 691} 692 693static irqreturn_t das1800_interrupt(int irq, void *d) 694{ 695 struct comedi_device *dev = d; 696 unsigned int status; 697 698 if (!dev->attached) { 699 dev_err(dev->class_dev, "premature interrupt\n"); 700 return IRQ_HANDLED; 701 } 702 703 /* Prevent race with das1800_ai_poll() on multi processor systems. 704 * Also protects indirect addressing in das1800_ai_handler */ 705 spin_lock(&dev->spinlock); 706 status = inb(dev->iobase + DAS1800_STATUS); 707 708 /* if interrupt was not caused by das-1800 */ 709 if (!(status & INT)) { 710 spin_unlock(&dev->spinlock); 711 return IRQ_NONE; 712 } 713 /* clear the interrupt status bit INT */ 714 outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS); 715 /* handle interrupt */ 716 das1800_ai_handler(dev); 717 718 spin_unlock(&dev->spinlock); 719 return IRQ_HANDLED; 720} 721 722/* converts requested conversion timing to timing compatible with 723 * hardware, used only when card is in 'burst mode' 724 */ 725static unsigned int burst_convert_arg(unsigned int convert_arg, int flags) 726{ 727 unsigned int micro_sec; 728 729 /* in burst mode, the maximum conversion time is 64 microseconds */ 730 if (convert_arg > 64000) 731 convert_arg = 64000; 732 733 /* the conversion time must be an integral number of microseconds */ 734 switch (flags & CMDF_ROUND_MASK) { 735 case CMDF_ROUND_NEAREST: 736 default: 737 micro_sec = (convert_arg + 500) / 1000; 738 break; 739 case CMDF_ROUND_DOWN: 740 micro_sec = convert_arg / 1000; 741 break; 742 case CMDF_ROUND_UP: 743 micro_sec = (convert_arg - 1) / 1000 + 1; 744 break; 745 } 746 747 /* return number of nanoseconds */ 748 return micro_sec * 1000; 749} 750 751static int das1800_ai_check_chanlist(struct comedi_device *dev, 752 struct comedi_subdevice *s, 753 struct comedi_cmd *cmd) 754{ 755 unsigned int unipolar0 = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR; 756 int i; 757 758 for (i = 1; i < cmd->chanlist_len; i++) { 759 unsigned int unipolar = CR_RANGE(cmd->chanlist[i]) & UNIPOLAR; 760 761 if (unipolar != unipolar0) { 762 dev_dbg(dev->class_dev, 763 "unipolar and bipolar ranges cannot be mixed in the chanlist\n"); 764 return -EINVAL; 765 } 766 } 767 768 return 0; 769} 770 771/* test analog input cmd */ 772static int das1800_ai_do_cmdtest(struct comedi_device *dev, 773 struct comedi_subdevice *s, 774 struct comedi_cmd *cmd) 775{ 776 const struct das1800_board *thisboard = dev->board_ptr; 777 struct das1800_private *devpriv = dev->private; 778 int err = 0; 779 unsigned int arg; 780 781 /* Step 1 : check if triggers are trivially valid */ 782 783 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); 784 err |= cfc_check_trigger_src(&cmd->scan_begin_src, 785 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT); 786 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT); 787 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 788 err |= cfc_check_trigger_src(&cmd->stop_src, 789 TRIG_COUNT | TRIG_EXT | TRIG_NONE); 790 791 if (err) 792 return 1; 793 794 /* Step 2a : make sure trigger sources are unique */ 795 796 err |= cfc_check_trigger_is_unique(cmd->start_src); 797 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); 798 err |= cfc_check_trigger_is_unique(cmd->convert_src); 799 err |= cfc_check_trigger_is_unique(cmd->stop_src); 800 801 /* Step 2b : and mutually compatible */ 802 803 if (cmd->scan_begin_src != TRIG_FOLLOW && 804 cmd->convert_src != TRIG_TIMER) 805 err |= -EINVAL; 806 807 if (err) 808 return 2; 809 810 /* Step 3: check if arguments are trivially valid */ 811 812 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 813 814 if (cmd->convert_src == TRIG_TIMER) 815 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 816 thisboard->ai_speed); 817 818 err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1); 819 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 820 821 switch (cmd->stop_src) { 822 case TRIG_COUNT: 823 err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1); 824 break; 825 case TRIG_NONE: 826 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 827 break; 828 default: 829 break; 830 } 831 832 if (err) 833 return 3; 834 835 /* step 4: fix up any arguments */ 836 837 if (cmd->scan_begin_src == TRIG_FOLLOW && 838 cmd->convert_src == TRIG_TIMER) { 839 /* we are not in burst mode */ 840 arg = cmd->convert_arg; 841 i8253_cascade_ns_to_timer(I8254_OSC_BASE_5MHZ, 842 &devpriv->divisor1, 843 &devpriv->divisor2, 844 &cmd->convert_arg, cmd->flags); 845 if (arg != cmd->convert_arg) 846 err++; 847 } else if (cmd->convert_src == TRIG_TIMER) { 848 /* we are in burst mode */ 849 arg = cmd->convert_arg; 850 cmd->convert_arg = burst_convert_arg(cmd->convert_arg, 851 cmd->flags); 852 if (arg != cmd->convert_arg) 853 err++; 854 855 if (cmd->scan_begin_src == TRIG_TIMER) { 856 arg = cmd->convert_arg * cmd->chanlist_len; 857 if (arg > cmd->scan_begin_arg) { 858 cmd->scan_begin_arg = arg; 859 err++; 860 } 861 862 arg = cmd->scan_begin_arg; 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 (arg != cmd->scan_begin_arg) 869 err++; 870 } 871 } 872 873 if (err) 874 return 4; 875 876 /* Step 5: check channel list if it exists */ 877 if (cmd->chanlist && cmd->chanlist_len > 0) 878 err |= das1800_ai_check_chanlist(dev, s, cmd); 879 880 if (err) 881 return 5; 882 883 return 0; 884} 885 886/* returns appropriate bits for control register a, depending on command */ 887static int control_a_bits(const struct comedi_cmd *cmd) 888{ 889 int control_a; 890 891 control_a = FFEN; /* enable fifo */ 892 if (cmd->stop_src == TRIG_EXT) 893 control_a |= ATEN; 894 switch (cmd->start_src) { 895 case TRIG_EXT: 896 control_a |= TGEN | CGSL; 897 break; 898 case TRIG_NOW: 899 control_a |= CGEN; 900 break; 901 default: 902 break; 903 } 904 905 return control_a; 906} 907 908/* returns appropriate bits for control register c, depending on command */ 909static int control_c_bits(const struct comedi_cmd *cmd) 910{ 911 int control_c; 912 int aref; 913 914 /* set clock source to internal or external, select analog reference, 915 * select unipolar / bipolar 916 */ 917 aref = CR_AREF(cmd->chanlist[0]); 918 control_c = UQEN; /* enable upper qram addresses */ 919 if (aref != AREF_DIFF) 920 control_c |= SD; 921 if (aref == AREF_COMMON) 922 control_c |= CMEN; 923 /* if a unipolar range was selected */ 924 if (CR_RANGE(cmd->chanlist[0]) & UNIPOLAR) 925 control_c |= UB; 926 switch (cmd->scan_begin_src) { 927 case TRIG_FOLLOW: /* not in burst mode */ 928 switch (cmd->convert_src) { 929 case TRIG_TIMER: 930 /* trig on cascaded counters */ 931 control_c |= IPCLK; 932 break; 933 case TRIG_EXT: 934 /* trig on falling edge of external trigger */ 935 control_c |= XPCLK; 936 break; 937 default: 938 break; 939 } 940 break; 941 case TRIG_TIMER: 942 /* burst mode with internal pacer clock */ 943 control_c |= BMDE | IPCLK; 944 break; 945 case TRIG_EXT: 946 /* burst mode with external trigger */ 947 control_c |= BMDE | XPCLK; 948 break; 949 default: 950 break; 951 } 952 953 return control_c; 954} 955 956static void das1800_setup_counters(struct comedi_device *dev, 957 const struct comedi_cmd *cmd) 958{ 959 struct das1800_private *devpriv = dev->private; 960 unsigned long timer_base = dev->iobase + DAS1800_COUNTER; 961 962 /* setup cascaded counters for conversion/scan frequency */ 963 if ((cmd->scan_begin_src == TRIG_FOLLOW || 964 cmd->scan_begin_src == TRIG_TIMER) && 965 cmd->convert_src == TRIG_TIMER) { 966 i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY); 967 i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY); 968 969 i8254_write(timer_base, 0, 1, devpriv->divisor1); 970 i8254_write(timer_base, 0, 2, devpriv->divisor2); 971 } 972 973 /* setup counter 0 for 'about triggering' */ 974 if (cmd->stop_src == TRIG_EXT) { 975 i8254_set_mode(timer_base, 0, 0, I8254_MODE0 | I8254_BINARY); 976 977 i8254_write(timer_base, 0, 0, 1); 978 } 979} 980 981/* utility function that suggests a dma transfer size based on the conversion period 'ns' */ 982static unsigned int suggest_transfer_size(const struct comedi_cmd *cmd) 983{ 984 unsigned int size = DMA_BUF_SIZE; 985 static const int sample_size = 2; /* size in bytes of one sample from board */ 986 unsigned int fill_time = 300000000; /* target time in nanoseconds for filling dma buffer */ 987 unsigned int max_size; /* maximum size we will allow for a transfer */ 988 989 /* make dma buffer fill in 0.3 seconds for timed modes */ 990 switch (cmd->scan_begin_src) { 991 case TRIG_FOLLOW: /* not in burst mode */ 992 if (cmd->convert_src == TRIG_TIMER) 993 size = (fill_time / cmd->convert_arg) * sample_size; 994 break; 995 case TRIG_TIMER: 996 size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) * 997 sample_size; 998 break; 999 default: 1000 size = DMA_BUF_SIZE; 1001 break; 1002 } 1003 1004 /* set a minimum and maximum size allowed */ 1005 max_size = DMA_BUF_SIZE; 1006 /* if we are taking limited number of conversions, limit transfer size to that */ 1007 if (cmd->stop_src == TRIG_COUNT && 1008 cmd->stop_arg * cmd->chanlist_len * sample_size < max_size) 1009 max_size = cmd->stop_arg * cmd->chanlist_len * sample_size; 1010 1011 if (size > max_size) 1012 size = max_size; 1013 if (size < sample_size) 1014 size = sample_size; 1015 1016 return size; 1017} 1018 1019/* sets up dma */ 1020static void setup_dma(struct comedi_device *dev, const struct comedi_cmd *cmd) 1021{ 1022 struct das1800_private *devpriv = dev->private; 1023 unsigned long lock_flags; 1024 const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL; 1025 1026 if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0) 1027 return; 1028 1029 /* determine a reasonable dma transfer size */ 1030 devpriv->dma_transfer_size = suggest_transfer_size(cmd); 1031 lock_flags = claim_dma_lock(); 1032 disable_dma(devpriv->dma0); 1033 /* clear flip-flop to make sure 2-byte registers for 1034 * count and address get set correctly */ 1035 clear_dma_ff(devpriv->dma0); 1036 set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0)); 1037 /* set appropriate size of transfer */ 1038 set_dma_count(devpriv->dma0, devpriv->dma_transfer_size); 1039 devpriv->dma_current = devpriv->dma0; 1040 devpriv->dma_current_buf = devpriv->ai_buf0; 1041 enable_dma(devpriv->dma0); 1042 /* set up dual dma if appropriate */ 1043 if (dual_dma) { 1044 disable_dma(devpriv->dma1); 1045 /* clear flip-flop to make sure 2-byte registers for 1046 * count and address get set correctly */ 1047 clear_dma_ff(devpriv->dma1); 1048 set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1)); 1049 /* set appropriate size of transfer */ 1050 set_dma_count(devpriv->dma1, devpriv->dma_transfer_size); 1051 enable_dma(devpriv->dma1); 1052 } 1053 release_dma_lock(lock_flags); 1054} 1055 1056/* programs channel/gain list into card */ 1057static void program_chanlist(struct comedi_device *dev, 1058 const struct comedi_cmd *cmd) 1059{ 1060 int i, n, chan_range; 1061 unsigned long irq_flags; 1062 const int range_mask = 0x3; /* masks unipolar/bipolar bit off range */ 1063 const int range_bitshift = 8; 1064 1065 n = cmd->chanlist_len; 1066 /* spinlock protects indirect addressing */ 1067 spin_lock_irqsave(&dev->spinlock, irq_flags); 1068 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1069 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */ 1070 /* make channel / gain list */ 1071 for (i = 0; i < n; i++) { 1072 chan_range = 1073 CR_CHAN(cmd->chanlist[i]) | 1074 ((CR_RANGE(cmd->chanlist[i]) & range_mask) << 1075 range_bitshift); 1076 outw(chan_range, dev->iobase + DAS1800_QRAM); 1077 } 1078 outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1079 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1080} 1081 1082/* analog input do_cmd */ 1083static int das1800_ai_do_cmd(struct comedi_device *dev, 1084 struct comedi_subdevice *s) 1085{ 1086 struct das1800_private *devpriv = dev->private; 1087 int control_a, control_c; 1088 struct comedi_async *async = s->async; 1089 const struct comedi_cmd *cmd = &async->cmd; 1090 1091 /* disable dma on CMDF_WAKE_EOS, or CMDF_PRIORITY 1092 * (because dma in handler is unsafe at hard real-time priority) */ 1093 if (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) 1094 devpriv->irq_dma_bits &= ~DMA_ENABLED; 1095 else 1096 devpriv->irq_dma_bits |= devpriv->dma_bits; 1097 /* interrupt on end of conversion for CMDF_WAKE_EOS */ 1098 if (cmd->flags & CMDF_WAKE_EOS) { 1099 /* interrupt fifo not empty */ 1100 devpriv->irq_dma_bits &= ~FIMD; 1101 } else { 1102 /* interrupt fifo half full */ 1103 devpriv->irq_dma_bits |= FIMD; 1104 } 1105 /* determine how many conversions we need */ 1106 if (cmd->stop_src == TRIG_COUNT) 1107 devpriv->count = cmd->stop_arg * cmd->chanlist_len; 1108 1109 das1800_cancel(dev, s); 1110 1111 /* determine proper bits for control registers */ 1112 control_a = control_a_bits(cmd); 1113 control_c = control_c_bits(cmd); 1114 1115 /* setup card and start */ 1116 program_chanlist(dev, cmd); 1117 das1800_setup_counters(dev, cmd); 1118 setup_dma(dev, cmd); 1119 outb(control_c, dev->iobase + DAS1800_CONTROL_C); 1120 /* set conversion rate and length for burst mode */ 1121 if (control_c & BMDE) { 1122 /* program conversion period with number of microseconds minus 1 */ 1123 outb(cmd->convert_arg / 1000 - 1, 1124 dev->iobase + DAS1800_BURST_RATE); 1125 outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH); 1126 } 1127 outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); /* enable irq/dma */ 1128 outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */ 1129 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1130 1131 return 0; 1132} 1133 1134/* read analog input */ 1135static int das1800_ai_rinsn(struct comedi_device *dev, 1136 struct comedi_subdevice *s, 1137 struct comedi_insn *insn, unsigned int *data) 1138{ 1139 const struct das1800_board *thisboard = dev->board_ptr; 1140 int i, n; 1141 int chan, range, aref, chan_range; 1142 int timeout = 1000; 1143 unsigned short dpnt; 1144 int conv_flags = 0; 1145 unsigned long irq_flags; 1146 1147 /* set up analog reference and unipolar / bipolar mode */ 1148 aref = CR_AREF(insn->chanspec); 1149 conv_flags |= UQEN; 1150 if (aref != AREF_DIFF) 1151 conv_flags |= SD; 1152 if (aref == AREF_COMMON) 1153 conv_flags |= CMEN; 1154 /* if a unipolar range was selected */ 1155 if (CR_RANGE(insn->chanspec) & UNIPOLAR) 1156 conv_flags |= UB; 1157 1158 outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */ 1159 outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */ 1160 outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */ 1161 outb(FFEN, dev->iobase + DAS1800_CONTROL_A); 1162 1163 chan = CR_CHAN(insn->chanspec); 1164 /* mask of unipolar/bipolar bit from range */ 1165 range = CR_RANGE(insn->chanspec) & 0x3; 1166 chan_range = chan | (range << 8); 1167 spin_lock_irqsave(&dev->spinlock, irq_flags); 1168 outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */ 1169 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */ 1170 outw(chan_range, dev->iobase + DAS1800_QRAM); 1171 outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */ 1172 outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */ 1173 1174 for (n = 0; n < insn->n; n++) { 1175 /* trigger conversion */ 1176 outb(0, dev->iobase + DAS1800_FIFO); 1177 for (i = 0; i < timeout; i++) { 1178 if (inb(dev->iobase + DAS1800_STATUS) & FNE) 1179 break; 1180 } 1181 if (i == timeout) { 1182 dev_err(dev->class_dev, "timeout\n"); 1183 n = -ETIME; 1184 goto exit; 1185 } 1186 dpnt = inw(dev->iobase + DAS1800_FIFO); 1187 /* shift data to offset binary for bipolar ranges */ 1188 if ((conv_flags & UB) == 0) 1189 dpnt += 1 << (thisboard->resolution - 1); 1190 data[n] = dpnt; 1191 } 1192exit: 1193 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1194 1195 return n; 1196} 1197 1198/* writes to an analog output channel */ 1199static int das1800_ao_winsn(struct comedi_device *dev, 1200 struct comedi_subdevice *s, 1201 struct comedi_insn *insn, unsigned int *data) 1202{ 1203 const struct das1800_board *thisboard = dev->board_ptr; 1204 struct das1800_private *devpriv = dev->private; 1205 int chan = CR_CHAN(insn->chanspec); 1206/* int range = CR_RANGE(insn->chanspec); */ 1207 int update_chan = thisboard->ao_n_chan - 1; 1208 unsigned short output; 1209 unsigned long irq_flags; 1210 1211 /* card expects two's complement data */ 1212 output = data[0] - (1 << (thisboard->resolution - 1)); 1213 /* if the write is to the 'update' channel, we need to remember its value */ 1214 if (chan == update_chan) 1215 devpriv->ao_update_bits = output; 1216 /* write to channel */ 1217 spin_lock_irqsave(&dev->spinlock, irq_flags); 1218 outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */ 1219 outw(output, dev->iobase + DAS1800_DAC); 1220 /* now we need to write to 'update' channel to update all dac channels */ 1221 if (chan != update_chan) { 1222 outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */ 1223 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1224 } 1225 spin_unlock_irqrestore(&dev->spinlock, irq_flags); 1226 1227 return 1; 1228} 1229 1230/* reads from digital input channels */ 1231static int das1800_di_rbits(struct comedi_device *dev, 1232 struct comedi_subdevice *s, 1233 struct comedi_insn *insn, unsigned int *data) 1234{ 1235 1236 data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf; 1237 data[0] = 0; 1238 1239 return insn->n; 1240} 1241 1242static int das1800_do_wbits(struct comedi_device *dev, 1243 struct comedi_subdevice *s, 1244 struct comedi_insn *insn, 1245 unsigned int *data) 1246{ 1247 if (comedi_dio_update_state(s, data)) 1248 outb(s->state, dev->iobase + DAS1800_DIGITAL); 1249 1250 data[1] = s->state; 1251 1252 return insn->n; 1253} 1254 1255static int das1800_init_dma(struct comedi_device *dev, unsigned int dma0, 1256 unsigned int dma1) 1257{ 1258 struct das1800_private *devpriv = dev->private; 1259 unsigned long flags; 1260 1261 /* need an irq to do dma */ 1262 if (dev->irq && dma0) { 1263 /* encode dma0 and dma1 into 2 digit hexadecimal for switch */ 1264 switch ((dma0 & 0x7) | (dma1 << 4)) { 1265 case 0x5: /* dma0 == 5 */ 1266 devpriv->dma_bits |= DMA_CH5; 1267 break; 1268 case 0x6: /* dma0 == 6 */ 1269 devpriv->dma_bits |= DMA_CH6; 1270 break; 1271 case 0x7: /* dma0 == 7 */ 1272 devpriv->dma_bits |= DMA_CH7; 1273 break; 1274 case 0x65: /* dma0 == 5, dma1 == 6 */ 1275 devpriv->dma_bits |= DMA_CH5_CH6; 1276 break; 1277 case 0x76: /* dma0 == 6, dma1 == 7 */ 1278 devpriv->dma_bits |= DMA_CH6_CH7; 1279 break; 1280 case 0x57: /* dma0 == 7, dma1 == 5 */ 1281 devpriv->dma_bits |= DMA_CH7_CH5; 1282 break; 1283 default: 1284 dev_err(dev->class_dev, 1285 "only supports dma channels 5 through 7\n"); 1286 dev_err(dev->class_dev, 1287 "Dual dma only allows the following combinations:\n"); 1288 dev_err(dev->class_dev, 1289 "dma 5,6 / 6,7 / or 7,5\n"); 1290 return -EINVAL; 1291 } 1292 if (request_dma(dma0, dev->driver->driver_name)) { 1293 dev_err(dev->class_dev, 1294 "failed to allocate dma channel %i\n", dma0); 1295 return -EINVAL; 1296 } 1297 devpriv->dma0 = dma0; 1298 devpriv->dma_current = dma0; 1299 if (dma1) { 1300 if (request_dma(dma1, dev->driver->driver_name)) { 1301 dev_err(dev->class_dev, 1302 "failed to allocate dma channel %i\n", 1303 dma1); 1304 return -EINVAL; 1305 } 1306 devpriv->dma1 = dma1; 1307 } 1308 devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 1309 if (devpriv->ai_buf0 == NULL) 1310 return -ENOMEM; 1311 devpriv->dma_current_buf = devpriv->ai_buf0; 1312 if (dma1) { 1313 devpriv->ai_buf1 = 1314 kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA); 1315 if (devpriv->ai_buf1 == NULL) 1316 return -ENOMEM; 1317 } 1318 flags = claim_dma_lock(); 1319 disable_dma(devpriv->dma0); 1320 set_dma_mode(devpriv->dma0, DMA_MODE_READ); 1321 if (dma1) { 1322 disable_dma(devpriv->dma1); 1323 set_dma_mode(devpriv->dma1, DMA_MODE_READ); 1324 } 1325 release_dma_lock(flags); 1326 } 1327 return 0; 1328} 1329 1330static int das1800_probe(struct comedi_device *dev) 1331{ 1332 const struct das1800_board *board = dev->board_ptr; 1333 int index; 1334 int id; 1335 1336 /* calc the offset to the boardinfo that was found by the core */ 1337 index = board - das1800_boards; 1338 1339 /* verify that the board id matches the boardinfo */ 1340 id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; 1341 switch (id) { 1342 case 0x3: 1343 if (index == das1801st_da || index == das1802st_da || 1344 index == das1701st_da || index == das1702st_da) 1345 return index; 1346 index = das1801st; 1347 break; 1348 case 0x4: 1349 if (index == das1802hr_da || index == das1702hr_da) 1350 return index; 1351 index = das1802hr; 1352 break; 1353 case 0x5: 1354 if (index == das1801ao || index == das1802ao || 1355 index == das1701ao || index == das1702ao) 1356 return index; 1357 index = das1801ao; 1358 break; 1359 case 0x6: 1360 if (index == das1802hr || index == das1702hr) 1361 return index; 1362 index = das1802hr; 1363 break; 1364 case 0x7: 1365 if (index == das1801st || index == das1802st || 1366 index == das1701st || index == das1702st) 1367 return index; 1368 index = das1801st; 1369 break; 1370 case 0x8: 1371 if (index == das1801hc || index == das1802hc) 1372 return index; 1373 index = das1801hc; 1374 break; 1375 default: 1376 dev_err(dev->class_dev, 1377 "Board model: probe returned 0x%x (unknown, please report)\n", 1378 id); 1379 break; 1380 } 1381 dev_err(dev->class_dev, 1382 "Board model (probed, not recommended): %s series\n", 1383 das1800_boards[index].name); 1384 1385 return index; 1386} 1387 1388static int das1800_attach(struct comedi_device *dev, 1389 struct comedi_devconfig *it) 1390{ 1391 const struct das1800_board *thisboard; 1392 struct das1800_private *devpriv; 1393 struct comedi_subdevice *s; 1394 unsigned int irq = it->options[1]; 1395 unsigned int dma0 = it->options[2]; 1396 unsigned int dma1 = it->options[3]; 1397 int board; 1398 int ret; 1399 1400 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1401 if (!devpriv) 1402 return -ENOMEM; 1403 1404 ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE); 1405 if (ret) 1406 return ret; 1407 1408 board = das1800_probe(dev); 1409 if (board < 0) { 1410 dev_err(dev->class_dev, "unable to determine board type\n"); 1411 return -ENODEV; 1412 } 1413 1414 dev->board_ptr = das1800_boards + board; 1415 thisboard = dev->board_ptr; 1416 dev->board_name = thisboard->name; 1417 1418 /* if it is an 'ao' board with fancy analog out then we need extra io ports */ 1419 if (thisboard->ao_ability == 2) { 1420 unsigned long iobase2 = dev->iobase + IOBASE2; 1421 1422 ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE); 1423 if (ret) 1424 return ret; 1425 devpriv->iobase2 = iobase2; 1426 } 1427 1428 if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 || 1429 irq == 15) { 1430 ret = request_irq(irq, das1800_interrupt, 0, 1431 dev->board_name, dev); 1432 if (ret == 0) { 1433 dev->irq = irq; 1434 1435 switch (irq) { 1436 case 3: 1437 devpriv->irq_dma_bits |= 0x8; 1438 break; 1439 case 5: 1440 devpriv->irq_dma_bits |= 0x10; 1441 break; 1442 case 7: 1443 devpriv->irq_dma_bits |= 0x18; 1444 break; 1445 case 10: 1446 devpriv->irq_dma_bits |= 0x28; 1447 break; 1448 case 11: 1449 devpriv->irq_dma_bits |= 0x30; 1450 break; 1451 case 15: 1452 devpriv->irq_dma_bits |= 0x38; 1453 break; 1454 } 1455 } 1456 } 1457 1458 ret = das1800_init_dma(dev, dma0, dma1); 1459 if (ret < 0) 1460 return ret; 1461 1462 if (devpriv->ai_buf0 == NULL) { 1463 devpriv->ai_buf0 = 1464 kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL); 1465 if (devpriv->ai_buf0 == NULL) 1466 return -ENOMEM; 1467 } 1468 1469 ret = comedi_alloc_subdevices(dev, 4); 1470 if (ret) 1471 return ret; 1472 1473 /* analog input subdevice */ 1474 s = &dev->subdevices[0]; 1475 s->type = COMEDI_SUBD_AI; 1476 s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND; 1477 if (thisboard->common) 1478 s->subdev_flags |= SDF_COMMON; 1479 s->n_chan = thisboard->qram_len; 1480 s->maxdata = (1 << thisboard->resolution) - 1; 1481 s->range_table = thisboard->range_ai; 1482 s->insn_read = das1800_ai_rinsn; 1483 if (dev->irq) { 1484 dev->read_subdev = s; 1485 s->subdev_flags |= SDF_CMD_READ; 1486 s->len_chanlist = s->n_chan; 1487 s->do_cmd = das1800_ai_do_cmd; 1488 s->do_cmdtest = das1800_ai_do_cmdtest; 1489 s->poll = das1800_ai_poll; 1490 s->cancel = das1800_cancel; 1491 } 1492 1493 /* analog out */ 1494 s = &dev->subdevices[1]; 1495 if (thisboard->ao_ability == 1) { 1496 s->type = COMEDI_SUBD_AO; 1497 s->subdev_flags = SDF_WRITABLE; 1498 s->n_chan = thisboard->ao_n_chan; 1499 s->maxdata = (1 << thisboard->resolution) - 1; 1500 s->range_table = &range_bipolar10; 1501 s->insn_write = das1800_ao_winsn; 1502 } else { 1503 s->type = COMEDI_SUBD_UNUSED; 1504 } 1505 1506 /* di */ 1507 s = &dev->subdevices[2]; 1508 s->type = COMEDI_SUBD_DI; 1509 s->subdev_flags = SDF_READABLE; 1510 s->n_chan = 4; 1511 s->maxdata = 1; 1512 s->range_table = &range_digital; 1513 s->insn_bits = das1800_di_rbits; 1514 1515 /* do */ 1516 s = &dev->subdevices[3]; 1517 s->type = COMEDI_SUBD_DO; 1518 s->subdev_flags = SDF_WRITABLE | SDF_READABLE; 1519 s->n_chan = thisboard->do_n_chan; 1520 s->maxdata = 1; 1521 s->range_table = &range_digital; 1522 s->insn_bits = das1800_do_wbits; 1523 1524 das1800_cancel(dev, dev->read_subdev); 1525 1526 /* initialize digital out channels */ 1527 outb(0, dev->iobase + DAS1800_DIGITAL); 1528 1529 /* initialize analog out channels */ 1530 if (thisboard->ao_ability == 1) { 1531 /* select 'update' dac channel for baseAddress + 0x0 */ 1532 outb(DAC(thisboard->ao_n_chan - 1), 1533 dev->iobase + DAS1800_SELECT); 1534 outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC); 1535 } 1536 1537 return 0; 1538}; 1539 1540static void das1800_detach(struct comedi_device *dev) 1541{ 1542 struct das1800_private *devpriv = dev->private; 1543 1544 if (devpriv) { 1545 if (devpriv->dma0) 1546 free_dma(devpriv->dma0); 1547 if (devpriv->dma1) 1548 free_dma(devpriv->dma1); 1549 kfree(devpriv->ai_buf0); 1550 kfree(devpriv->ai_buf1); 1551 if (devpriv->iobase2) 1552 release_region(devpriv->iobase2, DAS1800_SIZE); 1553 } 1554 comedi_legacy_detach(dev); 1555} 1556 1557static struct comedi_driver das1800_driver = { 1558 .driver_name = "das1800", 1559 .module = THIS_MODULE, 1560 .attach = das1800_attach, 1561 .detach = das1800_detach, 1562 .num_names = ARRAY_SIZE(das1800_boards), 1563 .board_name = &das1800_boards[0].name, 1564 .offset = sizeof(struct das1800_board), 1565}; 1566module_comedi_driver(das1800_driver); 1567 1568MODULE_AUTHOR("Comedi http://www.comedi.org"); 1569MODULE_DESCRIPTION("Comedi low-level driver"); 1570MODULE_LICENSE("GPL"); 1571