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