cb_pcidas.c revision cb9cfd7ed3f6ed4c40167b4251cdb382b6b3ba1c
1/* 2 comedi/drivers/cb_pcidas.c 3 4 Developed by Ivan Martinez and Frank Mori Hess, with valuable help from 5 David Schleef and the rest of the Comedi developers comunity. 6 7 Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk> 8 Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net> 9 10 COMEDI - Linux Control and Measurement Device Interface 11 Copyright (C) 1997-8 David A. Schleef <ds@schleef.org> 12 13 This program is free software; you can redistribute it and/or modify 14 it under the terms of the GNU General Public License as published by 15 the Free Software Foundation; either version 2 of the License, or 16 (at your option) any later version. 17 18 This program is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 GNU General Public License for more details. 22*/ 23/* 24Driver: cb_pcidas 25Description: MeasurementComputing PCI-DAS series 26 with the AMCC S5933 PCI controller 27Author: Ivan Martinez <imr@oersted.dtu.dk>, 28 Frank Mori Hess <fmhess@users.sourceforge.net> 29Updated: 2003-3-11 30Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas), 31 PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr, 32 PCI-DAS1000, PCI-DAS1001, PCI_DAS1002 33 34Status: 35 There are many reports of the driver being used with most of the 36 supported cards. Despite no detailed log is maintained, it can 37 be said that the driver is quite tested and stable. 38 39 The boards may be autocalibrated using the comedi_calibrate 40 utility. 41 42Configuration options: not applicable, uses PCI auto config 43 44For commands, the scanned channels must be consecutive 45(i.e. 4-5-6-7, 2-3-4,...), and must all have the same 46range and aref. 47 48AI Triggering: 49 For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used. 50 For 1602 series, the start_arg is interpreted as follows: 51 start_arg == 0 => gated trigger (level high) 52 start_arg == CR_INVERT => gated trigger (level low) 53 start_arg == CR_EDGE => Rising edge 54 start_arg == CR_EDGE | CR_INVERT => Falling edge 55 For the other boards the trigger will be done on rising edge 56*/ 57/* 58 59TODO: 60 61analog triggering on 1602 series 62*/ 63 64#include <linux/module.h> 65#include <linux/pci.h> 66#include <linux/delay.h> 67#include <linux/interrupt.h> 68 69#include "../comedidev.h" 70 71#include "8253.h" 72#include "8255.h" 73#include "amcc_s5933.h" 74#include "comedi_fc.h" 75 76#define AI_BUFFER_SIZE 1024 /* max ai fifo size */ 77#define AO_BUFFER_SIZE 1024 /* max ao fifo size */ 78#define NUM_CHANNELS_8800 8 79#define NUM_CHANNELS_7376 1 80#define NUM_CHANNELS_8402 2 81#define NUM_CHANNELS_DAC08 1 82 83/* Control/Status registers */ 84#define INT_ADCFIFO 0 /* INTERRUPT / ADC FIFO register */ 85#define INT_EOS 0x1 /* int end of scan */ 86#define INT_FHF 0x2 /* int fifo half full */ 87#define INT_FNE 0x3 /* int fifo not empty */ 88#define INT_MASK 0x3 /* mask of int select bits */ 89#define INTE 0x4 /* int enable */ 90#define DAHFIE 0x8 /* dac half full int enable */ 91#define EOAIE 0x10 /* end of acq. int enable */ 92#define DAHFI 0x20 /* dac half full status / clear */ 93#define EOAI 0x40 /* end of acq. int status / clear */ 94#define INT 0x80 /* int status / clear */ 95#define EOBI 0x200 /* end of burst int status */ 96#define ADHFI 0x400 /* half-full int status */ 97#define ADNEI 0x800 /* fifo not empty int status (latch) */ 98#define ADNE 0x1000 /* fifo not empty status (realtime) */ 99#define DAEMIE 0x1000 /* dac empty int enable */ 100#define LADFUL 0x2000 /* fifo overflow / clear */ 101#define DAEMI 0x4000 /* dac fifo empty int status / clear */ 102 103#define ADCMUX_CONT 2 /* ADC CHANNEL MUX AND CONTROL reg */ 104#define BEGIN_SCAN(x) ((x) & 0xf) 105#define END_SCAN(x) (((x) & 0xf) << 4) 106#define GAIN_BITS(x) (((x) & 0x3) << 8) 107#define UNIP 0x800 /* Analog front-end unipolar mode */ 108#define SE 0x400 /* Inputs in single-ended mode */ 109#define PACER_MASK 0x3000 /* pacer source bits */ 110#define PACER_INT 0x1000 /* int. pacer */ 111#define PACER_EXT_FALL 0x2000 /* ext. falling edge */ 112#define PACER_EXT_RISE 0x3000 /* ext. rising edge */ 113#define EOC 0x4000 /* adc not busy */ 114 115#define TRIG_CONTSTAT 4 /* TRIGGER CONTROL/STATUS register */ 116#define SW_TRIGGER 0x1 /* software start trigger */ 117#define EXT_TRIGGER 0x2 /* ext. start trigger */ 118#define ANALOG_TRIGGER 0x3 /* ext. analog trigger */ 119#define TRIGGER_MASK 0x3 /* start trigger mask */ 120#define TGPOL 0x04 /* invert trigger (1602 only) */ 121#define TGSEL 0x08 /* edge/level trigerred (1602 only) */ 122#define TGEN 0x10 /* enable external start trigger */ 123#define BURSTE 0x20 /* burst mode enable */ 124#define XTRCL 0x80 /* clear external trigger */ 125 126#define CALIBRATION_REG 6 /* CALIBRATION register */ 127#define SELECT_8800_BIT 0x100 /* select 8800 caldac */ 128#define SELECT_TRIMPOT_BIT 0x200 /* select ad7376 trim pot */ 129#define SELECT_DAC08_BIT 0x400 /* select dac08 caldac */ 130#define CAL_SRC_BITS(x) (((x) & 0x7) << 11) 131#define CAL_EN_BIT 0x4000 /* calibration source enable */ 132#define SERIAL_DATA_IN_BIT 0x8000 /* serial data bit going to caldac */ 133 134#define DAC_CSR 0x8 /* dac control and status register */ 135#define DACEN 0x02 /* dac enable */ 136#define DAC_MODE_UPDATE_BOTH 0x80 /* update both dacs */ 137 138static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range) 139{ 140 return (range & 0x3) << (8 + 2 * (channel & 0x1)); 141} 142 143static inline unsigned int DAC_RANGE_MASK(unsigned int channel) 144{ 145 return 0x3 << (8 + 2 * (channel & 0x1)); 146}; 147 148/* bits for 1602 series only */ 149#define DAC_EMPTY 0x1 /* fifo empty, read, write clear */ 150#define DAC_START 0x4 /* start/arm fifo operations */ 151#define DAC_PACER_MASK 0x18 /* bits that set pacer source */ 152#define DAC_PACER_INT 0x8 /* int. pacing */ 153#define DAC_PACER_EXT_FALL 0x10 /* ext. pacing, falling edge */ 154#define DAC_PACER_EXT_RISE 0x18 /* ext. pacing, rising edge */ 155 156static inline unsigned int DAC_CHAN_EN(unsigned int channel) 157{ 158 return 1 << (5 + (channel & 0x1)); /* enable channel 0 or 1 */ 159}; 160 161/* analog input fifo */ 162#define ADCDATA 0 /* ADC DATA register */ 163#define ADCFIFOCLR 2 /* ADC FIFO CLEAR */ 164 165/* pacer, counter, dio registers */ 166#define ADC8254 0 167#define DIO_8255 4 168#define DAC8254 8 169 170/* analog output registers for 100x, 1200 series */ 171static inline unsigned int DAC_DATA_REG(unsigned int channel) 172{ 173 return 2 * (channel & 0x1); 174} 175 176/* analog output registers for 1602 series*/ 177#define DACDATA 0 /* DAC DATA register */ 178#define DACFIFOCLR 2 /* DAC FIFO CLEAR */ 179 180#define IS_UNIPOLAR 0x4 /* unipolar range mask */ 181 182/* analog input ranges for most boards */ 183static const struct comedi_lrange cb_pcidas_ranges = { 184 8, 185 { 186 BIP_RANGE(10), 187 BIP_RANGE(5), 188 BIP_RANGE(2.5), 189 BIP_RANGE(1.25), 190 UNI_RANGE(10), 191 UNI_RANGE(5), 192 UNI_RANGE(2.5), 193 UNI_RANGE(1.25) 194 } 195}; 196 197/* pci-das1001 input ranges */ 198static const struct comedi_lrange cb_pcidas_alt_ranges = { 199 8, 200 { 201 BIP_RANGE(10), 202 BIP_RANGE(1), 203 BIP_RANGE(0.1), 204 BIP_RANGE(0.01), 205 UNI_RANGE(10), 206 UNI_RANGE(1), 207 UNI_RANGE(0.1), 208 UNI_RANGE(0.01) 209 } 210}; 211 212/* analog output ranges */ 213static const struct comedi_lrange cb_pcidas_ao_ranges = { 214 4, 215 { 216 BIP_RANGE(5), 217 BIP_RANGE(10), 218 UNI_RANGE(5), 219 UNI_RANGE(10), 220 } 221}; 222 223enum trimpot_model { 224 AD7376, 225 AD8402, 226}; 227 228enum cb_pcidas_boardid { 229 BOARD_PCIDAS1602_16, 230 BOARD_PCIDAS1200, 231 BOARD_PCIDAS1602_12, 232 BOARD_PCIDAS1200_JR, 233 BOARD_PCIDAS1602_16_JR, 234 BOARD_PCIDAS1000, 235 BOARD_PCIDAS1001, 236 BOARD_PCIDAS1002, 237}; 238 239struct cb_pcidas_board { 240 const char *name; 241 int ai_nchan; /* Inputs in single-ended mode */ 242 int ai_bits; /* analog input resolution */ 243 int ai_speed; /* fastest conversion period in ns */ 244 int ao_nchan; /* number of analog out channels */ 245 int has_ao_fifo; /* analog output has fifo */ 246 int ao_scan_speed; /* analog output scan speed for 1602 series */ 247 int fifo_size; /* number of samples fifo can hold */ 248 const struct comedi_lrange *ranges; 249 enum trimpot_model trimpot; 250 unsigned has_dac08:1; 251 unsigned is_1602:1; 252}; 253 254static const struct cb_pcidas_board cb_pcidas_boards[] = { 255 [BOARD_PCIDAS1602_16] = { 256 .name = "pci-das1602/16", 257 .ai_nchan = 16, 258 .ai_bits = 16, 259 .ai_speed = 5000, 260 .ao_nchan = 2, 261 .has_ao_fifo = 1, 262 .ao_scan_speed = 10000, 263 .fifo_size = 512, 264 .ranges = &cb_pcidas_ranges, 265 .trimpot = AD8402, 266 .has_dac08 = 1, 267 .is_1602 = 1, 268 }, 269 [BOARD_PCIDAS1200] = { 270 .name = "pci-das1200", 271 .ai_nchan = 16, 272 .ai_bits = 12, 273 .ai_speed = 3200, 274 .ao_nchan = 2, 275 .fifo_size = 1024, 276 .ranges = &cb_pcidas_ranges, 277 .trimpot = AD7376, 278 }, 279 [BOARD_PCIDAS1602_12] = { 280 .name = "pci-das1602/12", 281 .ai_nchan = 16, 282 .ai_bits = 12, 283 .ai_speed = 3200, 284 .ao_nchan = 2, 285 .has_ao_fifo = 1, 286 .ao_scan_speed = 4000, 287 .fifo_size = 1024, 288 .ranges = &cb_pcidas_ranges, 289 .trimpot = AD7376, 290 .is_1602 = 1, 291 }, 292 [BOARD_PCIDAS1200_JR] = { 293 .name = "pci-das1200/jr", 294 .ai_nchan = 16, 295 .ai_bits = 12, 296 .ai_speed = 3200, 297 .fifo_size = 1024, 298 .ranges = &cb_pcidas_ranges, 299 .trimpot = AD7376, 300 }, 301 [BOARD_PCIDAS1602_16_JR] = { 302 .name = "pci-das1602/16/jr", 303 .ai_nchan = 16, 304 .ai_bits = 16, 305 .ai_speed = 5000, 306 .fifo_size = 512, 307 .ranges = &cb_pcidas_ranges, 308 .trimpot = AD8402, 309 .has_dac08 = 1, 310 .is_1602 = 1, 311 }, 312 [BOARD_PCIDAS1000] = { 313 .name = "pci-das1000", 314 .ai_nchan = 16, 315 .ai_bits = 12, 316 .ai_speed = 4000, 317 .fifo_size = 1024, 318 .ranges = &cb_pcidas_ranges, 319 .trimpot = AD7376, 320 }, 321 [BOARD_PCIDAS1001] = { 322 .name = "pci-das1001", 323 .ai_nchan = 16, 324 .ai_bits = 12, 325 .ai_speed = 6800, 326 .ao_nchan = 2, 327 .fifo_size = 1024, 328 .ranges = &cb_pcidas_alt_ranges, 329 .trimpot = AD7376, 330 }, 331 [BOARD_PCIDAS1002] = { 332 .name = "pci-das1002", 333 .ai_nchan = 16, 334 .ai_bits = 12, 335 .ai_speed = 6800, 336 .ao_nchan = 2, 337 .fifo_size = 1024, 338 .ranges = &cb_pcidas_ranges, 339 .trimpot = AD7376, 340 }, 341}; 342 343struct cb_pcidas_private { 344 /* base addresses */ 345 unsigned long s5933_config; 346 unsigned long control_status; 347 unsigned long adc_fifo; 348 unsigned long pacer_counter_dio; 349 unsigned long ao_registers; 350 /* divisors of master clock for analog input pacing */ 351 unsigned int divisor1; 352 unsigned int divisor2; 353 /* number of analog input samples remaining */ 354 unsigned int count; 355 /* bits to write to registers */ 356 unsigned int adc_fifo_bits; 357 unsigned int s5933_intcsr_bits; 358 unsigned int ao_control_bits; 359 /* fifo buffers */ 360 short ai_buffer[AI_BUFFER_SIZE]; 361 short ao_buffer[AO_BUFFER_SIZE]; 362 /* divisors of master clock for analog output pacing */ 363 unsigned int ao_divisor1; 364 unsigned int ao_divisor2; 365 /* number of analog output samples remaining */ 366 unsigned int ao_count; 367 /* cached values for readback */ 368 int ao_value[2]; 369 unsigned int caldac_value[NUM_CHANNELS_8800]; 370 unsigned int trimpot_value[NUM_CHANNELS_8402]; 371 unsigned int dac08_value; 372 unsigned int calibration_source; 373}; 374 375static inline unsigned int cal_enable_bits(struct comedi_device *dev) 376{ 377 struct cb_pcidas_private *devpriv = dev->private; 378 379 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source); 380} 381 382static int cb_pcidas_ai_rinsn(struct comedi_device *dev, 383 struct comedi_subdevice *s, 384 struct comedi_insn *insn, unsigned int *data) 385{ 386 struct cb_pcidas_private *devpriv = dev->private; 387 unsigned int chan = CR_CHAN(insn->chanspec); 388 unsigned int range = CR_RANGE(insn->chanspec); 389 unsigned int aref = CR_AREF(insn->chanspec); 390 unsigned int bits; 391 int n, i; 392 393 /* enable calibration input if appropriate */ 394 if (insn->chanspec & CR_ALT_SOURCE) { 395 outw(cal_enable_bits(dev), 396 devpriv->control_status + CALIBRATION_REG); 397 chan = 0; 398 } else { 399 outw(0, devpriv->control_status + CALIBRATION_REG); 400 } 401 402 /* set mux limits and gain */ 403 bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range); 404 /* set unipolar/bipolar */ 405 if (range & IS_UNIPOLAR) 406 bits |= UNIP; 407 /* set single-ended/differential */ 408 if (aref != AREF_DIFF) 409 bits |= SE; 410 outw(bits, devpriv->control_status + ADCMUX_CONT); 411 412 /* clear fifo */ 413 outw(0, devpriv->adc_fifo + ADCFIFOCLR); 414 415 /* convert n samples */ 416 for (n = 0; n < insn->n; n++) { 417 /* trigger conversion */ 418 outw(0, devpriv->adc_fifo + ADCDATA); 419 420 /* wait for conversion to end */ 421 /* return -ETIMEDOUT if there is a timeout */ 422 for (i = 0; i < 10000; i++) { 423 if (inw(devpriv->control_status + ADCMUX_CONT) & EOC) 424 break; 425 } 426 if (i == 10000) 427 return -ETIMEDOUT; 428 429 /* read data */ 430 data[n] = inw(devpriv->adc_fifo + ADCDATA); 431 } 432 433 /* return the number of samples read/written */ 434 return n; 435} 436 437static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, 438 struct comedi_insn *insn, unsigned int *data) 439{ 440 struct cb_pcidas_private *devpriv = dev->private; 441 int id = data[0]; 442 unsigned int source = data[1]; 443 444 switch (id) { 445 case INSN_CONFIG_ALT_SOURCE: 446 if (source >= 8) { 447 dev_err(dev->class_dev, 448 "invalid calibration source: %i\n", 449 source); 450 return -EINVAL; 451 } 452 devpriv->calibration_source = source; 453 break; 454 default: 455 return -EINVAL; 456 break; 457 } 458 return insn->n; 459} 460 461/* analog output insn for pcidas-1000 and 1200 series */ 462static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, 463 struct comedi_subdevice *s, 464 struct comedi_insn *insn, 465 unsigned int *data) 466{ 467 struct cb_pcidas_private *devpriv = dev->private; 468 unsigned int chan = CR_CHAN(insn->chanspec); 469 unsigned int range = CR_RANGE(insn->chanspec); 470 unsigned long flags; 471 472 /* set channel and range */ 473 spin_lock_irqsave(&dev->spinlock, flags); 474 devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH & 475 ~DAC_RANGE_MASK(chan)); 476 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range)); 477 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 478 spin_unlock_irqrestore(&dev->spinlock, flags); 479 480 /* remember value for readback */ 481 devpriv->ao_value[chan] = data[0]; 482 483 /* send data */ 484 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan)); 485 486 return insn->n; 487} 488 489/* analog output insn for pcidas-1602 series */ 490static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, 491 struct comedi_subdevice *s, 492 struct comedi_insn *insn, unsigned int *data) 493{ 494 struct cb_pcidas_private *devpriv = dev->private; 495 unsigned int chan = CR_CHAN(insn->chanspec); 496 unsigned int range = CR_RANGE(insn->chanspec); 497 unsigned long flags; 498 499 /* clear dac fifo */ 500 outw(0, devpriv->ao_registers + DACFIFOCLR); 501 502 /* set channel and range */ 503 spin_lock_irqsave(&dev->spinlock, flags); 504 devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & 505 ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK); 506 devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) | 507 DAC_CHAN_EN(chan) | DAC_START); 508 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 509 spin_unlock_irqrestore(&dev->spinlock, flags); 510 511 /* remember value for readback */ 512 devpriv->ao_value[chan] = data[0]; 513 514 /* send data */ 515 outw(data[0], devpriv->ao_registers + DACDATA); 516 517 return insn->n; 518} 519 520static int cb_pcidas_ao_readback_insn(struct comedi_device *dev, 521 struct comedi_subdevice *s, 522 struct comedi_insn *insn, 523 unsigned int *data) 524{ 525 struct cb_pcidas_private *devpriv = dev->private; 526 527 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; 528 529 return 1; 530} 531 532static int wait_for_nvram_ready(unsigned long s5933_base_addr) 533{ 534 static const int timeout = 1000; 535 unsigned int i; 536 537 for (i = 0; i < timeout; i++) { 538 if ((inb(s5933_base_addr + 539 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY) 540 == 0) 541 return 0; 542 udelay(1); 543 } 544 return -1; 545} 546 547static int nvram_read(struct comedi_device *dev, unsigned int address, 548 uint8_t *data) 549{ 550 struct cb_pcidas_private *devpriv = dev->private; 551 unsigned long iobase = devpriv->s5933_config; 552 553 if (wait_for_nvram_ready(iobase) < 0) 554 return -ETIMEDOUT; 555 556 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR, 557 iobase + AMCC_OP_REG_MCSR_NVCMD); 558 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 559 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR, 560 iobase + AMCC_OP_REG_MCSR_NVCMD); 561 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 562 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); 563 564 if (wait_for_nvram_ready(iobase) < 0) 565 return -ETIMEDOUT; 566 567 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); 568 569 return 0; 570} 571 572static int eeprom_read_insn(struct comedi_device *dev, 573 struct comedi_subdevice *s, 574 struct comedi_insn *insn, unsigned int *data) 575{ 576 uint8_t nvram_data; 577 int retval; 578 579 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data); 580 if (retval < 0) 581 return retval; 582 583 data[0] = nvram_data; 584 585 return 1; 586} 587 588static void write_calibration_bitstream(struct comedi_device *dev, 589 unsigned int register_bits, 590 unsigned int bitstream, 591 unsigned int bitstream_length) 592{ 593 struct cb_pcidas_private *devpriv = dev->private; 594 static const int write_delay = 1; 595 unsigned int bit; 596 597 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { 598 if (bitstream & bit) 599 register_bits |= SERIAL_DATA_IN_BIT; 600 else 601 register_bits &= ~SERIAL_DATA_IN_BIT; 602 udelay(write_delay); 603 outw(register_bits, devpriv->control_status + CALIBRATION_REG); 604 } 605} 606 607static int caldac_8800_write(struct comedi_device *dev, unsigned int address, 608 uint8_t value) 609{ 610 struct cb_pcidas_private *devpriv = dev->private; 611 static const int num_caldac_channels = 8; 612 static const int bitstream_length = 11; 613 unsigned int bitstream = ((address & 0x7) << 8) | value; 614 static const int caldac_8800_udelay = 1; 615 616 if (address >= num_caldac_channels) { 617 comedi_error(dev, "illegal caldac channel"); 618 return -1; 619 } 620 621 if (value == devpriv->caldac_value[address]) 622 return 1; 623 624 devpriv->caldac_value[address] = value; 625 626 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream, 627 bitstream_length); 628 629 udelay(caldac_8800_udelay); 630 outw(cal_enable_bits(dev) | SELECT_8800_BIT, 631 devpriv->control_status + CALIBRATION_REG); 632 udelay(caldac_8800_udelay); 633 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 634 635 return 1; 636} 637 638static int caldac_write_insn(struct comedi_device *dev, 639 struct comedi_subdevice *s, 640 struct comedi_insn *insn, unsigned int *data) 641{ 642 const unsigned int channel = CR_CHAN(insn->chanspec); 643 644 return caldac_8800_write(dev, channel, data[0]); 645} 646 647static int caldac_read_insn(struct comedi_device *dev, 648 struct comedi_subdevice *s, 649 struct comedi_insn *insn, unsigned int *data) 650{ 651 struct cb_pcidas_private *devpriv = dev->private; 652 653 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)]; 654 655 return 1; 656} 657 658/* 1602/16 pregain offset */ 659static void dac08_write(struct comedi_device *dev, unsigned int value) 660{ 661 struct cb_pcidas_private *devpriv = dev->private; 662 unsigned long cal_reg; 663 664 if (devpriv->dac08_value != value) { 665 devpriv->dac08_value = value; 666 667 cal_reg = devpriv->control_status + CALIBRATION_REG; 668 669 value &= 0xff; 670 value |= cal_enable_bits(dev); 671 672 /* latch the new value into the caldac */ 673 outw(value, cal_reg); 674 udelay(1); 675 outw(value | SELECT_DAC08_BIT, cal_reg); 676 udelay(1); 677 outw(value, cal_reg); 678 udelay(1); 679 } 680} 681 682static int dac08_write_insn(struct comedi_device *dev, 683 struct comedi_subdevice *s, 684 struct comedi_insn *insn, unsigned int *data) 685{ 686 int i; 687 688 for (i = 0; i < insn->n; i++) 689 dac08_write(dev, data[i]); 690 691 return insn->n; 692} 693 694static int dac08_read_insn(struct comedi_device *dev, 695 struct comedi_subdevice *s, struct comedi_insn *insn, 696 unsigned int *data) 697{ 698 struct cb_pcidas_private *devpriv = dev->private; 699 700 data[0] = devpriv->dac08_value; 701 702 return 1; 703} 704 705static int trimpot_7376_write(struct comedi_device *dev, uint8_t value) 706{ 707 struct cb_pcidas_private *devpriv = dev->private; 708 static const int bitstream_length = 7; 709 unsigned int bitstream = value & 0x7f; 710 unsigned int register_bits; 711 static const int ad7376_udelay = 1; 712 713 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 714 udelay(ad7376_udelay); 715 outw(register_bits, devpriv->control_status + CALIBRATION_REG); 716 717 write_calibration_bitstream(dev, register_bits, bitstream, 718 bitstream_length); 719 720 udelay(ad7376_udelay); 721 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 722 723 return 0; 724} 725 726/* For 1602/16 only 727 * ch 0 : adc gain 728 * ch 1 : adc postgain offset */ 729static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 730 uint8_t value) 731{ 732 struct cb_pcidas_private *devpriv = dev->private; 733 static const int bitstream_length = 10; 734 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff); 735 unsigned int register_bits; 736 static const int ad8402_udelay = 1; 737 738 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 739 udelay(ad8402_udelay); 740 outw(register_bits, devpriv->control_status + CALIBRATION_REG); 741 742 write_calibration_bitstream(dev, register_bits, bitstream, 743 bitstream_length); 744 745 udelay(ad8402_udelay); 746 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 747 748 return 0; 749} 750 751static int cb_pcidas_trimpot_write(struct comedi_device *dev, 752 unsigned int channel, unsigned int value) 753{ 754 const struct cb_pcidas_board *thisboard = comedi_board(dev); 755 struct cb_pcidas_private *devpriv = dev->private; 756 757 if (devpriv->trimpot_value[channel] == value) 758 return 1; 759 760 devpriv->trimpot_value[channel] = value; 761 switch (thisboard->trimpot) { 762 case AD7376: 763 trimpot_7376_write(dev, value); 764 break; 765 case AD8402: 766 trimpot_8402_write(dev, channel, value); 767 break; 768 default: 769 comedi_error(dev, "driver bug?"); 770 return -1; 771 break; 772 } 773 774 return 1; 775} 776 777static int trimpot_write_insn(struct comedi_device *dev, 778 struct comedi_subdevice *s, 779 struct comedi_insn *insn, unsigned int *data) 780{ 781 unsigned int channel = CR_CHAN(insn->chanspec); 782 783 return cb_pcidas_trimpot_write(dev, channel, data[0]); 784} 785 786static int trimpot_read_insn(struct comedi_device *dev, 787 struct comedi_subdevice *s, 788 struct comedi_insn *insn, unsigned int *data) 789{ 790 struct cb_pcidas_private *devpriv = dev->private; 791 unsigned int channel = CR_CHAN(insn->chanspec); 792 793 data[0] = devpriv->trimpot_value[channel]; 794 795 return 1; 796} 797 798static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, 799 struct comedi_subdevice *s, 800 struct comedi_cmd *cmd) 801{ 802 const struct cb_pcidas_board *thisboard = comedi_board(dev); 803 struct cb_pcidas_private *devpriv = dev->private; 804 int err = 0; 805 int tmp; 806 int i, gain, start_chan; 807 808 /* Step 1 : check if triggers are trivially valid */ 809 810 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); 811 err |= cfc_check_trigger_src(&cmd->scan_begin_src, 812 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT); 813 err |= cfc_check_trigger_src(&cmd->convert_src, 814 TRIG_TIMER | TRIG_NOW | TRIG_EXT); 815 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 816 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 817 818 if (err) 819 return 1; 820 821 /* Step 2a : make sure trigger sources are unique */ 822 823 err |= cfc_check_trigger_is_unique(cmd->start_src); 824 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); 825 err |= cfc_check_trigger_is_unique(cmd->convert_src); 826 err |= cfc_check_trigger_is_unique(cmd->stop_src); 827 828 /* Step 2b : and mutually compatible */ 829 830 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) 831 err |= -EINVAL; 832 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) 833 err |= -EINVAL; 834 if (cmd->start_src == TRIG_EXT && 835 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)) 836 err |= -EINVAL; 837 838 if (err) 839 return 2; 840 841 /* step 3: arguments are trivially compatible */ 842 843 switch (cmd->start_src) { 844 case TRIG_EXT: 845 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */ 846 if ((cmd->start_arg 847 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) { 848 cmd->start_arg &= ~(CR_FLAGS_MASK & 849 ~(CR_EDGE | CR_INVERT)); 850 err |= -EINVAL; 851 } 852 if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) { 853 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT); 854 err |= -EINVAL; 855 } 856 break; 857 default: 858 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 859 break; 860 } 861 862 if (cmd->scan_begin_src == TRIG_TIMER) 863 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 864 thisboard->ai_speed * cmd->chanlist_len); 865 866 if (cmd->convert_src == TRIG_TIMER) 867 err |= cfc_check_trigger_arg_min(&cmd->convert_arg, 868 thisboard->ai_speed); 869 870 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 871 872 if (cmd->stop_src == TRIG_NONE) 873 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 874 875 if (err) 876 return 3; 877 878 /* step 4: fix up any arguments */ 879 880 if (cmd->scan_begin_src == TRIG_TIMER) { 881 tmp = cmd->scan_begin_arg; 882 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, 883 &devpriv->divisor1, 884 &devpriv->divisor2, 885 &cmd->scan_begin_arg, cmd->flags); 886 if (tmp != cmd->scan_begin_arg) 887 err++; 888 } 889 if (cmd->convert_src == TRIG_TIMER) { 890 tmp = cmd->convert_arg; 891 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, 892 &devpriv->divisor1, 893 &devpriv->divisor2, 894 &cmd->convert_arg, cmd->flags); 895 if (tmp != cmd->convert_arg) 896 err++; 897 } 898 899 if (err) 900 return 4; 901 902 /* check channel/gain list against card's limitations */ 903 if (cmd->chanlist) { 904 gain = CR_RANGE(cmd->chanlist[0]); 905 start_chan = CR_CHAN(cmd->chanlist[0]); 906 for (i = 1; i < cmd->chanlist_len; i++) { 907 if (CR_CHAN(cmd->chanlist[i]) != 908 (start_chan + i) % s->n_chan) { 909 comedi_error(dev, 910 "entries in chanlist must be consecutive channels, counting upwards\n"); 911 err++; 912 } 913 if (CR_RANGE(cmd->chanlist[i]) != gain) { 914 comedi_error(dev, 915 "entries in chanlist must all have the same gain\n"); 916 err++; 917 } 918 } 919 } 920 921 if (err) 922 return 5; 923 924 return 0; 925} 926 927static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns, 928 int rounding_flags) 929{ 930 struct cb_pcidas_private *devpriv = dev->private; 931 932 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, 933 &devpriv->divisor1, &devpriv->divisor2, 934 ns, rounding_flags); 935 936 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 937 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1, 938 devpriv->divisor1, 2); 939 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2, 940 devpriv->divisor2, 2); 941} 942 943static int cb_pcidas_ai_cmd(struct comedi_device *dev, 944 struct comedi_subdevice *s) 945{ 946 const struct cb_pcidas_board *thisboard = comedi_board(dev); 947 struct cb_pcidas_private *devpriv = dev->private; 948 struct comedi_async *async = s->async; 949 struct comedi_cmd *cmd = &async->cmd; 950 unsigned int bits; 951 unsigned long flags; 952 953 /* make sure CAL_EN_BIT is disabled */ 954 outw(0, devpriv->control_status + CALIBRATION_REG); 955 /* initialize before settings pacer source and count values */ 956 outw(0, devpriv->control_status + TRIG_CONTSTAT); 957 /* clear fifo */ 958 outw(0, devpriv->adc_fifo + ADCFIFOCLR); 959 960 /* set mux limits, gain and pacer source */ 961 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) | 962 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) | 963 GAIN_BITS(CR_RANGE(cmd->chanlist[0])); 964 /* set unipolar/bipolar */ 965 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR) 966 bits |= UNIP; 967 /* set singleended/differential */ 968 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF) 969 bits |= SE; 970 /* set pacer source */ 971 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT) 972 bits |= PACER_EXT_RISE; 973 else 974 bits |= PACER_INT; 975 outw(bits, devpriv->control_status + ADCMUX_CONT); 976 977 /* load counters */ 978 if (cmd->convert_src == TRIG_TIMER) 979 cb_pcidas_load_counters(dev, &cmd->convert_arg, 980 cmd->flags & TRIG_ROUND_MASK); 981 else if (cmd->scan_begin_src == TRIG_TIMER) 982 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg, 983 cmd->flags & TRIG_ROUND_MASK); 984 985 /* set number of conversions */ 986 if (cmd->stop_src == TRIG_COUNT) 987 devpriv->count = cmd->chanlist_len * cmd->stop_arg; 988 /* enable interrupts */ 989 spin_lock_irqsave(&dev->spinlock, flags); 990 devpriv->adc_fifo_bits |= INTE; 991 devpriv->adc_fifo_bits &= ~INT_MASK; 992 if (cmd->flags & TRIG_WAKE_EOS) { 993 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) { 994 /* interrupt end of burst */ 995 devpriv->adc_fifo_bits |= INT_EOS; 996 } else { 997 /* interrupt fifo not empty */ 998 devpriv->adc_fifo_bits |= INT_FNE; 999 } 1000 } else { 1001 /* interrupt fifo half full */ 1002 devpriv->adc_fifo_bits |= INT_FHF; 1003 } 1004 1005 /* enable (and clear) interrupts */ 1006 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL, 1007 devpriv->control_status + INT_ADCFIFO); 1008 spin_unlock_irqrestore(&dev->spinlock, flags); 1009 1010 /* set start trigger and burst mode */ 1011 bits = 0; 1012 if (cmd->start_src == TRIG_NOW) 1013 bits |= SW_TRIGGER; 1014 else if (cmd->start_src == TRIG_EXT) { 1015 bits |= EXT_TRIGGER | TGEN | XTRCL; 1016 if (thisboard->is_1602) { 1017 if (cmd->start_arg & CR_INVERT) 1018 bits |= TGPOL; 1019 if (cmd->start_arg & CR_EDGE) 1020 bits |= TGSEL; 1021 } 1022 } else { 1023 comedi_error(dev, "bug!"); 1024 return -1; 1025 } 1026 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 1027 bits |= BURSTE; 1028 outw(bits, devpriv->control_status + TRIG_CONTSTAT); 1029 1030 return 0; 1031} 1032 1033static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, 1034 struct comedi_subdevice *s, 1035 struct comedi_cmd *cmd) 1036{ 1037 const struct cb_pcidas_board *thisboard = comedi_board(dev); 1038 struct cb_pcidas_private *devpriv = dev->private; 1039 int err = 0; 1040 int tmp; 1041 1042 /* Step 1 : check if triggers are trivially valid */ 1043 1044 err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT); 1045 err |= cfc_check_trigger_src(&cmd->scan_begin_src, 1046 TRIG_TIMER | TRIG_EXT); 1047 err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW); 1048 err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 1049 err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 1050 1051 if (err) 1052 return 1; 1053 1054 /* Step 2a : make sure trigger sources are unique */ 1055 1056 err |= cfc_check_trigger_is_unique(cmd->scan_begin_src); 1057 err |= cfc_check_trigger_is_unique(cmd->stop_src); 1058 1059 /* Step 2b : and mutually compatible */ 1060 1061 if (err) 1062 return 2; 1063 1064 /* Step 3: check if arguments are trivially valid */ 1065 1066 err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0); 1067 1068 if (cmd->scan_begin_src == TRIG_TIMER) 1069 err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 1070 thisboard->ao_scan_speed); 1071 1072 err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len); 1073 1074 if (cmd->stop_src == TRIG_NONE) 1075 err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0); 1076 1077 if (err) 1078 return 3; 1079 1080 /* step 4: fix up any arguments */ 1081 1082 if (cmd->scan_begin_src == TRIG_TIMER) { 1083 tmp = cmd->scan_begin_arg; 1084 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, 1085 &devpriv->ao_divisor1, 1086 &devpriv->ao_divisor2, 1087 &cmd->scan_begin_arg, cmd->flags); 1088 if (tmp != cmd->scan_begin_arg) 1089 err++; 1090 } 1091 1092 if (err) 1093 return 4; 1094 1095 /* check channel/gain list against card's limitations */ 1096 if (cmd->chanlist && cmd->chanlist_len > 1) { 1097 if (CR_CHAN(cmd->chanlist[0]) != 0 || 1098 CR_CHAN(cmd->chanlist[1]) != 1) { 1099 comedi_error(dev, 1100 "channels must be ordered channel 0, channel 1 in chanlist\n"); 1101 err++; 1102 } 1103 } 1104 1105 if (err) 1106 return 5; 1107 1108 return 0; 1109} 1110 1111/* cancel analog input command */ 1112static int cb_pcidas_cancel(struct comedi_device *dev, 1113 struct comedi_subdevice *s) 1114{ 1115 struct cb_pcidas_private *devpriv = dev->private; 1116 unsigned long flags; 1117 1118 spin_lock_irqsave(&dev->spinlock, flags); 1119 /* disable interrupts */ 1120 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE; 1121 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 1122 spin_unlock_irqrestore(&dev->spinlock, flags); 1123 1124 /* disable start trigger source and burst mode */ 1125 outw(0, devpriv->control_status + TRIG_CONTSTAT); 1126 /* software pacer source */ 1127 outw(0, devpriv->control_status + ADCMUX_CONT); 1128 1129 return 0; 1130} 1131 1132static int cb_pcidas_ao_inttrig(struct comedi_device *dev, 1133 struct comedi_subdevice *s, 1134 unsigned int trig_num) 1135{ 1136 const struct cb_pcidas_board *thisboard = comedi_board(dev); 1137 struct cb_pcidas_private *devpriv = dev->private; 1138 unsigned int num_bytes, num_points = thisboard->fifo_size; 1139 struct comedi_async *async = s->async; 1140 struct comedi_cmd *cmd = &s->async->cmd; 1141 unsigned long flags; 1142 1143 if (trig_num != 0) 1144 return -EINVAL; 1145 1146 /* load up fifo */ 1147 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points) 1148 num_points = devpriv->ao_count; 1149 1150 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer, 1151 num_points * sizeof(short)); 1152 num_points = num_bytes / sizeof(short); 1153 1154 if (cmd->stop_src == TRIG_COUNT) 1155 devpriv->ao_count -= num_points; 1156 /* write data to board's fifo */ 1157 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); 1158 1159 /* enable dac half-full and empty interrupts */ 1160 spin_lock_irqsave(&dev->spinlock, flags); 1161 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE; 1162 1163 /* enable and clear interrupts */ 1164 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI, 1165 devpriv->control_status + INT_ADCFIFO); 1166 1167 /* start dac */ 1168 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY; 1169 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 1170 1171 spin_unlock_irqrestore(&dev->spinlock, flags); 1172 1173 async->inttrig = NULL; 1174 1175 return 0; 1176} 1177 1178static int cb_pcidas_ao_cmd(struct comedi_device *dev, 1179 struct comedi_subdevice *s) 1180{ 1181 struct cb_pcidas_private *devpriv = dev->private; 1182 struct comedi_async *async = s->async; 1183 struct comedi_cmd *cmd = &async->cmd; 1184 unsigned int i; 1185 unsigned long flags; 1186 1187 /* set channel limits, gain */ 1188 spin_lock_irqsave(&dev->spinlock, flags); 1189 for (i = 0; i < cmd->chanlist_len; i++) { 1190 /* enable channel */ 1191 devpriv->ao_control_bits |= 1192 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i])); 1193 /* set range */ 1194 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]), 1195 CR_RANGE(cmd-> 1196 chanlist[i])); 1197 } 1198 1199 /* disable analog out before settings pacer source and count values */ 1200 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 1201 spin_unlock_irqrestore(&dev->spinlock, flags); 1202 1203 /* clear fifo */ 1204 outw(0, devpriv->ao_registers + DACFIFOCLR); 1205 1206 /* load counters */ 1207 if (cmd->scan_begin_src == TRIG_TIMER) { 1208 i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ, 1209 &devpriv->ao_divisor1, 1210 &devpriv->ao_divisor2, 1211 &cmd->scan_begin_arg, cmd->flags); 1212 1213 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 1214 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1, 1215 devpriv->ao_divisor1, 2); 1216 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2, 1217 devpriv->ao_divisor2, 2); 1218 } 1219 /* set number of conversions */ 1220 if (cmd->stop_src == TRIG_COUNT) 1221 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg; 1222 /* set pacer source */ 1223 spin_lock_irqsave(&dev->spinlock, flags); 1224 switch (cmd->scan_begin_src) { 1225 case TRIG_TIMER: 1226 devpriv->ao_control_bits |= DAC_PACER_INT; 1227 break; 1228 case TRIG_EXT: 1229 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE; 1230 break; 1231 default: 1232 spin_unlock_irqrestore(&dev->spinlock, flags); 1233 comedi_error(dev, "error setting dac pacer source"); 1234 return -1; 1235 break; 1236 } 1237 spin_unlock_irqrestore(&dev->spinlock, flags); 1238 1239 async->inttrig = cb_pcidas_ao_inttrig; 1240 1241 return 0; 1242} 1243 1244/* cancel analog output command */ 1245static int cb_pcidas_ao_cancel(struct comedi_device *dev, 1246 struct comedi_subdevice *s) 1247{ 1248 struct cb_pcidas_private *devpriv = dev->private; 1249 unsigned long flags; 1250 1251 spin_lock_irqsave(&dev->spinlock, flags); 1252 /* disable interrupts */ 1253 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE; 1254 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 1255 1256 /* disable output */ 1257 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK; 1258 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 1259 spin_unlock_irqrestore(&dev->spinlock, flags); 1260 1261 return 0; 1262} 1263 1264static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) 1265{ 1266 const struct cb_pcidas_board *thisboard = comedi_board(dev); 1267 struct cb_pcidas_private *devpriv = dev->private; 1268 struct comedi_subdevice *s = dev->write_subdev; 1269 struct comedi_async *async = s->async; 1270 struct comedi_cmd *cmd = &async->cmd; 1271 unsigned int half_fifo = thisboard->fifo_size / 2; 1272 unsigned int num_points; 1273 unsigned long flags; 1274 1275 async->events = 0; 1276 1277 if (status & DAEMI) { 1278 /* clear dac empty interrupt latch */ 1279 spin_lock_irqsave(&dev->spinlock, flags); 1280 outw(devpriv->adc_fifo_bits | DAEMI, 1281 devpriv->control_status + INT_ADCFIFO); 1282 spin_unlock_irqrestore(&dev->spinlock, flags); 1283 if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) { 1284 if (cmd->stop_src == TRIG_NONE || 1285 (cmd->stop_src == TRIG_COUNT 1286 && devpriv->ao_count)) { 1287 comedi_error(dev, "dac fifo underflow"); 1288 cb_pcidas_ao_cancel(dev, s); 1289 async->events |= COMEDI_CB_ERROR; 1290 } 1291 async->events |= COMEDI_CB_EOA; 1292 } 1293 } else if (status & DAHFI) { 1294 unsigned int num_bytes; 1295 1296 /* figure out how many points we are writing to fifo */ 1297 num_points = half_fifo; 1298 if (cmd->stop_src == TRIG_COUNT && 1299 devpriv->ao_count < num_points) 1300 num_points = devpriv->ao_count; 1301 num_bytes = 1302 cfc_read_array_from_buffer(s, devpriv->ao_buffer, 1303 num_points * sizeof(short)); 1304 num_points = num_bytes / sizeof(short); 1305 1306 if (async->cmd.stop_src == TRIG_COUNT) 1307 devpriv->ao_count -= num_points; 1308 /* write data to board's fifo */ 1309 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, 1310 num_points); 1311 /* clear half-full interrupt latch */ 1312 spin_lock_irqsave(&dev->spinlock, flags); 1313 outw(devpriv->adc_fifo_bits | DAHFI, 1314 devpriv->control_status + INT_ADCFIFO); 1315 spin_unlock_irqrestore(&dev->spinlock, flags); 1316 } 1317 1318 comedi_event(dev, s); 1319} 1320 1321static irqreturn_t cb_pcidas_interrupt(int irq, void *d) 1322{ 1323 struct comedi_device *dev = (struct comedi_device *)d; 1324 const struct cb_pcidas_board *thisboard = comedi_board(dev); 1325 struct cb_pcidas_private *devpriv = dev->private; 1326 struct comedi_subdevice *s = dev->read_subdev; 1327 struct comedi_async *async; 1328 int status, s5933_status; 1329 int half_fifo = thisboard->fifo_size / 2; 1330 unsigned int num_samples, i; 1331 static const int timeout = 10000; 1332 unsigned long flags; 1333 1334 if (!dev->attached) 1335 return IRQ_NONE; 1336 1337 async = s->async; 1338 async->events = 0; 1339 1340 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1341 1342 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0) 1343 return IRQ_NONE; 1344 1345 /* make sure mailbox 4 is empty */ 1346 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4); 1347 /* clear interrupt on amcc s5933 */ 1348 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 1349 devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1350 1351 status = inw(devpriv->control_status + INT_ADCFIFO); 1352 1353 /* check for analog output interrupt */ 1354 if (status & (DAHFI | DAEMI)) 1355 handle_ao_interrupt(dev, status); 1356 /* check for analog input interrupts */ 1357 /* if fifo half-full */ 1358 if (status & ADHFI) { 1359 /* read data */ 1360 num_samples = half_fifo; 1361 if (async->cmd.stop_src == TRIG_COUNT && 1362 num_samples > devpriv->count) { 1363 num_samples = devpriv->count; 1364 } 1365 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer, 1366 num_samples); 1367 cfc_write_array_to_buffer(s, devpriv->ai_buffer, 1368 num_samples * sizeof(short)); 1369 devpriv->count -= num_samples; 1370 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) { 1371 async->events |= COMEDI_CB_EOA; 1372 cb_pcidas_cancel(dev, s); 1373 } 1374 /* clear half-full interrupt latch */ 1375 spin_lock_irqsave(&dev->spinlock, flags); 1376 outw(devpriv->adc_fifo_bits | INT, 1377 devpriv->control_status + INT_ADCFIFO); 1378 spin_unlock_irqrestore(&dev->spinlock, flags); 1379 /* else if fifo not empty */ 1380 } else if (status & (ADNEI | EOBI)) { 1381 for (i = 0; i < timeout; i++) { 1382 /* break if fifo is empty */ 1383 if ((ADNE & inw(devpriv->control_status + 1384 INT_ADCFIFO)) == 0) 1385 break; 1386 cfc_write_to_buffer(s, inw(devpriv->adc_fifo)); 1387 if (async->cmd.stop_src == TRIG_COUNT && 1388 --devpriv->count == 0) { 1389 /* end of acquisition */ 1390 cb_pcidas_cancel(dev, s); 1391 async->events |= COMEDI_CB_EOA; 1392 break; 1393 } 1394 } 1395 /* clear not-empty interrupt latch */ 1396 spin_lock_irqsave(&dev->spinlock, flags); 1397 outw(devpriv->adc_fifo_bits | INT, 1398 devpriv->control_status + INT_ADCFIFO); 1399 spin_unlock_irqrestore(&dev->spinlock, flags); 1400 } else if (status & EOAI) { 1401 comedi_error(dev, 1402 "bug! encountered end of acquisition interrupt?"); 1403 /* clear EOA interrupt latch */ 1404 spin_lock_irqsave(&dev->spinlock, flags); 1405 outw(devpriv->adc_fifo_bits | EOAI, 1406 devpriv->control_status + INT_ADCFIFO); 1407 spin_unlock_irqrestore(&dev->spinlock, flags); 1408 } 1409 /* check for fifo overflow */ 1410 if (status & LADFUL) { 1411 comedi_error(dev, "fifo overflow"); 1412 /* clear overflow interrupt latch */ 1413 spin_lock_irqsave(&dev->spinlock, flags); 1414 outw(devpriv->adc_fifo_bits | LADFUL, 1415 devpriv->control_status + INT_ADCFIFO); 1416 spin_unlock_irqrestore(&dev->spinlock, flags); 1417 cb_pcidas_cancel(dev, s); 1418 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 1419 } 1420 1421 comedi_event(dev, s); 1422 1423 return IRQ_HANDLED; 1424} 1425 1426static int cb_pcidas_auto_attach(struct comedi_device *dev, 1427 unsigned long context) 1428{ 1429 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 1430 const struct cb_pcidas_board *thisboard = NULL; 1431 struct cb_pcidas_private *devpriv; 1432 struct comedi_subdevice *s; 1433 int i; 1434 int ret; 1435 1436 if (context < ARRAY_SIZE(cb_pcidas_boards)) 1437 thisboard = &cb_pcidas_boards[context]; 1438 if (!thisboard) 1439 return -ENODEV; 1440 dev->board_ptr = thisboard; 1441 dev->board_name = thisboard->name; 1442 1443 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1444 if (!devpriv) 1445 return -ENOMEM; 1446 1447 ret = comedi_pci_enable(dev); 1448 if (ret) 1449 return ret; 1450 1451 devpriv->s5933_config = pci_resource_start(pcidev, 0); 1452 devpriv->control_status = pci_resource_start(pcidev, 1); 1453 devpriv->adc_fifo = pci_resource_start(pcidev, 2); 1454 devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3); 1455 if (thisboard->ao_nchan) 1456 devpriv->ao_registers = pci_resource_start(pcidev, 4); 1457 1458 /* disable and clear interrupts on amcc s5933 */ 1459 outl(INTCSR_INBOX_INTR_STATUS, 1460 devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1461 1462 if (request_irq(pcidev->irq, cb_pcidas_interrupt, 1463 IRQF_SHARED, dev->driver->driver_name, dev)) { 1464 dev_dbg(dev->class_dev, "unable to allocate irq %d\n", 1465 pcidev->irq); 1466 return -EINVAL; 1467 } 1468 dev->irq = pcidev->irq; 1469 1470 ret = comedi_alloc_subdevices(dev, 7); 1471 if (ret) 1472 return ret; 1473 1474 s = &dev->subdevices[0]; 1475 /* analog input subdevice */ 1476 dev->read_subdev = s; 1477 s->type = COMEDI_SUBD_AI; 1478 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 1479 /* WARNING: Number of inputs in differential mode is ignored */ 1480 s->n_chan = thisboard->ai_nchan; 1481 s->len_chanlist = thisboard->ai_nchan; 1482 s->maxdata = (1 << thisboard->ai_bits) - 1; 1483 s->range_table = thisboard->ranges; 1484 s->insn_read = cb_pcidas_ai_rinsn; 1485 s->insn_config = ai_config_insn; 1486 s->do_cmd = cb_pcidas_ai_cmd; 1487 s->do_cmdtest = cb_pcidas_ai_cmdtest; 1488 s->cancel = cb_pcidas_cancel; 1489 1490 /* analog output subdevice */ 1491 s = &dev->subdevices[1]; 1492 if (thisboard->ao_nchan) { 1493 s->type = COMEDI_SUBD_AO; 1494 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; 1495 s->n_chan = thisboard->ao_nchan; 1496 /* 1497 * analog out resolution is the same as 1498 * analog input resolution, so use ai_bits 1499 */ 1500 s->maxdata = (1 << thisboard->ai_bits) - 1; 1501 s->range_table = &cb_pcidas_ao_ranges; 1502 s->insn_read = cb_pcidas_ao_readback_insn; 1503 if (thisboard->has_ao_fifo) { 1504 dev->write_subdev = s; 1505 s->subdev_flags |= SDF_CMD_WRITE; 1506 s->insn_write = cb_pcidas_ao_fifo_winsn; 1507 s->do_cmdtest = cb_pcidas_ao_cmdtest; 1508 s->do_cmd = cb_pcidas_ao_cmd; 1509 s->cancel = cb_pcidas_ao_cancel; 1510 } else { 1511 s->insn_write = cb_pcidas_ao_nofifo_winsn; 1512 } 1513 } else { 1514 s->type = COMEDI_SUBD_UNUSED; 1515 } 1516 1517 /* 8255 */ 1518 s = &dev->subdevices[2]; 1519 ret = subdev_8255_init(dev, s, NULL, 1520 devpriv->pacer_counter_dio + DIO_8255); 1521 if (ret) 1522 return ret; 1523 1524 /* serial EEPROM, */ 1525 s = &dev->subdevices[3]; 1526 s->type = COMEDI_SUBD_MEMORY; 1527 s->subdev_flags = SDF_READABLE | SDF_INTERNAL; 1528 s->n_chan = 256; 1529 s->maxdata = 0xff; 1530 s->insn_read = eeprom_read_insn; 1531 1532 /* 8800 caldac */ 1533 s = &dev->subdevices[4]; 1534 s->type = COMEDI_SUBD_CALIB; 1535 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 1536 s->n_chan = NUM_CHANNELS_8800; 1537 s->maxdata = 0xff; 1538 s->insn_read = caldac_read_insn; 1539 s->insn_write = caldac_write_insn; 1540 for (i = 0; i < s->n_chan; i++) 1541 caldac_8800_write(dev, i, s->maxdata / 2); 1542 1543 /* trim potentiometer */ 1544 s = &dev->subdevices[5]; 1545 s->type = COMEDI_SUBD_CALIB; 1546 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 1547 if (thisboard->trimpot == AD7376) { 1548 s->n_chan = NUM_CHANNELS_7376; 1549 s->maxdata = 0x7f; 1550 } else { 1551 s->n_chan = NUM_CHANNELS_8402; 1552 s->maxdata = 0xff; 1553 } 1554 s->insn_read = trimpot_read_insn; 1555 s->insn_write = trimpot_write_insn; 1556 for (i = 0; i < s->n_chan; i++) 1557 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2); 1558 1559 /* dac08 caldac */ 1560 s = &dev->subdevices[6]; 1561 if (thisboard->has_dac08) { 1562 s->type = COMEDI_SUBD_CALIB; 1563 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 1564 s->n_chan = NUM_CHANNELS_DAC08; 1565 s->insn_read = dac08_read_insn; 1566 s->insn_write = dac08_write_insn; 1567 s->maxdata = 0xff; 1568 dac08_write(dev, s->maxdata / 2); 1569 } else 1570 s->type = COMEDI_SUBD_UNUSED; 1571 1572 /* make sure mailbox 4 is empty */ 1573 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4); 1574 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */ 1575 devpriv->s5933_intcsr_bits = 1576 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) | 1577 INTCSR_INBOX_FULL_INT; 1578 /* clear and enable interrupt on amcc s5933 */ 1579 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 1580 devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1581 1582 dev_info(dev->class_dev, "%s: %s attached\n", 1583 dev->driver->driver_name, dev->board_name); 1584 1585 return 0; 1586} 1587 1588static void cb_pcidas_detach(struct comedi_device *dev) 1589{ 1590 struct cb_pcidas_private *devpriv = dev->private; 1591 1592 if (devpriv) { 1593 if (devpriv->s5933_config) { 1594 outl(INTCSR_INBOX_INTR_STATUS, 1595 devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1596 } 1597 } 1598 if (dev->irq) 1599 free_irq(dev->irq, dev); 1600 comedi_pci_disable(dev); 1601} 1602 1603static struct comedi_driver cb_pcidas_driver = { 1604 .driver_name = "cb_pcidas", 1605 .module = THIS_MODULE, 1606 .auto_attach = cb_pcidas_auto_attach, 1607 .detach = cb_pcidas_detach, 1608}; 1609 1610static int cb_pcidas_pci_probe(struct pci_dev *dev, 1611 const struct pci_device_id *id) 1612{ 1613 return comedi_pci_auto_config(dev, &cb_pcidas_driver, 1614 id->driver_data); 1615} 1616 1617static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { 1618 { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 }, 1619 { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 }, 1620 { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 }, 1621 { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR }, 1622 { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR }, 1623 { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 }, 1624 { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 }, 1625 { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 }, 1626 { 0 } 1627}; 1628MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table); 1629 1630static struct pci_driver cb_pcidas_pci_driver = { 1631 .name = "cb_pcidas", 1632 .id_table = cb_pcidas_pci_table, 1633 .probe = cb_pcidas_pci_probe, 1634 .remove = comedi_pci_auto_unconfig, 1635}; 1636module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver); 1637 1638MODULE_AUTHOR("Comedi http://www.comedi.org"); 1639MODULE_DESCRIPTION("Comedi low-level driver"); 1640MODULE_LICENSE("GPL"); 1641