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