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