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