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