cb_pcidas.c revision 9a0f7631f26cd9d9fc9f8fd1513427e13912a63c
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/* 408 * Useful for shorthand access to the particular board structure 409 */ 410#define thisboard ((const struct cb_pcidas_board *)dev->board_ptr) 411 412/* this structure is for data unique to this hardware driver. If 413 several hardware drivers keep similar information in this structure, 414 feel free to suggest moving the variable to the struct comedi_device struct. */ 415struct cb_pcidas_private { 416 /* would be useful for a PCI device */ 417 struct pci_dev *pci_dev; 418 /* base addresses */ 419 unsigned long s5933_config; 420 unsigned long control_status; 421 unsigned long adc_fifo; 422 unsigned long pacer_counter_dio; 423 unsigned long ao_registers; 424 /* divisors of master clock for analog input pacing */ 425 unsigned int divisor1; 426 unsigned int divisor2; 427 volatile unsigned int count; /* number of analog input samples remaining */ 428 volatile unsigned int adc_fifo_bits; /* bits to write to interrupt/adcfifo register */ 429 volatile unsigned int s5933_intcsr_bits; /* bits to write to amcc s5933 interrupt control/status register */ 430 volatile unsigned int ao_control_bits; /* bits to write to ao control and status register */ 431 short ai_buffer[AI_BUFFER_SIZE]; 432 short ao_buffer[AO_BUFFER_SIZE]; 433 /* divisors of master clock for analog output pacing */ 434 unsigned int ao_divisor1; 435 unsigned int ao_divisor2; 436 volatile unsigned int ao_count; /* number of analog output samples remaining */ 437 int ao_value[2]; /* remember what the analog outputs are set to, to allow readback */ 438 unsigned int caldac_value[NUM_CHANNELS_8800]; /* for readback of caldac */ 439 unsigned int trimpot_value[NUM_CHANNELS_8402]; /* for readback of trimpot */ 440 unsigned int dac08_value; 441 unsigned int calibration_source; 442}; 443 444/* 445 * most drivers define the following macro to make it easy to 446 * access the private structure. 447 */ 448#define devpriv ((struct cb_pcidas_private *)dev->private) 449 450static int cb_pcidas_ao_cancel(struct comedi_device *dev, 451 struct comedi_subdevice *s); 452static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns, 453 int round_flags); 454static int caldac_8800_write(struct comedi_device *dev, unsigned int address, 455 uint8_t value); 456static int trimpot_7376_write(struct comedi_device *dev, uint8_t value); 457static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 458 uint8_t value); 459static int nvram_read(struct comedi_device *dev, unsigned int address, 460 uint8_t *data); 461 462static inline unsigned int cal_enable_bits(struct comedi_device *dev) 463{ 464 return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source); 465} 466 467/* 468 * "instructions" read/write data in "one-shot" or "software-triggered" 469 * mode. 470 */ 471static int cb_pcidas_ai_rinsn(struct comedi_device *dev, 472 struct comedi_subdevice *s, 473 struct comedi_insn *insn, unsigned int *data) 474{ 475 int n, i; 476 unsigned int bits; 477 static const int timeout = 10000; 478 int channel; 479 /* enable calibration input if appropriate */ 480 if (insn->chanspec & CR_ALT_SOURCE) { 481 outw(cal_enable_bits(dev), 482 devpriv->control_status + CALIBRATION_REG); 483 channel = 0; 484 } else { 485 outw(0, devpriv->control_status + CALIBRATION_REG); 486 channel = CR_CHAN(insn->chanspec); 487 } 488 /* set mux limits and gain */ 489 bits = BEGIN_SCAN(channel) | 490 END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec)); 491 /* set unipolar/bipolar */ 492 if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR) 493 bits |= UNIP; 494 /* set singleended/differential */ 495 if (CR_AREF(insn->chanspec) != AREF_DIFF) 496 bits |= SE; 497 outw(bits, devpriv->control_status + ADCMUX_CONT); 498 499 /* clear fifo */ 500 outw(0, devpriv->adc_fifo + ADCFIFOCLR); 501 502 /* convert n samples */ 503 for (n = 0; n < insn->n; n++) { 504 /* trigger conversion */ 505 outw(0, devpriv->adc_fifo + ADCDATA); 506 507 /* wait for conversion to end */ 508 /* return -ETIMEDOUT if there is a timeout */ 509 for (i = 0; i < timeout; i++) { 510 if (inw(devpriv->control_status + ADCMUX_CONT) & EOC) 511 break; 512 } 513 if (i == timeout) 514 return -ETIMEDOUT; 515 516 /* read data */ 517 data[n] = inw(devpriv->adc_fifo + ADCDATA); 518 } 519 520 /* return the number of samples read/written */ 521 return n; 522} 523 524static int ai_config_calibration_source(struct comedi_device *dev, 525 unsigned int *data) 526{ 527 static const int num_calibration_sources = 8; 528 unsigned int source = data[1]; 529 530 if (source >= num_calibration_sources) { 531 dev_err(dev->class_dev, "invalid calibration source: %i\n", 532 source); 533 return -EINVAL; 534 } 535 536 devpriv->calibration_source = source; 537 538 return 2; 539} 540 541static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s, 542 struct comedi_insn *insn, unsigned int *data) 543{ 544 int id = data[0]; 545 546 switch (id) { 547 case INSN_CONFIG_ALT_SOURCE: 548 return ai_config_calibration_source(dev, data); 549 break; 550 default: 551 return -EINVAL; 552 break; 553 } 554 return -EINVAL; 555} 556 557/* analog output insn for pcidas-1000 and 1200 series */ 558static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev, 559 struct comedi_subdevice *s, 560 struct comedi_insn *insn, 561 unsigned int *data) 562{ 563 int channel; 564 unsigned long flags; 565 566 /* set channel and range */ 567 channel = CR_CHAN(insn->chanspec); 568 spin_lock_irqsave(&dev->spinlock, flags); 569 devpriv->ao_control_bits &= 570 ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel); 571 devpriv->ao_control_bits |= 572 DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec)); 573 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 574 spin_unlock_irqrestore(&dev->spinlock, flags); 575 576 /* remember value for readback */ 577 devpriv->ao_value[channel] = data[0]; 578 /* send data */ 579 outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel)); 580 581 return 1; 582} 583 584/* analog output insn for pcidas-1602 series */ 585static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev, 586 struct comedi_subdevice *s, 587 struct comedi_insn *insn, unsigned int *data) 588{ 589 int channel; 590 unsigned long flags; 591 592 /* clear dac fifo */ 593 outw(0, devpriv->ao_registers + DACFIFOCLR); 594 595 /* set channel and range */ 596 channel = CR_CHAN(insn->chanspec); 597 spin_lock_irqsave(&dev->spinlock, flags); 598 devpriv->ao_control_bits &= 599 ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) & 600 ~DAC_PACER_MASK; 601 devpriv->ao_control_bits |= 602 DACEN | DAC_RANGE(channel, 603 CR_RANGE(insn-> 604 chanspec)) | DAC_CHAN_EN(channel) | 605 DAC_START; 606 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 607 spin_unlock_irqrestore(&dev->spinlock, flags); 608 609 /* remember value for readback */ 610 devpriv->ao_value[channel] = data[0]; 611 /* send data */ 612 outw(data[0], devpriv->ao_registers + DACDATA); 613 614 return 1; 615} 616 617/* analog output readback insn */ 618/* XXX loses track of analog output value back after an analog ouput command is executed */ 619static int cb_pcidas_ao_readback_insn(struct comedi_device *dev, 620 struct comedi_subdevice *s, 621 struct comedi_insn *insn, 622 unsigned int *data) 623{ 624 data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)]; 625 626 return 1; 627} 628 629static int eeprom_read_insn(struct comedi_device *dev, 630 struct comedi_subdevice *s, 631 struct comedi_insn *insn, unsigned int *data) 632{ 633 uint8_t nvram_data; 634 int retval; 635 636 retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data); 637 if (retval < 0) 638 return retval; 639 640 data[0] = nvram_data; 641 642 return 1; 643} 644 645static int caldac_write_insn(struct comedi_device *dev, 646 struct comedi_subdevice *s, 647 struct comedi_insn *insn, unsigned int *data) 648{ 649 const unsigned int channel = CR_CHAN(insn->chanspec); 650 651 return caldac_8800_write(dev, channel, data[0]); 652} 653 654static int caldac_read_insn(struct comedi_device *dev, 655 struct comedi_subdevice *s, 656 struct comedi_insn *insn, unsigned int *data) 657{ 658 data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)]; 659 660 return 1; 661} 662 663/* 1602/16 pregain offset */ 664static int dac08_write(struct comedi_device *dev, unsigned int value) 665{ 666 if (devpriv->dac08_value == value) 667 return 1; 668 669 devpriv->dac08_value = value; 670 671 outw(cal_enable_bits(dev) | (value & 0xff), 672 devpriv->control_status + CALIBRATION_REG); 673 udelay(1); 674 outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff), 675 devpriv->control_status + CALIBRATION_REG); 676 udelay(1); 677 outw(cal_enable_bits(dev) | (value & 0xff), 678 devpriv->control_status + CALIBRATION_REG); 679 udelay(1); 680 681 return 1; 682} 683 684static int dac08_write_insn(struct comedi_device *dev, 685 struct comedi_subdevice *s, 686 struct comedi_insn *insn, unsigned int *data) 687{ 688 return dac08_write(dev, data[0]); 689} 690 691static int dac08_read_insn(struct comedi_device *dev, 692 struct comedi_subdevice *s, struct comedi_insn *insn, 693 unsigned int *data) 694{ 695 data[0] = devpriv->dac08_value; 696 697 return 1; 698} 699 700static int cb_pcidas_trimpot_write(struct comedi_device *dev, 701 unsigned int channel, unsigned int value) 702{ 703 if (devpriv->trimpot_value[channel] == value) 704 return 1; 705 706 devpriv->trimpot_value[channel] = value; 707 switch (thisboard->trimpot) { 708 case AD7376: 709 trimpot_7376_write(dev, value); 710 break; 711 case AD8402: 712 trimpot_8402_write(dev, channel, value); 713 break; 714 default: 715 comedi_error(dev, "driver bug?"); 716 return -1; 717 break; 718 } 719 720 return 1; 721} 722 723static int trimpot_write_insn(struct comedi_device *dev, 724 struct comedi_subdevice *s, 725 struct comedi_insn *insn, unsigned int *data) 726{ 727 unsigned int channel = CR_CHAN(insn->chanspec); 728 729 return cb_pcidas_trimpot_write(dev, channel, data[0]); 730} 731 732static int trimpot_read_insn(struct comedi_device *dev, 733 struct comedi_subdevice *s, 734 struct comedi_insn *insn, unsigned int *data) 735{ 736 unsigned int channel = CR_CHAN(insn->chanspec); 737 738 data[0] = devpriv->trimpot_value[channel]; 739 740 return 1; 741} 742 743static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, 744 struct comedi_subdevice *s, 745 struct comedi_cmd *cmd) 746{ 747 int err = 0; 748 int tmp; 749 int i, gain, start_chan; 750 751 /* cmdtest tests a particular command to see if it is valid. 752 * Using the cmdtest ioctl, a user can create a valid cmd 753 * and then have it executes by the cmd ioctl. 754 * 755 * cmdtest returns 1,2,3,4 or 0, depending on which tests 756 * the command passes. */ 757 758 /* step 1: make sure trigger sources are trivially valid */ 759 760 tmp = cmd->start_src; 761 cmd->start_src &= TRIG_NOW | TRIG_EXT; 762 if (!cmd->start_src || tmp != cmd->start_src) 763 err++; 764 765 tmp = cmd->scan_begin_src; 766 cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT; 767 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 768 err++; 769 770 tmp = cmd->convert_src; 771 cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT; 772 if (!cmd->convert_src || tmp != cmd->convert_src) 773 err++; 774 775 tmp = cmd->scan_end_src; 776 cmd->scan_end_src &= TRIG_COUNT; 777 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 778 err++; 779 780 tmp = cmd->stop_src; 781 cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 782 if (!cmd->stop_src || tmp != cmd->stop_src) 783 err++; 784 785 if (err) 786 return 1; 787 788 /* step 2: make sure trigger sources are unique and mutually compatible */ 789 790 if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) 791 err++; 792 if (cmd->scan_begin_src != TRIG_FOLLOW && 793 cmd->scan_begin_src != TRIG_TIMER && 794 cmd->scan_begin_src != TRIG_EXT) 795 err++; 796 if (cmd->convert_src != TRIG_TIMER && 797 cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) 798 err++; 799 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 800 err++; 801 802 /* make sure trigger sources are compatible with each other */ 803 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) 804 err++; 805 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) 806 err++; 807 if (cmd->start_src == TRIG_EXT && 808 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)) 809 err++; 810 811 if (err) 812 return 2; 813 814 /* step 3: make sure arguments are trivially compatible */ 815 816 switch (cmd->start_src) { 817 case TRIG_EXT: 818 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */ 819 if ((cmd->start_arg 820 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) { 821 cmd->start_arg &= 822 ~(CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT)); 823 err++; 824 } 825 if (!thisboard->has_ai_trig_invert && 826 (cmd->start_arg & CR_INVERT)) { 827 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT); 828 err++; 829 } 830 break; 831 default: 832 if (cmd->start_arg != 0) { 833 cmd->start_arg = 0; 834 err++; 835 } 836 break; 837 } 838 839 if (cmd->scan_begin_src == TRIG_TIMER) { 840 if (cmd->scan_begin_arg < 841 thisboard->ai_speed * cmd->chanlist_len) { 842 cmd->scan_begin_arg = 843 thisboard->ai_speed * cmd->chanlist_len; 844 err++; 845 } 846 } 847 if (cmd->convert_src == TRIG_TIMER) { 848 if (cmd->convert_arg < thisboard->ai_speed) { 849 cmd->convert_arg = thisboard->ai_speed; 850 err++; 851 } 852 } 853 854 if (cmd->scan_end_arg != cmd->chanlist_len) { 855 cmd->scan_end_arg = cmd->chanlist_len; 856 err++; 857 } 858 if (cmd->stop_src == TRIG_NONE) { 859 /* TRIG_NONE */ 860 if (cmd->stop_arg != 0) { 861 cmd->stop_arg = 0; 862 err++; 863 } 864 } 865 866 if (err) 867 return 3; 868 869 /* step 4: fix up any arguments */ 870 871 if (cmd->scan_begin_src == TRIG_TIMER) { 872 tmp = cmd->scan_begin_arg; 873 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 874 &(devpriv->divisor1), 875 &(devpriv->divisor2), 876 &(cmd->scan_begin_arg), 877 cmd->flags & TRIG_ROUND_MASK); 878 if (tmp != cmd->scan_begin_arg) 879 err++; 880 } 881 if (cmd->convert_src == TRIG_TIMER) { 882 tmp = cmd->convert_arg; 883 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 884 &(devpriv->divisor1), 885 &(devpriv->divisor2), 886 &(cmd->convert_arg), 887 cmd->flags & TRIG_ROUND_MASK); 888 if (tmp != cmd->convert_arg) 889 err++; 890 } 891 892 if (err) 893 return 4; 894 895 /* check channel/gain list against card's limitations */ 896 if (cmd->chanlist) { 897 gain = CR_RANGE(cmd->chanlist[0]); 898 start_chan = CR_CHAN(cmd->chanlist[0]); 899 for (i = 1; i < cmd->chanlist_len; i++) { 900 if (CR_CHAN(cmd->chanlist[i]) != 901 (start_chan + i) % s->n_chan) { 902 comedi_error(dev, 903 "entries in chanlist must be consecutive channels, counting upwards\n"); 904 err++; 905 } 906 if (CR_RANGE(cmd->chanlist[i]) != gain) { 907 comedi_error(dev, 908 "entries in chanlist must all have the same gain\n"); 909 err++; 910 } 911 } 912 } 913 914 if (err) 915 return 5; 916 917 return 0; 918} 919 920static int cb_pcidas_ai_cmd(struct comedi_device *dev, 921 struct comedi_subdevice *s) 922{ 923 struct comedi_async *async = s->async; 924 struct comedi_cmd *cmd = &async->cmd; 925 unsigned int bits; 926 unsigned long flags; 927 928 /* make sure CAL_EN_BIT is disabled */ 929 outw(0, devpriv->control_status + CALIBRATION_REG); 930 /* initialize before settings pacer source and count values */ 931 outw(0, devpriv->control_status + TRIG_CONTSTAT); 932 /* clear fifo */ 933 outw(0, devpriv->adc_fifo + ADCFIFOCLR); 934 935 /* set mux limits, gain and pacer source */ 936 bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) | 937 END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) | 938 GAIN_BITS(CR_RANGE(cmd->chanlist[0])); 939 /* set unipolar/bipolar */ 940 if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR) 941 bits |= UNIP; 942 /* set singleended/differential */ 943 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF) 944 bits |= SE; 945 /* set pacer source */ 946 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT) 947 bits |= PACER_EXT_RISE; 948 else 949 bits |= PACER_INT; 950 outw(bits, devpriv->control_status + ADCMUX_CONT); 951 952#ifdef CB_PCIDAS_DEBUG 953 dev_dbg(dev->class_dev, "sent 0x%x to adcmux control\n", bits); 954#endif 955 956 /* load counters */ 957 if (cmd->convert_src == TRIG_TIMER) 958 cb_pcidas_load_counters(dev, &cmd->convert_arg, 959 cmd->flags & TRIG_ROUND_MASK); 960 else if (cmd->scan_begin_src == TRIG_TIMER) 961 cb_pcidas_load_counters(dev, &cmd->scan_begin_arg, 962 cmd->flags & TRIG_ROUND_MASK); 963 964 /* set number of conversions */ 965 if (cmd->stop_src == TRIG_COUNT) 966 devpriv->count = cmd->chanlist_len * cmd->stop_arg; 967 /* enable interrupts */ 968 spin_lock_irqsave(&dev->spinlock, flags); 969 devpriv->adc_fifo_bits |= INTE; 970 devpriv->adc_fifo_bits &= ~INT_MASK; 971 if (cmd->flags & TRIG_WAKE_EOS) { 972 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 973 devpriv->adc_fifo_bits |= INT_EOS; /* interrupt end of burst */ 974 else 975 devpriv->adc_fifo_bits |= INT_FNE; /* interrupt fifo not empty */ 976 } else { 977 devpriv->adc_fifo_bits |= INT_FHF; /* interrupt fifo half full */ 978 } 979#ifdef CB_PCIDAS_DEBUG 980 dev_dbg(dev->class_dev, "adc_fifo_bits are 0x%x\n", 981 devpriv->adc_fifo_bits); 982#endif 983 /* enable (and clear) interrupts */ 984 outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL, 985 devpriv->control_status + INT_ADCFIFO); 986 spin_unlock_irqrestore(&dev->spinlock, flags); 987 988 /* set start trigger and burst mode */ 989 bits = 0; 990 if (cmd->start_src == TRIG_NOW) 991 bits |= SW_TRIGGER; 992 else if (cmd->start_src == TRIG_EXT) { 993 bits |= EXT_TRIGGER | TGEN | XTRCL; 994 if (thisboard->has_ai_trig_invert 995 && (cmd->start_arg & CR_INVERT)) 996 bits |= TGPOL; 997 if (thisboard->has_ai_trig_gated && (cmd->start_arg & CR_EDGE)) 998 bits |= TGSEL; 999 } else { 1000 comedi_error(dev, "bug!"); 1001 return -1; 1002 } 1003 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 1004 bits |= BURSTE; 1005 outw(bits, devpriv->control_status + TRIG_CONTSTAT); 1006#ifdef CB_PCIDAS_DEBUG 1007 dev_dbg(dev->class_dev, "sent 0x%x to trig control\n", bits); 1008#endif 1009 1010 return 0; 1011} 1012 1013static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, 1014 struct comedi_subdevice *s, 1015 struct comedi_cmd *cmd) 1016{ 1017 int err = 0; 1018 int tmp; 1019 1020 /* cmdtest tests a particular command to see if it is valid. 1021 * Using the cmdtest ioctl, a user can create a valid cmd 1022 * and then have it executes by the cmd ioctl. 1023 * 1024 * cmdtest returns 1,2,3,4 or 0, depending on which tests 1025 * the command passes. */ 1026 1027 /* step 1: make sure trigger sources are trivially valid */ 1028 1029 tmp = cmd->start_src; 1030 cmd->start_src &= TRIG_INT; 1031 if (!cmd->start_src || tmp != cmd->start_src) 1032 err++; 1033 1034 tmp = cmd->scan_begin_src; 1035 cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT; 1036 if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) 1037 err++; 1038 1039 tmp = cmd->convert_src; 1040 cmd->convert_src &= TRIG_NOW; 1041 if (!cmd->convert_src || tmp != cmd->convert_src) 1042 err++; 1043 1044 tmp = cmd->scan_end_src; 1045 cmd->scan_end_src &= TRIG_COUNT; 1046 if (!cmd->scan_end_src || tmp != cmd->scan_end_src) 1047 err++; 1048 1049 tmp = cmd->stop_src; 1050 cmd->stop_src &= TRIG_COUNT | TRIG_NONE; 1051 if (!cmd->stop_src || tmp != cmd->stop_src) 1052 err++; 1053 1054 if (err) 1055 return 1; 1056 1057 /* step 2: make sure trigger sources are unique and mutually compatible */ 1058 1059 if (cmd->scan_begin_src != TRIG_TIMER && 1060 cmd->scan_begin_src != TRIG_EXT) 1061 err++; 1062 if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) 1063 err++; 1064 1065 if (err) 1066 return 2; 1067 1068 /* step 3: make sure arguments are trivially compatible */ 1069 1070 if (cmd->start_arg != 0) { 1071 cmd->start_arg = 0; 1072 err++; 1073 } 1074 1075 if (cmd->scan_begin_src == TRIG_TIMER) { 1076 if (cmd->scan_begin_arg < thisboard->ao_scan_speed) { 1077 cmd->scan_begin_arg = thisboard->ao_scan_speed; 1078 err++; 1079 } 1080 } 1081 1082 if (cmd->scan_end_arg != cmd->chanlist_len) { 1083 cmd->scan_end_arg = cmd->chanlist_len; 1084 err++; 1085 } 1086 if (cmd->stop_src == TRIG_NONE) { 1087 /* TRIG_NONE */ 1088 if (cmd->stop_arg != 0) { 1089 cmd->stop_arg = 0; 1090 err++; 1091 } 1092 } 1093 1094 if (err) 1095 return 3; 1096 1097 /* step 4: fix up any arguments */ 1098 1099 if (cmd->scan_begin_src == TRIG_TIMER) { 1100 tmp = cmd->scan_begin_arg; 1101 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1102 &(devpriv->ao_divisor1), 1103 &(devpriv->ao_divisor2), 1104 &(cmd->scan_begin_arg), 1105 cmd->flags & TRIG_ROUND_MASK); 1106 if (tmp != cmd->scan_begin_arg) 1107 err++; 1108 } 1109 1110 if (err) 1111 return 4; 1112 1113 /* check channel/gain list against card's limitations */ 1114 if (cmd->chanlist && cmd->chanlist_len > 1) { 1115 if (CR_CHAN(cmd->chanlist[0]) != 0 || 1116 CR_CHAN(cmd->chanlist[1]) != 1) { 1117 comedi_error(dev, 1118 "channels must be ordered channel 0, channel 1 in chanlist\n"); 1119 err++; 1120 } 1121 } 1122 1123 if (err) 1124 return 5; 1125 1126 return 0; 1127} 1128 1129/* cancel analog input command */ 1130static int cb_pcidas_cancel(struct comedi_device *dev, 1131 struct comedi_subdevice *s) 1132{ 1133 unsigned long flags; 1134 1135 spin_lock_irqsave(&dev->spinlock, flags); 1136 /* disable interrupts */ 1137 devpriv->adc_fifo_bits &= ~INTE & ~EOAIE; 1138 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 1139 spin_unlock_irqrestore(&dev->spinlock, flags); 1140 1141 /* disable start trigger source and burst mode */ 1142 outw(0, devpriv->control_status + TRIG_CONTSTAT); 1143 /* software pacer source */ 1144 outw(0, devpriv->control_status + ADCMUX_CONT); 1145 1146 return 0; 1147} 1148 1149static int cb_pcidas_ao_inttrig(struct comedi_device *dev, 1150 struct comedi_subdevice *s, 1151 unsigned int trig_num) 1152{ 1153 unsigned int num_bytes, num_points = thisboard->fifo_size; 1154 struct comedi_async *async = s->async; 1155 struct comedi_cmd *cmd = &s->async->cmd; 1156 unsigned long flags; 1157 1158 if (trig_num != 0) 1159 return -EINVAL; 1160 1161 /* load up fifo */ 1162 if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points) 1163 num_points = devpriv->ao_count; 1164 1165 num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer, 1166 num_points * sizeof(short)); 1167 num_points = num_bytes / sizeof(short); 1168 1169 if (cmd->stop_src == TRIG_COUNT) 1170 devpriv->ao_count -= num_points; 1171 /* write data to board's fifo */ 1172 outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes); 1173 1174 /* enable dac half-full and empty interrupts */ 1175 spin_lock_irqsave(&dev->spinlock, flags); 1176 devpriv->adc_fifo_bits |= DAEMIE | DAHFIE; 1177#ifdef CB_PCIDAS_DEBUG 1178 dev_dbg(dev->class_dev, "adc_fifo_bits are 0x%x\n", 1179 devpriv->adc_fifo_bits); 1180#endif 1181 /* enable and clear interrupts */ 1182 outw(devpriv->adc_fifo_bits | DAEMI | DAHFI, 1183 devpriv->control_status + INT_ADCFIFO); 1184 1185 /* start dac */ 1186 devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY; 1187 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 1188#ifdef CB_PCIDAS_DEBUG 1189 dev_dbg(dev->class_dev, "sent 0x%x to dac control\n", 1190 devpriv->ao_control_bits); 1191#endif 1192 spin_unlock_irqrestore(&dev->spinlock, flags); 1193 1194 async->inttrig = NULL; 1195 1196 return 0; 1197} 1198 1199static int cb_pcidas_ao_cmd(struct comedi_device *dev, 1200 struct comedi_subdevice *s) 1201{ 1202 struct comedi_async *async = s->async; 1203 struct comedi_cmd *cmd = &async->cmd; 1204 unsigned int i; 1205 unsigned long flags; 1206 1207 /* set channel limits, gain */ 1208 spin_lock_irqsave(&dev->spinlock, flags); 1209 for (i = 0; i < cmd->chanlist_len; i++) { 1210 /* enable channel */ 1211 devpriv->ao_control_bits |= 1212 DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i])); 1213 /* set range */ 1214 devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]), 1215 CR_RANGE(cmd-> 1216 chanlist[i])); 1217 } 1218 1219 /* disable analog out before settings pacer source and count values */ 1220 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 1221 spin_unlock_irqrestore(&dev->spinlock, flags); 1222 1223 /* clear fifo */ 1224 outw(0, devpriv->ao_registers + DACFIFOCLR); 1225 1226 /* load counters */ 1227 if (cmd->scan_begin_src == TRIG_TIMER) { 1228 i8253_cascade_ns_to_timer_2div(TIMER_BASE, 1229 &(devpriv->ao_divisor1), 1230 &(devpriv->ao_divisor2), 1231 &(cmd->scan_begin_arg), 1232 cmd->flags); 1233 1234 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 1235 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1, 1236 devpriv->ao_divisor1, 2); 1237 i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2, 1238 devpriv->ao_divisor2, 2); 1239 } 1240 /* set number of conversions */ 1241 if (cmd->stop_src == TRIG_COUNT) 1242 devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg; 1243 /* set pacer source */ 1244 spin_lock_irqsave(&dev->spinlock, flags); 1245 switch (cmd->scan_begin_src) { 1246 case TRIG_TIMER: 1247 devpriv->ao_control_bits |= DAC_PACER_INT; 1248 break; 1249 case TRIG_EXT: 1250 devpriv->ao_control_bits |= DAC_PACER_EXT_RISE; 1251 break; 1252 default: 1253 spin_unlock_irqrestore(&dev->spinlock, flags); 1254 comedi_error(dev, "error setting dac pacer source"); 1255 return -1; 1256 break; 1257 } 1258 spin_unlock_irqrestore(&dev->spinlock, flags); 1259 1260 async->inttrig = cb_pcidas_ao_inttrig; 1261 1262 return 0; 1263} 1264 1265static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status) 1266{ 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 struct comedi_subdevice *s = dev->read_subdev; 1324 struct comedi_async *async; 1325 int status, s5933_status; 1326 int half_fifo = thisboard->fifo_size / 2; 1327 unsigned int num_samples, i; 1328 static const int timeout = 10000; 1329 unsigned long flags; 1330 1331 if (dev->attached == 0) 1332 return IRQ_NONE; 1333 1334 async = s->async; 1335 async->events = 0; 1336 1337 s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1338#ifdef CB_PCIDAS_DEBUG 1339 dev_dbg(dev->class_dev, "intcsr 0x%x\n", s5933_status); 1340 dev_dbg(dev->class_dev, "mbef 0x%x\n", 1341 inl(devpriv->s5933_config + AMCC_OP_REG_MBEF)); 1342#endif 1343 1344 if ((INTCSR_INTR_ASSERTED & s5933_status) == 0) 1345 return IRQ_NONE; 1346 1347 /* make sure mailbox 4 is empty */ 1348 inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4); 1349 /* clear interrupt on amcc s5933 */ 1350 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 1351 devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1352 1353 status = inw(devpriv->control_status + INT_ADCFIFO); 1354#ifdef CB_PCIDAS_DEBUG 1355 if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) 1356 comedi_error(dev, "spurious interrupt"); 1357#endif 1358 1359 /* check for analog output interrupt */ 1360 if (status & (DAHFI | DAEMI)) 1361 handle_ao_interrupt(dev, status); 1362 /* check for analog input interrupts */ 1363 /* if fifo half-full */ 1364 if (status & ADHFI) { 1365 /* read data */ 1366 num_samples = half_fifo; 1367 if (async->cmd.stop_src == TRIG_COUNT && 1368 num_samples > devpriv->count) { 1369 num_samples = devpriv->count; 1370 } 1371 insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer, 1372 num_samples); 1373 cfc_write_array_to_buffer(s, devpriv->ai_buffer, 1374 num_samples * sizeof(short)); 1375 devpriv->count -= num_samples; 1376 if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) { 1377 async->events |= COMEDI_CB_EOA; 1378 cb_pcidas_cancel(dev, s); 1379 } 1380 /* clear half-full interrupt latch */ 1381 spin_lock_irqsave(&dev->spinlock, flags); 1382 outw(devpriv->adc_fifo_bits | INT, 1383 devpriv->control_status + INT_ADCFIFO); 1384 spin_unlock_irqrestore(&dev->spinlock, flags); 1385 /* else if fifo not empty */ 1386 } else if (status & (ADNEI | EOBI)) { 1387 for (i = 0; i < timeout; i++) { 1388 /* break if fifo is empty */ 1389 if ((ADNE & inw(devpriv->control_status + 1390 INT_ADCFIFO)) == 0) 1391 break; 1392 cfc_write_to_buffer(s, inw(devpriv->adc_fifo)); 1393 if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) { /* end of acquisition */ 1394 cb_pcidas_cancel(dev, s); 1395 async->events |= COMEDI_CB_EOA; 1396 break; 1397 } 1398 } 1399 /* clear not-empty interrupt latch */ 1400 spin_lock_irqsave(&dev->spinlock, flags); 1401 outw(devpriv->adc_fifo_bits | INT, 1402 devpriv->control_status + INT_ADCFIFO); 1403 spin_unlock_irqrestore(&dev->spinlock, flags); 1404 } else if (status & EOAI) { 1405 comedi_error(dev, 1406 "bug! encountered end of acquisition interrupt?"); 1407 /* clear EOA interrupt latch */ 1408 spin_lock_irqsave(&dev->spinlock, flags); 1409 outw(devpriv->adc_fifo_bits | EOAI, 1410 devpriv->control_status + INT_ADCFIFO); 1411 spin_unlock_irqrestore(&dev->spinlock, flags); 1412 } 1413 /* check for fifo overflow */ 1414 if (status & LADFUL) { 1415 comedi_error(dev, "fifo overflow"); 1416 /* clear overflow interrupt latch */ 1417 spin_lock_irqsave(&dev->spinlock, flags); 1418 outw(devpriv->adc_fifo_bits | LADFUL, 1419 devpriv->control_status + INT_ADCFIFO); 1420 spin_unlock_irqrestore(&dev->spinlock, flags); 1421 cb_pcidas_cancel(dev, s); 1422 async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR; 1423 } 1424 1425 comedi_event(dev, s); 1426 1427 return IRQ_HANDLED; 1428} 1429 1430/* cancel analog output command */ 1431static int cb_pcidas_ao_cancel(struct comedi_device *dev, 1432 struct comedi_subdevice *s) 1433{ 1434 unsigned long flags; 1435 1436 spin_lock_irqsave(&dev->spinlock, flags); 1437 /* disable interrupts */ 1438 devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE; 1439 outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO); 1440 1441 /* disable output */ 1442 devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK; 1443 outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR); 1444 spin_unlock_irqrestore(&dev->spinlock, flags); 1445 1446 return 0; 1447} 1448 1449static void cb_pcidas_load_counters(struct comedi_device *dev, unsigned int *ns, 1450 int rounding_flags) 1451{ 1452 i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1), 1453 &(devpriv->divisor2), ns, 1454 rounding_flags & TRIG_ROUND_MASK); 1455 1456 /* Write the values of ctr1 and ctr2 into counters 1 and 2 */ 1457 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1, 1458 devpriv->divisor1, 2); 1459 i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2, 1460 devpriv->divisor2, 2); 1461} 1462 1463static void write_calibration_bitstream(struct comedi_device *dev, 1464 unsigned int register_bits, 1465 unsigned int bitstream, 1466 unsigned int bitstream_length) 1467{ 1468 static const int write_delay = 1; 1469 unsigned int bit; 1470 1471 for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) { 1472 if (bitstream & bit) 1473 register_bits |= SERIAL_DATA_IN_BIT; 1474 else 1475 register_bits &= ~SERIAL_DATA_IN_BIT; 1476 udelay(write_delay); 1477 outw(register_bits, devpriv->control_status + CALIBRATION_REG); 1478 } 1479} 1480 1481static int caldac_8800_write(struct comedi_device *dev, unsigned int address, 1482 uint8_t value) 1483{ 1484 static const int num_caldac_channels = 8; 1485 static const int bitstream_length = 11; 1486 unsigned int bitstream = ((address & 0x7) << 8) | value; 1487 static const int caldac_8800_udelay = 1; 1488 1489 if (address >= num_caldac_channels) { 1490 comedi_error(dev, "illegal caldac channel"); 1491 return -1; 1492 } 1493 1494 if (value == devpriv->caldac_value[address]) 1495 return 1; 1496 1497 devpriv->caldac_value[address] = value; 1498 1499 write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream, 1500 bitstream_length); 1501 1502 udelay(caldac_8800_udelay); 1503 outw(cal_enable_bits(dev) | SELECT_8800_BIT, 1504 devpriv->control_status + CALIBRATION_REG); 1505 udelay(caldac_8800_udelay); 1506 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 1507 1508 return 1; 1509} 1510 1511static int trimpot_7376_write(struct comedi_device *dev, uint8_t value) 1512{ 1513 static const int bitstream_length = 7; 1514 unsigned int bitstream = value & 0x7f; 1515 unsigned int register_bits; 1516 static const int ad7376_udelay = 1; 1517 1518 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 1519 udelay(ad7376_udelay); 1520 outw(register_bits, devpriv->control_status + CALIBRATION_REG); 1521 1522 write_calibration_bitstream(dev, register_bits, bitstream, 1523 bitstream_length); 1524 1525 udelay(ad7376_udelay); 1526 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 1527 1528 return 0; 1529} 1530 1531/* For 1602/16 only 1532 * ch 0 : adc gain 1533 * ch 1 : adc postgain offset */ 1534static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel, 1535 uint8_t value) 1536{ 1537 static const int bitstream_length = 10; 1538 unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff); 1539 unsigned int register_bits; 1540 static const int ad8402_udelay = 1; 1541 1542 register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT; 1543 udelay(ad8402_udelay); 1544 outw(register_bits, devpriv->control_status + CALIBRATION_REG); 1545 1546 write_calibration_bitstream(dev, register_bits, bitstream, 1547 bitstream_length); 1548 1549 udelay(ad8402_udelay); 1550 outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG); 1551 1552 return 0; 1553} 1554 1555static int wait_for_nvram_ready(unsigned long s5933_base_addr) 1556{ 1557 static const int timeout = 1000; 1558 unsigned int i; 1559 1560 for (i = 0; i < timeout; i++) { 1561 if ((inb(s5933_base_addr + 1562 AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY) 1563 == 0) 1564 return 0; 1565 udelay(1); 1566 } 1567 return -1; 1568} 1569 1570static int nvram_read(struct comedi_device *dev, unsigned int address, 1571 uint8_t *data) 1572{ 1573 unsigned long iobase = devpriv->s5933_config; 1574 1575 if (wait_for_nvram_ready(iobase) < 0) 1576 return -ETIMEDOUT; 1577 1578 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR, 1579 iobase + AMCC_OP_REG_MCSR_NVCMD); 1580 outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 1581 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR, 1582 iobase + AMCC_OP_REG_MCSR_NVCMD); 1583 outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA); 1584 outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD); 1585 1586 if (wait_for_nvram_ready(iobase) < 0) 1587 return -ETIMEDOUT; 1588 1589 *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA); 1590 1591 return 0; 1592} 1593 1594static int cb_pcidas_attach(struct comedi_device *dev, 1595 struct comedi_devconfig *it) 1596{ 1597 struct comedi_subdevice *s; 1598 struct pci_dev *pcidev = NULL; 1599 int index; 1600 int i; 1601 int ret; 1602 1603/* 1604 * Allocate the private structure area. 1605 */ 1606 if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0) 1607 return -ENOMEM; 1608 1609/* 1610 * Probe the device to determine what device in the series it is. 1611 */ 1612 1613 for_each_pci_dev(pcidev) { 1614 /* is it not a computer boards card? */ 1615 if (pcidev->vendor != PCI_VENDOR_ID_CB) 1616 continue; 1617 /* loop through cards supported by this driver */ 1618 for (index = 0; index < ARRAY_SIZE(cb_pcidas_boards); index++) { 1619 if (cb_pcidas_boards[index].device_id != pcidev->device) 1620 continue; 1621 /* was a particular bus/slot requested? */ 1622 if (it->options[0] || it->options[1]) { 1623 /* are we on the wrong bus/slot? */ 1624 if (pcidev->bus->number != it->options[0] || 1625 PCI_SLOT(pcidev->devfn) != it->options[1]) { 1626 continue; 1627 } 1628 } 1629 devpriv->pci_dev = pcidev; 1630 dev->board_ptr = cb_pcidas_boards + index; 1631 goto found; 1632 } 1633 } 1634 1635 dev_err(dev->class_dev, 1636 "No supported ComputerBoards/MeasurementComputing card found on requested position\n"); 1637 return -EIO; 1638 1639found: 1640 1641 dev_dbg(dev->class_dev, "Found %s on bus %i, slot %i\n", 1642 cb_pcidas_boards[index].name, pcidev->bus->number, 1643 PCI_SLOT(pcidev->devfn)); 1644 1645 /* 1646 * Enable PCI device and reserve I/O ports. 1647 */ 1648 if (comedi_pci_enable(pcidev, "cb_pcidas")) { 1649 dev_err(dev->class_dev, 1650 "Failed to enable PCI device and request regions\n"); 1651 return -EIO; 1652 } 1653 /* 1654 * Initialize devpriv->control_status and devpriv->adc_fifo to point to 1655 * their base address. 1656 */ 1657 devpriv->s5933_config = 1658 pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX); 1659 devpriv->control_status = 1660 pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX); 1661 devpriv->adc_fifo = 1662 pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX); 1663 devpriv->pacer_counter_dio = 1664 pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX); 1665 if (thisboard->ao_nchan) { 1666 devpriv->ao_registers = 1667 pci_resource_start(devpriv->pci_dev, AO_BADRINDEX); 1668 } 1669 /* disable and clear interrupts on amcc s5933 */ 1670 outl(INTCSR_INBOX_INTR_STATUS, 1671 devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1672 1673 /* get irq */ 1674 if (request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt, 1675 IRQF_SHARED, "cb_pcidas", dev)) { 1676 dev_dbg(dev->class_dev, "unable to allocate irq %d\n", 1677 devpriv->pci_dev->irq); 1678 return -EINVAL; 1679 } 1680 dev->irq = devpriv->pci_dev->irq; 1681 1682 /* Initialize dev->board_name */ 1683 dev->board_name = thisboard->name; 1684 1685 ret = comedi_alloc_subdevices(dev, 7); 1686 if (ret) 1687 return ret; 1688 1689 s = dev->subdevices + 0; 1690 /* analog input subdevice */ 1691 dev->read_subdev = s; 1692 s->type = COMEDI_SUBD_AI; 1693 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ; 1694 /* WARNING: Number of inputs in differential mode is ignored */ 1695 s->n_chan = thisboard->ai_se_chans; 1696 s->len_chanlist = thisboard->ai_se_chans; 1697 s->maxdata = (1 << thisboard->ai_bits) - 1; 1698 s->range_table = thisboard->ranges; 1699 s->insn_read = cb_pcidas_ai_rinsn; 1700 s->insn_config = ai_config_insn; 1701 s->do_cmd = cb_pcidas_ai_cmd; 1702 s->do_cmdtest = cb_pcidas_ai_cmdtest; 1703 s->cancel = cb_pcidas_cancel; 1704 1705 /* analog output subdevice */ 1706 s = dev->subdevices + 1; 1707 if (thisboard->ao_nchan) { 1708 s->type = COMEDI_SUBD_AO; 1709 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; 1710 s->n_chan = thisboard->ao_nchan; 1711 /* analog out resolution is the same as analog input resolution, so use ai_bits */ 1712 s->maxdata = (1 << thisboard->ai_bits) - 1; 1713 s->range_table = &cb_pcidas_ao_ranges; 1714 s->insn_read = cb_pcidas_ao_readback_insn; 1715 if (thisboard->has_ao_fifo) { 1716 dev->write_subdev = s; 1717 s->subdev_flags |= SDF_CMD_WRITE; 1718 s->insn_write = cb_pcidas_ao_fifo_winsn; 1719 s->do_cmdtest = cb_pcidas_ao_cmdtest; 1720 s->do_cmd = cb_pcidas_ao_cmd; 1721 s->cancel = cb_pcidas_ao_cancel; 1722 } else { 1723 s->insn_write = cb_pcidas_ao_nofifo_winsn; 1724 } 1725 } else { 1726 s->type = COMEDI_SUBD_UNUSED; 1727 } 1728 1729 /* 8255 */ 1730 s = dev->subdevices + 2; 1731 subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255); 1732 1733 /* serial EEPROM, */ 1734 s = dev->subdevices + 3; 1735 s->type = COMEDI_SUBD_MEMORY; 1736 s->subdev_flags = SDF_READABLE | SDF_INTERNAL; 1737 s->n_chan = 256; 1738 s->maxdata = 0xff; 1739 s->insn_read = eeprom_read_insn; 1740 1741 /* 8800 caldac */ 1742 s = dev->subdevices + 4; 1743 s->type = COMEDI_SUBD_CALIB; 1744 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 1745 s->n_chan = NUM_CHANNELS_8800; 1746 s->maxdata = 0xff; 1747 s->insn_read = caldac_read_insn; 1748 s->insn_write = caldac_write_insn; 1749 for (i = 0; i < s->n_chan; i++) 1750 caldac_8800_write(dev, i, s->maxdata / 2); 1751 1752 /* trim potentiometer */ 1753 s = dev->subdevices + 5; 1754 s->type = COMEDI_SUBD_CALIB; 1755 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 1756 if (thisboard->trimpot == AD7376) { 1757 s->n_chan = NUM_CHANNELS_7376; 1758 s->maxdata = 0x7f; 1759 } else { 1760 s->n_chan = NUM_CHANNELS_8402; 1761 s->maxdata = 0xff; 1762 } 1763 s->insn_read = trimpot_read_insn; 1764 s->insn_write = trimpot_write_insn; 1765 for (i = 0; i < s->n_chan; i++) 1766 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2); 1767 1768 /* dac08 caldac */ 1769 s = dev->subdevices + 6; 1770 if (thisboard->has_dac08) { 1771 s->type = COMEDI_SUBD_CALIB; 1772 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 1773 s->n_chan = NUM_CHANNELS_DAC08; 1774 s->insn_read = dac08_read_insn; 1775 s->insn_write = dac08_write_insn; 1776 s->maxdata = 0xff; 1777 dac08_write(dev, s->maxdata / 2); 1778 } else 1779 s->type = COMEDI_SUBD_UNUSED; 1780 1781 /* make sure mailbox 4 is empty */ 1782 inl(devpriv->s5933_config + AMCC_OP_REG_IMB4); 1783 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */ 1784 devpriv->s5933_intcsr_bits = 1785 INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) | 1786 INTCSR_INBOX_FULL_INT; 1787 /* clear and enable interrupt on amcc s5933 */ 1788 outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS, 1789 devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1790 1791 return 1; 1792} 1793 1794static void cb_pcidas_detach(struct comedi_device *dev) 1795{ 1796 if (devpriv) { 1797 if (devpriv->s5933_config) { 1798 outl(INTCSR_INBOX_INTR_STATUS, 1799 devpriv->s5933_config + AMCC_OP_REG_INTCSR); 1800 } 1801 } 1802 if (dev->irq) 1803 free_irq(dev->irq, dev); 1804 if (dev->subdevices) 1805 subdev_8255_cleanup(dev, dev->subdevices + 2); 1806 if (devpriv && devpriv->pci_dev) { 1807 if (devpriv->s5933_config) 1808 comedi_pci_disable(devpriv->pci_dev); 1809 pci_dev_put(devpriv->pci_dev); 1810 } 1811} 1812 1813static struct comedi_driver cb_pcidas_driver = { 1814 .driver_name = "cb_pcidas", 1815 .module = THIS_MODULE, 1816 .attach = cb_pcidas_attach, 1817 .detach = cb_pcidas_detach, 1818}; 1819 1820static int __devinit cb_pcidas_pci_probe(struct pci_dev *dev, 1821 const struct pci_device_id *ent) 1822{ 1823 return comedi_pci_auto_config(dev, &cb_pcidas_driver); 1824} 1825 1826static void __devexit cb_pcidas_pci_remove(struct pci_dev *dev) 1827{ 1828 comedi_pci_auto_unconfig(dev); 1829} 1830 1831static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = { 1832 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0001) }, 1833 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x000f) }, 1834 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0010) }, 1835 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x0019) }, 1836 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001c) }, 1837 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x004c) }, 1838 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001a) }, 1839 { PCI_DEVICE(PCI_VENDOR_ID_CB, 0x001b) }, 1840 { 0 } 1841}; 1842MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table); 1843 1844static struct pci_driver cb_pcidas_pci_driver = { 1845 .name = "cb_pcidas", 1846 .id_table = cb_pcidas_pci_table, 1847 .probe = cb_pcidas_pci_probe, 1848 .remove = __devexit_p(cb_pcidas_pci_remove) 1849}; 1850module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver); 1851 1852MODULE_AUTHOR("Comedi http://www.comedi.org"); 1853MODULE_DESCRIPTION("Comedi low-level driver"); 1854MODULE_LICENSE("GPL"); 1855