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