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