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