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