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