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