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