1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * cb_pcidas.c 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 14 /* 15 * Driver: cb_pcidas 16 * Description: MeasurementComputing PCI-DAS series 17 * with the AMCC S5933 PCI controller 18 * Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas), 19 * PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr, 20 * PCI-DAS1000, PCI-DAS1001, PCI_DAS1002 21 * Author: Ivan Martinez <imr@oersted.dtu.dk>, 22 * Frank Mori Hess <fmhess@users.sourceforge.net> 23 * Updated: 2003-3-11 24 * 25 * Status: 26 * There are many reports of the driver being used with most of the 27 * supported cards. Despite no detailed log is maintained, it can 28 * be said that the driver is quite tested and stable. 29 * 30 * The boards may be autocalibrated using the comedi_calibrate 31 * utility. 32 * 33 * Configuration options: not applicable, uses PCI auto config 34 * 35 * For commands, the scanned channels must be consecutive 36 * (i.e. 4-5-6-7, 2-3-4,...), and must all have the same 37 * range and aref. 38 * 39 * AI Triggering: 40 * For start_src == TRIG_EXT, the A/D EXTERNAL TRIGGER IN (pin 45) is used. 41 * For 1602 series, the start_arg is interpreted as follows: 42 * start_arg == 0 => gated trigger (level high) 43 * start_arg == CR_INVERT => gated trigger (level low) 44 * start_arg == CR_EDGE => Rising edge 45 * start_arg == CR_EDGE | CR_INVERT => Falling edge 46 * For the other boards the trigger will be done on rising edge 47 */ 48 49 /* 50 * TODO: 51 * analog triggering on 1602 series 52 */ 53 54 #include <linux/module.h> 55 #include <linux/delay.h> 56 #include <linux/interrupt.h> 57 #include <linux/comedi/comedi_pci.h> 58 #include <linux/comedi/comedi_8255.h> 59 #include <linux/comedi/comedi_8254.h> 60 61 #include "amcc_s5933.h" 62 63 #define AI_BUFFER_SIZE 1024 /* max ai fifo size */ 64 #define AO_BUFFER_SIZE 1024 /* max ao fifo size */ 65 66 /* 67 * PCI BAR1 Register map (devpriv->pcibar1) 68 */ 69 #define PCIDAS_CTRL_REG 0x00 /* INTERRUPT / ADC FIFO register */ 70 #define PCIDAS_CTRL_INT(x) (((x) & 0x3) << 0) 71 #define PCIDAS_CTRL_INT_NONE PCIDAS_CTRL_INT(0) /* no int selected */ 72 #define PCIDAS_CTRL_INT_EOS PCIDAS_CTRL_INT(1) /* int on end of scan */ 73 #define PCIDAS_CTRL_INT_FHF PCIDAS_CTRL_INT(2) /* int on fifo half full */ 74 #define PCIDAS_CTRL_INT_FNE PCIDAS_CTRL_INT(3) /* int on fifo not empty */ 75 #define PCIDAS_CTRL_INT_MASK PCIDAS_CTRL_INT(3) /* mask of int select bits */ 76 #define PCIDAS_CTRL_INTE BIT(2) /* int enable */ 77 #define PCIDAS_CTRL_DAHFIE BIT(3) /* dac half full int enable */ 78 #define PCIDAS_CTRL_EOAIE BIT(4) /* end of acq. int enable */ 79 #define PCIDAS_CTRL_DAHFI BIT(5) /* dac half full status / clear */ 80 #define PCIDAS_CTRL_EOAI BIT(6) /* end of acq. int status / clear */ 81 #define PCIDAS_CTRL_INT_CLR BIT(7) /* int status / clear */ 82 #define PCIDAS_CTRL_EOBI BIT(9) /* end of burst int status */ 83 #define PCIDAS_CTRL_ADHFI BIT(10) /* half-full int status */ 84 #define PCIDAS_CTRL_ADNEI BIT(11) /* fifo not empty int status (latch) */ 85 #define PCIDAS_CTRL_ADNE BIT(12) /* fifo not empty status (realtime) */ 86 #define PCIDAS_CTRL_DAEMIE BIT(12) /* dac empty int enable */ 87 #define PCIDAS_CTRL_LADFUL BIT(13) /* fifo overflow / clear */ 88 #define PCIDAS_CTRL_DAEMI BIT(14) /* dac fifo empty int status / clear */ 89 90 #define PCIDAS_CTRL_AI_INT (PCIDAS_CTRL_EOAI | PCIDAS_CTRL_EOBI | \ 91 PCIDAS_CTRL_ADHFI | PCIDAS_CTRL_ADNEI | \ 92 PCIDAS_CTRL_LADFUL) 93 #define PCIDAS_CTRL_AO_INT (PCIDAS_CTRL_DAHFI | PCIDAS_CTRL_DAEMI) 94 95 #define PCIDAS_AI_REG 0x02 /* ADC CHANNEL MUX AND CONTROL reg */ 96 #define PCIDAS_AI_FIRST(x) ((x) & 0xf) 97 #define PCIDAS_AI_LAST(x) (((x) & 0xf) << 4) 98 #define PCIDAS_AI_CHAN(x) (PCIDAS_AI_FIRST(x) | PCIDAS_AI_LAST(x)) 99 #define PCIDAS_AI_GAIN(x) (((x) & 0x3) << 8) 100 #define PCIDAS_AI_SE BIT(10) /* Inputs in single-ended mode */ 101 #define PCIDAS_AI_UNIP BIT(11) /* Analog front-end unipolar mode */ 102 #define PCIDAS_AI_PACER(x) (((x) & 0x3) << 12) 103 #define PCIDAS_AI_PACER_SW PCIDAS_AI_PACER(0) /* software pacer */ 104 #define PCIDAS_AI_PACER_INT PCIDAS_AI_PACER(1) /* int. pacer */ 105 #define PCIDAS_AI_PACER_EXTN PCIDAS_AI_PACER(2) /* ext. falling edge */ 106 #define PCIDAS_AI_PACER_EXTP PCIDAS_AI_PACER(3) /* ext. rising edge */ 107 #define PCIDAS_AI_PACER_MASK PCIDAS_AI_PACER(3) /* pacer source bits */ 108 #define PCIDAS_AI_EOC BIT(14) /* adc not busy */ 109 110 #define PCIDAS_TRIG_REG 0x04 /* TRIGGER CONTROL/STATUS register */ 111 #define PCIDAS_TRIG_SEL(x) (((x) & 0x3) << 0) 112 #define PCIDAS_TRIG_SEL_NONE PCIDAS_TRIG_SEL(0) /* no start trigger */ 113 #define PCIDAS_TRIG_SEL_SW PCIDAS_TRIG_SEL(1) /* software start trigger */ 114 #define PCIDAS_TRIG_SEL_EXT PCIDAS_TRIG_SEL(2) /* ext. start trigger */ 115 #define PCIDAS_TRIG_SEL_ANALOG PCIDAS_TRIG_SEL(3) /* ext. analog trigger */ 116 #define PCIDAS_TRIG_SEL_MASK PCIDAS_TRIG_SEL(3) /* start trigger mask */ 117 #define PCIDAS_TRIG_POL BIT(2) /* invert trigger (1602 only) */ 118 #define PCIDAS_TRIG_MODE BIT(3) /* edge/level triggered (1602 only) */ 119 #define PCIDAS_TRIG_EN BIT(4) /* enable external start trigger */ 120 #define PCIDAS_TRIG_BURSTE BIT(5) /* burst mode enable */ 121 #define PCIDAS_TRIG_CLR BIT(7) /* clear external trigger */ 122 123 #define PCIDAS_CALIB_REG 0x06 /* CALIBRATION register */ 124 #define PCIDAS_CALIB_8800_SEL BIT(8) /* select 8800 caldac */ 125 #define PCIDAS_CALIB_TRIM_SEL BIT(9) /* select ad7376 trim pot */ 126 #define PCIDAS_CALIB_DAC08_SEL BIT(10) /* select dac08 caldac */ 127 #define PCIDAS_CALIB_SRC(x) (((x) & 0x7) << 11) 128 #define PCIDAS_CALIB_EN BIT(14) /* calibration source enable */ 129 #define PCIDAS_CALIB_DATA BIT(15) /* serial data bit going to caldac */ 130 131 #define PCIDAS_AO_REG 0x08 /* dac control and status register */ 132 #define PCIDAS_AO_EMPTY BIT(0) /* fifo empty, write clear (1602) */ 133 #define PCIDAS_AO_DACEN BIT(1) /* dac enable */ 134 #define PCIDAS_AO_START BIT(2) /* start/arm fifo (1602) */ 135 #define PCIDAS_AO_PACER(x) (((x) & 0x3) << 3) /* (1602) */ 136 #define PCIDAS_AO_PACER_SW PCIDAS_AO_PACER(0) /* software pacer */ 137 #define PCIDAS_AO_PACER_INT PCIDAS_AO_PACER(1) /* int. pacer */ 138 #define PCIDAS_AO_PACER_EXTN PCIDAS_AO_PACER(2) /* ext. falling edge */ 139 #define PCIDAS_AO_PACER_EXTP PCIDAS_AO_PACER(3) /* ext. rising edge */ 140 #define PCIDAS_AO_PACER_MASK PCIDAS_AO_PACER(3) /* pacer source bits */ 141 #define PCIDAS_AO_CHAN_EN(c) BIT(5 + ((c) & 0x1)) 142 #define PCIDAS_AO_CHAN_MASK (PCIDAS_AO_CHAN_EN(0) | PCIDAS_AO_CHAN_EN(1)) 143 #define PCIDAS_AO_UPDATE_BOTH BIT(7) /* update both dacs */ 144 #define PCIDAS_AO_RANGE(c, r) (((r) & 0x3) << (8 + 2 * ((c) & 0x1))) 145 #define PCIDAS_AO_RANGE_MASK(c) PCIDAS_AO_RANGE((c), 0x3) 146 147 /* 148 * PCI BAR2 Register map (devpriv->pcibar2) 149 */ 150 #define PCIDAS_AI_DATA_REG 0x00 151 #define PCIDAS_AI_FIFO_CLR_REG 0x02 152 153 /* 154 * PCI BAR3 Register map (dev->iobase) 155 */ 156 #define PCIDAS_AI_8254_BASE 0x00 157 #define PCIDAS_8255_BASE 0x04 158 #define PCIDAS_AO_8254_BASE 0x08 159 160 /* 161 * PCI BAR4 Register map (devpriv->pcibar4) 162 */ 163 #define PCIDAS_AO_DATA_REG(x) (0x00 + ((x) * 2)) 164 #define PCIDAS_AO_FIFO_REG 0x00 165 #define PCIDAS_AO_FIFO_CLR_REG 0x02 166 167 /* analog input ranges for most boards */ 168 static const struct comedi_lrange cb_pcidas_ranges = { 169 8, { 170 BIP_RANGE(10), 171 BIP_RANGE(5), 172 BIP_RANGE(2.5), 173 BIP_RANGE(1.25), 174 UNI_RANGE(10), 175 UNI_RANGE(5), 176 UNI_RANGE(2.5), 177 UNI_RANGE(1.25) 178 } 179 }; 180 181 /* pci-das1001 input ranges */ 182 static const struct comedi_lrange cb_pcidas_alt_ranges = { 183 8, { 184 BIP_RANGE(10), 185 BIP_RANGE(1), 186 BIP_RANGE(0.1), 187 BIP_RANGE(0.01), 188 UNI_RANGE(10), 189 UNI_RANGE(1), 190 UNI_RANGE(0.1), 191 UNI_RANGE(0.01) 192 } 193 }; 194 195 /* analog output ranges */ 196 static const struct comedi_lrange cb_pcidas_ao_ranges = { 197 4, { 198 BIP_RANGE(5), 199 BIP_RANGE(10), 200 UNI_RANGE(5), 201 UNI_RANGE(10) 202 } 203 }; 204 205 enum cb_pcidas_boardid { 206 BOARD_PCIDAS1602_16, 207 BOARD_PCIDAS1200, 208 BOARD_PCIDAS1602_12, 209 BOARD_PCIDAS1200_JR, 210 BOARD_PCIDAS1602_16_JR, 211 BOARD_PCIDAS1000, 212 BOARD_PCIDAS1001, 213 BOARD_PCIDAS1002, 214 }; 215 216 struct cb_pcidas_board { 217 const char *name; 218 int ai_speed; /* fastest conversion period in ns */ 219 int ao_scan_speed; /* analog output scan speed for 1602 series */ 220 int fifo_size; /* number of samples fifo can hold */ 221 unsigned int is_16bit; /* ai/ao is 1=16-bit; 0=12-bit */ 222 unsigned int use_alt_range:1; /* use alternate ai range table */ 223 unsigned int has_ao:1; /* has 2 analog output channels */ 224 unsigned int has_ao_fifo:1; /* analog output has fifo */ 225 unsigned int has_ad8402:1; /* trimpot type 1=AD8402; 0=AD7376 */ 226 unsigned int has_dac08:1; 227 unsigned int is_1602:1; 228 }; 229 230 static const struct cb_pcidas_board cb_pcidas_boards[] = { 231 [BOARD_PCIDAS1602_16] = { 232 .name = "pci-das1602/16", 233 .ai_speed = 5000, 234 .ao_scan_speed = 10000, 235 .fifo_size = 512, 236 .is_16bit = 1, 237 .has_ao = 1, 238 .has_ao_fifo = 1, 239 .has_ad8402 = 1, 240 .has_dac08 = 1, 241 .is_1602 = 1, 242 }, 243 [BOARD_PCIDAS1200] = { 244 .name = "pci-das1200", 245 .ai_speed = 3200, 246 .fifo_size = 1024, 247 .has_ao = 1, 248 }, 249 [BOARD_PCIDAS1602_12] = { 250 .name = "pci-das1602/12", 251 .ai_speed = 3200, 252 .ao_scan_speed = 4000, 253 .fifo_size = 1024, 254 .has_ao = 1, 255 .has_ao_fifo = 1, 256 .is_1602 = 1, 257 }, 258 [BOARD_PCIDAS1200_JR] = { 259 .name = "pci-das1200/jr", 260 .ai_speed = 3200, 261 .fifo_size = 1024, 262 }, 263 [BOARD_PCIDAS1602_16_JR] = { 264 .name = "pci-das1602/16/jr", 265 .ai_speed = 5000, 266 .fifo_size = 512, 267 .is_16bit = 1, 268 .has_ad8402 = 1, 269 .has_dac08 = 1, 270 .is_1602 = 1, 271 }, 272 [BOARD_PCIDAS1000] = { 273 .name = "pci-das1000", 274 .ai_speed = 4000, 275 .fifo_size = 1024, 276 }, 277 [BOARD_PCIDAS1001] = { 278 .name = "pci-das1001", 279 .ai_speed = 6800, 280 .fifo_size = 1024, 281 .use_alt_range = 1, 282 .has_ao = 1, 283 }, 284 [BOARD_PCIDAS1002] = { 285 .name = "pci-das1002", 286 .ai_speed = 6800, 287 .fifo_size = 1024, 288 .has_ao = 1, 289 }, 290 }; 291 292 struct cb_pcidas_private { 293 struct comedi_8254 *ao_pacer; 294 /* base addresses */ 295 unsigned long amcc; /* pcibar0 */ 296 unsigned long pcibar1; 297 unsigned long pcibar2; 298 unsigned long pcibar4; 299 /* bits to write to registers */ 300 unsigned int ctrl; 301 unsigned int amcc_intcsr; 302 unsigned int ao_ctrl; 303 /* fifo buffers */ 304 unsigned short ai_buffer[AI_BUFFER_SIZE]; 305 unsigned short ao_buffer[AO_BUFFER_SIZE]; 306 unsigned int calib_src; 307 }; 308 309 static int cb_pcidas_ai_eoc(struct comedi_device *dev, 310 struct comedi_subdevice *s, 311 struct comedi_insn *insn, 312 unsigned long context) 313 { 314 struct cb_pcidas_private *devpriv = dev->private; 315 unsigned int status; 316 317 status = inw(devpriv->pcibar1 + PCIDAS_AI_REG); 318 if (status & PCIDAS_AI_EOC) 319 return 0; 320 return -EBUSY; 321 } 322 323 static int cb_pcidas_ai_insn_read(struct comedi_device *dev, 324 struct comedi_subdevice *s, 325 struct comedi_insn *insn, 326 unsigned int *data) 327 { 328 struct cb_pcidas_private *devpriv = dev->private; 329 unsigned int chan = CR_CHAN(insn->chanspec); 330 unsigned int range = CR_RANGE(insn->chanspec); 331 unsigned int aref = CR_AREF(insn->chanspec); 332 unsigned int bits; 333 int ret; 334 int n; 335 336 /* enable calibration input if appropriate */ 337 if (insn->chanspec & CR_ALT_SOURCE) { 338 outw(PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src), 339 devpriv->pcibar1 + PCIDAS_CALIB_REG); 340 chan = 0; 341 } else { 342 outw(0, devpriv->pcibar1 + PCIDAS_CALIB_REG); 343 } 344 345 /* set mux limits and gain */ 346 bits = PCIDAS_AI_CHAN(chan) | PCIDAS_AI_GAIN(range); 347 /* set unipolar/bipolar */ 348 if (comedi_range_is_unipolar(s, range)) 349 bits |= PCIDAS_AI_UNIP; 350 /* set single-ended/differential */ 351 if (aref != AREF_DIFF) 352 bits |= PCIDAS_AI_SE; 353 outw(bits, devpriv->pcibar1 + PCIDAS_AI_REG); 354 355 /* clear fifo */ 356 outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG); 357 358 /* convert n samples */ 359 for (n = 0; n < insn->n; n++) { 360 /* trigger conversion */ 361 outw(0, devpriv->pcibar2 + PCIDAS_AI_DATA_REG); 362 363 /* wait for conversion to end */ 364 ret = comedi_timeout(dev, s, insn, cb_pcidas_ai_eoc, 0); 365 if (ret) 366 return ret; 367 368 /* read data */ 369 data[n] = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG); 370 } 371 372 /* return the number of samples read/written */ 373 return n; 374 } 375 376 static int cb_pcidas_ai_insn_config(struct comedi_device *dev, 377 struct comedi_subdevice *s, 378 struct comedi_insn *insn, 379 unsigned int *data) 380 { 381 struct cb_pcidas_private *devpriv = dev->private; 382 int id = data[0]; 383 unsigned int source = data[1]; 384 385 switch (id) { 386 case INSN_CONFIG_ALT_SOURCE: 387 if (source >= 8) { 388 dev_err(dev->class_dev, 389 "invalid calibration source: %i\n", 390 source); 391 return -EINVAL; 392 } 393 devpriv->calib_src = source; 394 break; 395 default: 396 return -EINVAL; 397 } 398 return insn->n; 399 } 400 401 /* analog output insn for pcidas-1000 and 1200 series */ 402 static int cb_pcidas_ao_nofifo_insn_write(struct comedi_device *dev, 403 struct comedi_subdevice *s, 404 struct comedi_insn *insn, 405 unsigned int *data) 406 { 407 struct cb_pcidas_private *devpriv = dev->private; 408 unsigned int chan = CR_CHAN(insn->chanspec); 409 unsigned int range = CR_RANGE(insn->chanspec); 410 unsigned int val = s->readback[chan]; 411 unsigned long flags; 412 int i; 413 414 /* set channel and range */ 415 spin_lock_irqsave(&dev->spinlock, flags); 416 devpriv->ao_ctrl &= ~(PCIDAS_AO_UPDATE_BOTH | 417 PCIDAS_AO_RANGE_MASK(chan)); 418 devpriv->ao_ctrl |= PCIDAS_AO_DACEN | PCIDAS_AO_RANGE(chan, range); 419 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG); 420 spin_unlock_irqrestore(&dev->spinlock, flags); 421 422 for (i = 0; i < insn->n; i++) { 423 val = data[i]; 424 outw(val, devpriv->pcibar4 + PCIDAS_AO_DATA_REG(chan)); 425 } 426 427 s->readback[chan] = val; 428 429 return insn->n; 430 } 431 432 /* analog output insn for pcidas-1602 series */ 433 static int cb_pcidas_ao_fifo_insn_write(struct comedi_device *dev, 434 struct comedi_subdevice *s, 435 struct comedi_insn *insn, 436 unsigned int *data) 437 { 438 struct cb_pcidas_private *devpriv = dev->private; 439 unsigned int chan = CR_CHAN(insn->chanspec); 440 unsigned int range = CR_RANGE(insn->chanspec); 441 unsigned int val = s->readback[chan]; 442 unsigned long flags; 443 int i; 444 445 /* clear dac fifo */ 446 outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG); 447 448 /* set channel and range */ 449 spin_lock_irqsave(&dev->spinlock, flags); 450 devpriv->ao_ctrl &= ~(PCIDAS_AO_CHAN_MASK | PCIDAS_AO_RANGE_MASK(chan) | 451 PCIDAS_AO_PACER_MASK); 452 devpriv->ao_ctrl |= PCIDAS_AO_DACEN | PCIDAS_AO_RANGE(chan, range) | 453 PCIDAS_AO_CHAN_EN(chan) | PCIDAS_AO_START; 454 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG); 455 spin_unlock_irqrestore(&dev->spinlock, flags); 456 457 for (i = 0; i < insn->n; i++) { 458 val = data[i]; 459 outw(val, devpriv->pcibar4 + PCIDAS_AO_FIFO_REG); 460 } 461 462 s->readback[chan] = val; 463 464 return insn->n; 465 } 466 467 static int cb_pcidas_eeprom_ready(struct comedi_device *dev, 468 struct comedi_subdevice *s, 469 struct comedi_insn *insn, 470 unsigned long context) 471 { 472 struct cb_pcidas_private *devpriv = dev->private; 473 unsigned int status; 474 475 status = inb(devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD); 476 if ((status & MCSR_NV_BUSY) == 0) 477 return 0; 478 return -EBUSY; 479 } 480 481 static int cb_pcidas_eeprom_insn_read(struct comedi_device *dev, 482 struct comedi_subdevice *s, 483 struct comedi_insn *insn, 484 unsigned int *data) 485 { 486 struct cb_pcidas_private *devpriv = dev->private; 487 unsigned int chan = CR_CHAN(insn->chanspec); 488 int ret; 489 int i; 490 491 for (i = 0; i < insn->n; i++) { 492 /* make sure eeprom is ready */ 493 ret = comedi_timeout(dev, s, insn, cb_pcidas_eeprom_ready, 0); 494 if (ret) 495 return ret; 496 497 /* set address (chan) and read operation */ 498 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR, 499 devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD); 500 outb(chan & 0xff, devpriv->amcc + AMCC_OP_REG_MCSR_NVDATA); 501 outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR, 502 devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD); 503 outb((chan >> 8) & 0xff, 504 devpriv->amcc + AMCC_OP_REG_MCSR_NVDATA); 505 outb(MCSR_NV_ENABLE | MCSR_NV_READ, 506 devpriv->amcc + AMCC_OP_REG_MCSR_NVCMD); 507 508 /* wait for data to be returned */ 509 ret = comedi_timeout(dev, s, insn, cb_pcidas_eeprom_ready, 0); 510 if (ret) 511 return ret; 512 513 data[i] = inb(devpriv->amcc + AMCC_OP_REG_MCSR_NVDATA); 514 } 515 516 return insn->n; 517 } 518 519 static void cb_pcidas_calib_write(struct comedi_device *dev, 520 unsigned int val, unsigned int len, 521 bool trimpot) 522 { 523 struct cb_pcidas_private *devpriv = dev->private; 524 unsigned int calib_bits; 525 unsigned int bit; 526 527 calib_bits = PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src); 528 if (trimpot) { 529 /* select trimpot */ 530 calib_bits |= PCIDAS_CALIB_TRIM_SEL; 531 outw(calib_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG); 532 } 533 534 /* write bitstream to calibration device */ 535 for (bit = 1 << (len - 1); bit; bit >>= 1) { 536 if (val & bit) 537 calib_bits |= PCIDAS_CALIB_DATA; 538 else 539 calib_bits &= ~PCIDAS_CALIB_DATA; 540 udelay(1); 541 outw(calib_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG); 542 } 543 udelay(1); 544 545 calib_bits = PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src); 546 547 if (!trimpot) { 548 /* select caldac */ 549 outw(calib_bits | PCIDAS_CALIB_8800_SEL, 550 devpriv->pcibar1 + PCIDAS_CALIB_REG); 551 udelay(1); 552 } 553 554 /* latch value to trimpot/caldac */ 555 outw(calib_bits, devpriv->pcibar1 + PCIDAS_CALIB_REG); 556 } 557 558 static int cb_pcidas_caldac_insn_write(struct comedi_device *dev, 559 struct comedi_subdevice *s, 560 struct comedi_insn *insn, 561 unsigned int *data) 562 { 563 unsigned int chan = CR_CHAN(insn->chanspec); 564 565 if (insn->n) { 566 unsigned int val = data[insn->n - 1]; 567 568 if (s->readback[chan] != val) { 569 /* write 11-bit channel/value to caldac */ 570 cb_pcidas_calib_write(dev, (chan << 8) | val, 11, 571 false); 572 s->readback[chan] = val; 573 } 574 } 575 576 return insn->n; 577 } 578 579 static void cb_pcidas_dac08_write(struct comedi_device *dev, unsigned int val) 580 { 581 struct cb_pcidas_private *devpriv = dev->private; 582 583 val |= PCIDAS_CALIB_EN | PCIDAS_CALIB_SRC(devpriv->calib_src); 584 585 /* latch the new value into the caldac */ 586 outw(val, devpriv->pcibar1 + PCIDAS_CALIB_REG); 587 udelay(1); 588 outw(val | PCIDAS_CALIB_DAC08_SEL, 589 devpriv->pcibar1 + PCIDAS_CALIB_REG); 590 udelay(1); 591 outw(val, devpriv->pcibar1 + PCIDAS_CALIB_REG); 592 udelay(1); 593 } 594 595 static int cb_pcidas_dac08_insn_write(struct comedi_device *dev, 596 struct comedi_subdevice *s, 597 struct comedi_insn *insn, 598 unsigned int *data) 599 { 600 unsigned int chan = CR_CHAN(insn->chanspec); 601 602 if (insn->n) { 603 unsigned int val = data[insn->n - 1]; 604 605 if (s->readback[chan] != val) { 606 cb_pcidas_dac08_write(dev, val); 607 s->readback[chan] = val; 608 } 609 } 610 611 return insn->n; 612 } 613 614 static void cb_pcidas_trimpot_write(struct comedi_device *dev, 615 unsigned int chan, unsigned int val) 616 { 617 const struct cb_pcidas_board *board = dev->board_ptr; 618 619 if (board->has_ad8402) { 620 /* write 10-bit channel/value to AD8402 trimpot */ 621 cb_pcidas_calib_write(dev, (chan << 8) | val, 10, true); 622 } else { 623 /* write 7-bit value to AD7376 trimpot */ 624 cb_pcidas_calib_write(dev, val, 7, true); 625 } 626 } 627 628 static int cb_pcidas_trimpot_insn_write(struct comedi_device *dev, 629 struct comedi_subdevice *s, 630 struct comedi_insn *insn, 631 unsigned int *data) 632 { 633 unsigned int chan = CR_CHAN(insn->chanspec); 634 635 if (insn->n) { 636 unsigned int val = data[insn->n - 1]; 637 638 if (s->readback[chan] != val) { 639 cb_pcidas_trimpot_write(dev, chan, val); 640 s->readback[chan] = val; 641 } 642 } 643 644 return insn->n; 645 } 646 647 static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev, 648 struct comedi_subdevice *s, 649 struct comedi_cmd *cmd) 650 { 651 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); 652 unsigned int range0 = CR_RANGE(cmd->chanlist[0]); 653 int i; 654 655 for (i = 1; i < cmd->chanlist_len; i++) { 656 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 657 unsigned int range = CR_RANGE(cmd->chanlist[i]); 658 659 if (chan != (chan0 + i) % s->n_chan) { 660 dev_dbg(dev->class_dev, 661 "entries in chanlist must be consecutive channels, counting upwards\n"); 662 return -EINVAL; 663 } 664 665 if (range != range0) { 666 dev_dbg(dev->class_dev, 667 "entries in chanlist must all have the same gain\n"); 668 return -EINVAL; 669 } 670 } 671 return 0; 672 } 673 674 static int cb_pcidas_ai_cmdtest(struct comedi_device *dev, 675 struct comedi_subdevice *s, 676 struct comedi_cmd *cmd) 677 { 678 const struct cb_pcidas_board *board = dev->board_ptr; 679 int err = 0; 680 unsigned int arg; 681 682 /* Step 1 : check if triggers are trivially valid */ 683 684 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); 685 err |= comedi_check_trigger_src(&cmd->scan_begin_src, 686 TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT); 687 err |= comedi_check_trigger_src(&cmd->convert_src, 688 TRIG_TIMER | TRIG_NOW | TRIG_EXT); 689 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 690 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 691 692 if (err) 693 return 1; 694 695 /* Step 2a : make sure trigger sources are unique */ 696 697 err |= comedi_check_trigger_is_unique(cmd->start_src); 698 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); 699 err |= comedi_check_trigger_is_unique(cmd->convert_src); 700 err |= comedi_check_trigger_is_unique(cmd->stop_src); 701 702 /* Step 2b : and mutually compatible */ 703 704 if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW) 705 err |= -EINVAL; 706 if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW) 707 err |= -EINVAL; 708 if (cmd->start_src == TRIG_EXT && 709 (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)) 710 err |= -EINVAL; 711 712 if (err) 713 return 2; 714 715 /* Step 3: check if arguments are trivially valid */ 716 717 switch (cmd->start_src) { 718 case TRIG_NOW: 719 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); 720 break; 721 case TRIG_EXT: 722 /* External trigger, only CR_EDGE and CR_INVERT flags allowed */ 723 if ((cmd->start_arg 724 & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) { 725 cmd->start_arg &= ~(CR_FLAGS_MASK & 726 ~(CR_EDGE | CR_INVERT)); 727 err |= -EINVAL; 728 } 729 if (!board->is_1602 && (cmd->start_arg & CR_INVERT)) { 730 cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT); 731 err |= -EINVAL; 732 } 733 break; 734 } 735 736 if (cmd->scan_begin_src == TRIG_TIMER) { 737 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 738 board->ai_speed * 739 cmd->chanlist_len); 740 } 741 742 if (cmd->convert_src == TRIG_TIMER) { 743 err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 744 board->ai_speed); 745 } 746 747 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, 748 cmd->chanlist_len); 749 750 if (cmd->stop_src == TRIG_COUNT) 751 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); 752 else /* TRIG_NONE */ 753 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); 754 755 if (err) 756 return 3; 757 758 /* step 4: fix up any arguments */ 759 760 if (cmd->scan_begin_src == TRIG_TIMER) { 761 arg = cmd->scan_begin_arg; 762 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); 763 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg); 764 } 765 if (cmd->convert_src == TRIG_TIMER) { 766 arg = cmd->convert_arg; 767 comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags); 768 err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg); 769 } 770 771 if (err) 772 return 4; 773 774 /* Step 5: check channel list if it exists */ 775 if (cmd->chanlist && cmd->chanlist_len > 0) 776 err |= cb_pcidas_ai_check_chanlist(dev, s, cmd); 777 778 if (err) 779 return 5; 780 781 return 0; 782 } 783 784 static int cb_pcidas_ai_cmd(struct comedi_device *dev, 785 struct comedi_subdevice *s) 786 { 787 const struct cb_pcidas_board *board = dev->board_ptr; 788 struct cb_pcidas_private *devpriv = dev->private; 789 struct comedi_async *async = s->async; 790 struct comedi_cmd *cmd = &async->cmd; 791 unsigned int range0 = CR_RANGE(cmd->chanlist[0]); 792 unsigned int bits; 793 unsigned long flags; 794 795 /* make sure PCIDAS_CALIB_EN is disabled */ 796 outw(0, devpriv->pcibar1 + PCIDAS_CALIB_REG); 797 /* initialize before settings pacer source and count values */ 798 outw(PCIDAS_TRIG_SEL_NONE, devpriv->pcibar1 + PCIDAS_TRIG_REG); 799 /* clear fifo */ 800 outw(0, devpriv->pcibar2 + PCIDAS_AI_FIFO_CLR_REG); 801 802 /* set mux limits, gain and pacer source */ 803 bits = PCIDAS_AI_FIRST(CR_CHAN(cmd->chanlist[0])) | 804 PCIDAS_AI_LAST(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) | 805 PCIDAS_AI_GAIN(range0); 806 /* set unipolar/bipolar */ 807 if (comedi_range_is_unipolar(s, range0)) 808 bits |= PCIDAS_AI_UNIP; 809 /* set singleended/differential */ 810 if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF) 811 bits |= PCIDAS_AI_SE; 812 /* set pacer source */ 813 if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT) 814 bits |= PCIDAS_AI_PACER_EXTP; 815 else 816 bits |= PCIDAS_AI_PACER_INT; 817 outw(bits, devpriv->pcibar1 + PCIDAS_AI_REG); 818 819 /* load counters */ 820 if (cmd->scan_begin_src == TRIG_TIMER || 821 cmd->convert_src == TRIG_TIMER) { 822 comedi_8254_update_divisors(dev->pacer); 823 comedi_8254_pacer_enable(dev->pacer, 1, 2, true); 824 } 825 826 /* enable interrupts */ 827 spin_lock_irqsave(&dev->spinlock, flags); 828 devpriv->ctrl |= PCIDAS_CTRL_INTE; 829 devpriv->ctrl &= ~PCIDAS_CTRL_INT_MASK; 830 if (cmd->flags & CMDF_WAKE_EOS) { 831 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) { 832 /* interrupt end of burst */ 833 devpriv->ctrl |= PCIDAS_CTRL_INT_EOS; 834 } else { 835 /* interrupt fifo not empty */ 836 devpriv->ctrl |= PCIDAS_CTRL_INT_FNE; 837 } 838 } else { 839 /* interrupt fifo half full */ 840 devpriv->ctrl |= PCIDAS_CTRL_INT_FHF; 841 } 842 843 /* enable (and clear) interrupts */ 844 outw(devpriv->ctrl | 845 PCIDAS_CTRL_EOAI | PCIDAS_CTRL_INT_CLR | PCIDAS_CTRL_LADFUL, 846 devpriv->pcibar1 + PCIDAS_CTRL_REG); 847 spin_unlock_irqrestore(&dev->spinlock, flags); 848 849 /* set start trigger and burst mode */ 850 bits = 0; 851 if (cmd->start_src == TRIG_NOW) { 852 bits |= PCIDAS_TRIG_SEL_SW; 853 } else { /* TRIG_EXT */ 854 bits |= PCIDAS_TRIG_SEL_EXT | PCIDAS_TRIG_EN | PCIDAS_TRIG_CLR; 855 if (board->is_1602) { 856 if (cmd->start_arg & CR_INVERT) 857 bits |= PCIDAS_TRIG_POL; 858 if (cmd->start_arg & CR_EDGE) 859 bits |= PCIDAS_TRIG_MODE; 860 } 861 } 862 if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) 863 bits |= PCIDAS_TRIG_BURSTE; 864 outw(bits, devpriv->pcibar1 + PCIDAS_TRIG_REG); 865 866 return 0; 867 } 868 869 static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev, 870 struct comedi_subdevice *s, 871 struct comedi_cmd *cmd) 872 { 873 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); 874 875 if (cmd->chanlist_len > 1) { 876 unsigned int chan1 = CR_CHAN(cmd->chanlist[1]); 877 878 if (chan0 != 0 || chan1 != 1) { 879 dev_dbg(dev->class_dev, 880 "channels must be ordered channel 0, channel 1 in chanlist\n"); 881 return -EINVAL; 882 } 883 } 884 885 return 0; 886 } 887 888 static int cb_pcidas_ao_cmdtest(struct comedi_device *dev, 889 struct comedi_subdevice *s, 890 struct comedi_cmd *cmd) 891 { 892 const struct cb_pcidas_board *board = dev->board_ptr; 893 struct cb_pcidas_private *devpriv = dev->private; 894 int err = 0; 895 896 /* Step 1 : check if triggers are trivially valid */ 897 898 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_INT); 899 err |= comedi_check_trigger_src(&cmd->scan_begin_src, 900 TRIG_TIMER | TRIG_EXT); 901 err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_NOW); 902 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 903 err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE); 904 905 if (err) 906 return 1; 907 908 /* Step 2a : make sure trigger sources are unique */ 909 910 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); 911 err |= comedi_check_trigger_is_unique(cmd->stop_src); 912 913 /* Step 2b : and mutually compatible */ 914 915 if (err) 916 return 2; 917 918 /* Step 3: check if arguments are trivially valid */ 919 920 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); 921 922 if (cmd->scan_begin_src == TRIG_TIMER) { 923 err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, 924 board->ao_scan_speed); 925 } 926 927 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, 928 cmd->chanlist_len); 929 930 if (cmd->stop_src == TRIG_COUNT) 931 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); 932 else /* TRIG_NONE */ 933 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); 934 935 if (err) 936 return 3; 937 938 /* step 4: fix up any arguments */ 939 940 if (cmd->scan_begin_src == TRIG_TIMER) { 941 unsigned int arg = cmd->scan_begin_arg; 942 943 comedi_8254_cascade_ns_to_timer(devpriv->ao_pacer, 944 &arg, cmd->flags); 945 err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg); 946 } 947 948 if (err) 949 return 4; 950 951 /* Step 5: check channel list if it exists */ 952 if (cmd->chanlist && cmd->chanlist_len > 0) 953 err |= cb_pcidas_ao_check_chanlist(dev, s, cmd); 954 955 if (err) 956 return 5; 957 958 return 0; 959 } 960 961 static int cb_pcidas_ai_cancel(struct comedi_device *dev, 962 struct comedi_subdevice *s) 963 { 964 struct cb_pcidas_private *devpriv = dev->private; 965 unsigned long flags; 966 967 spin_lock_irqsave(&dev->spinlock, flags); 968 /* disable interrupts */ 969 devpriv->ctrl &= ~(PCIDAS_CTRL_INTE | PCIDAS_CTRL_EOAIE); 970 outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG); 971 spin_unlock_irqrestore(&dev->spinlock, flags); 972 973 /* disable start trigger source and burst mode */ 974 outw(PCIDAS_TRIG_SEL_NONE, devpriv->pcibar1 + PCIDAS_TRIG_REG); 975 outw(PCIDAS_AI_PACER_SW, devpriv->pcibar1 + PCIDAS_AI_REG); 976 977 return 0; 978 } 979 980 static void cb_pcidas_ao_load_fifo(struct comedi_device *dev, 981 struct comedi_subdevice *s, 982 unsigned int nsamples) 983 { 984 struct cb_pcidas_private *devpriv = dev->private; 985 unsigned int nbytes; 986 987 nsamples = comedi_nsamples_left(s, nsamples); 988 nbytes = comedi_buf_read_samples(s, devpriv->ao_buffer, nsamples); 989 990 nsamples = comedi_bytes_to_samples(s, nbytes); 991 outsw(devpriv->pcibar4 + PCIDAS_AO_FIFO_REG, 992 devpriv->ao_buffer, nsamples); 993 } 994 995 static int cb_pcidas_ao_inttrig(struct comedi_device *dev, 996 struct comedi_subdevice *s, 997 unsigned int trig_num) 998 { 999 const struct cb_pcidas_board *board = dev->board_ptr; 1000 struct cb_pcidas_private *devpriv = dev->private; 1001 struct comedi_async *async = s->async; 1002 struct comedi_cmd *cmd = &async->cmd; 1003 unsigned long flags; 1004 1005 if (trig_num != cmd->start_arg) 1006 return -EINVAL; 1007 1008 cb_pcidas_ao_load_fifo(dev, s, board->fifo_size); 1009 1010 /* enable dac half-full and empty interrupts */ 1011 spin_lock_irqsave(&dev->spinlock, flags); 1012 devpriv->ctrl |= PCIDAS_CTRL_DAEMIE | PCIDAS_CTRL_DAHFIE; 1013 1014 /* enable and clear interrupts */ 1015 outw(devpriv->ctrl | PCIDAS_CTRL_DAEMI | PCIDAS_CTRL_DAHFI, 1016 devpriv->pcibar1 + PCIDAS_CTRL_REG); 1017 1018 /* start dac */ 1019 devpriv->ao_ctrl |= PCIDAS_AO_START | PCIDAS_AO_DACEN | PCIDAS_AO_EMPTY; 1020 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG); 1021 1022 spin_unlock_irqrestore(&dev->spinlock, flags); 1023 1024 async->inttrig = NULL; 1025 1026 return 0; 1027 } 1028 1029 static int cb_pcidas_ao_cmd(struct comedi_device *dev, 1030 struct comedi_subdevice *s) 1031 { 1032 struct cb_pcidas_private *devpriv = dev->private; 1033 struct comedi_async *async = s->async; 1034 struct comedi_cmd *cmd = &async->cmd; 1035 unsigned int i; 1036 unsigned long flags; 1037 1038 /* set channel limits, gain */ 1039 spin_lock_irqsave(&dev->spinlock, flags); 1040 for (i = 0; i < cmd->chanlist_len; i++) { 1041 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 1042 unsigned int range = CR_RANGE(cmd->chanlist[i]); 1043 1044 /* enable channel */ 1045 devpriv->ao_ctrl |= PCIDAS_AO_CHAN_EN(chan); 1046 /* set range */ 1047 devpriv->ao_ctrl |= PCIDAS_AO_RANGE(chan, range); 1048 } 1049 1050 /* disable analog out before settings pacer source and count values */ 1051 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG); 1052 spin_unlock_irqrestore(&dev->spinlock, flags); 1053 1054 /* clear fifo */ 1055 outw(0, devpriv->pcibar4 + PCIDAS_AO_FIFO_CLR_REG); 1056 1057 /* load counters */ 1058 if (cmd->scan_begin_src == TRIG_TIMER) { 1059 comedi_8254_update_divisors(devpriv->ao_pacer); 1060 comedi_8254_pacer_enable(devpriv->ao_pacer, 1, 2, true); 1061 } 1062 1063 /* set pacer source */ 1064 spin_lock_irqsave(&dev->spinlock, flags); 1065 switch (cmd->scan_begin_src) { 1066 case TRIG_TIMER: 1067 devpriv->ao_ctrl |= PCIDAS_AO_PACER_INT; 1068 break; 1069 case TRIG_EXT: 1070 devpriv->ao_ctrl |= PCIDAS_AO_PACER_EXTP; 1071 break; 1072 default: 1073 spin_unlock_irqrestore(&dev->spinlock, flags); 1074 dev_err(dev->class_dev, "error setting dac pacer source\n"); 1075 return -1; 1076 } 1077 spin_unlock_irqrestore(&dev->spinlock, flags); 1078 1079 async->inttrig = cb_pcidas_ao_inttrig; 1080 1081 return 0; 1082 } 1083 1084 static int cb_pcidas_ao_cancel(struct comedi_device *dev, 1085 struct comedi_subdevice *s) 1086 { 1087 struct cb_pcidas_private *devpriv = dev->private; 1088 unsigned long flags; 1089 1090 spin_lock_irqsave(&dev->spinlock, flags); 1091 /* disable interrupts */ 1092 devpriv->ctrl &= ~(PCIDAS_CTRL_DAHFIE | PCIDAS_CTRL_DAEMIE); 1093 outw(devpriv->ctrl, devpriv->pcibar1 + PCIDAS_CTRL_REG); 1094 1095 /* disable output */ 1096 devpriv->ao_ctrl &= ~(PCIDAS_AO_DACEN | PCIDAS_AO_PACER_MASK); 1097 outw(devpriv->ao_ctrl, devpriv->pcibar1 + PCIDAS_AO_REG); 1098 spin_unlock_irqrestore(&dev->spinlock, flags); 1099 1100 return 0; 1101 } 1102 1103 static unsigned int cb_pcidas_ao_interrupt(struct comedi_device *dev, 1104 unsigned int status) 1105 { 1106 const struct cb_pcidas_board *board = dev->board_ptr; 1107 struct cb_pcidas_private *devpriv = dev->private; 1108 struct comedi_subdevice *s = dev->write_subdev; 1109 struct comedi_async *async = s->async; 1110 struct comedi_cmd *cmd = &async->cmd; 1111 unsigned int irq_clr = 0; 1112 1113 if (status & PCIDAS_CTRL_DAEMI) { 1114 irq_clr |= PCIDAS_CTRL_DAEMI; 1115 1116 if (inw(devpriv->pcibar4 + PCIDAS_AO_REG) & PCIDAS_AO_EMPTY) { 1117 if (cmd->stop_src == TRIG_COUNT && 1118 async->scans_done >= cmd->stop_arg) { 1119 async->events |= COMEDI_CB_EOA; 1120 } else { 1121 dev_err(dev->class_dev, "dac fifo underflow\n"); 1122 async->events |= COMEDI_CB_ERROR; 1123 } 1124 } 1125 } else if (status & PCIDAS_CTRL_DAHFI) { 1126 irq_clr |= PCIDAS_CTRL_DAHFI; 1127 1128 cb_pcidas_ao_load_fifo(dev, s, board->fifo_size / 2); 1129 } 1130 1131 comedi_handle_events(dev, s); 1132 1133 return irq_clr; 1134 } 1135 1136 static unsigned int cb_pcidas_ai_interrupt(struct comedi_device *dev, 1137 unsigned int status) 1138 { 1139 const struct cb_pcidas_board *board = dev->board_ptr; 1140 struct cb_pcidas_private *devpriv = dev->private; 1141 struct comedi_subdevice *s = dev->read_subdev; 1142 struct comedi_async *async = s->async; 1143 struct comedi_cmd *cmd = &async->cmd; 1144 unsigned int irq_clr = 0; 1145 1146 if (status & PCIDAS_CTRL_ADHFI) { 1147 unsigned int num_samples; 1148 1149 irq_clr |= PCIDAS_CTRL_INT_CLR; 1150 1151 /* FIFO is half-full - read data */ 1152 num_samples = comedi_nsamples_left(s, board->fifo_size / 2); 1153 insw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG, 1154 devpriv->ai_buffer, num_samples); 1155 comedi_buf_write_samples(s, devpriv->ai_buffer, num_samples); 1156 1157 if (cmd->stop_src == TRIG_COUNT && 1158 async->scans_done >= cmd->stop_arg) 1159 async->events |= COMEDI_CB_EOA; 1160 } else if (status & (PCIDAS_CTRL_ADNEI | PCIDAS_CTRL_EOBI)) { 1161 unsigned int i; 1162 1163 irq_clr |= PCIDAS_CTRL_INT_CLR; 1164 1165 /* FIFO is not empty - read data until empty or timeoout */ 1166 for (i = 0; i < 10000; i++) { 1167 unsigned short val; 1168 1169 /* break if fifo is empty */ 1170 if ((inw(devpriv->pcibar1 + PCIDAS_CTRL_REG) & 1171 PCIDAS_CTRL_ADNE) == 0) 1172 break; 1173 val = inw(devpriv->pcibar2 + PCIDAS_AI_DATA_REG); 1174 comedi_buf_write_samples(s, &val, 1); 1175 1176 if (cmd->stop_src == TRIG_COUNT && 1177 async->scans_done >= cmd->stop_arg) { 1178 async->events |= COMEDI_CB_EOA; 1179 break; 1180 } 1181 } 1182 } else if (status & PCIDAS_CTRL_EOAI) { 1183 irq_clr |= PCIDAS_CTRL_EOAI; 1184 1185 dev_err(dev->class_dev, 1186 "bug! encountered end of acquisition interrupt?\n"); 1187 } 1188 1189 /* check for fifo overflow */ 1190 if (status & PCIDAS_CTRL_LADFUL) { 1191 irq_clr |= PCIDAS_CTRL_LADFUL; 1192 1193 dev_err(dev->class_dev, "fifo overflow\n"); 1194 async->events |= COMEDI_CB_ERROR; 1195 } 1196 1197 comedi_handle_events(dev, s); 1198 1199 return irq_clr; 1200 } 1201 1202 static irqreturn_t cb_pcidas_interrupt(int irq, void *d) 1203 { 1204 struct comedi_device *dev = d; 1205 struct cb_pcidas_private *devpriv = dev->private; 1206 unsigned int irq_clr = 0; 1207 unsigned int amcc_status; 1208 unsigned int status; 1209 1210 if (!dev->attached) 1211 return IRQ_NONE; 1212 1213 amcc_status = inl(devpriv->amcc + AMCC_OP_REG_INTCSR); 1214 1215 if ((INTCSR_INTR_ASSERTED & amcc_status) == 0) 1216 return IRQ_NONE; 1217 1218 /* make sure mailbox 4 is empty */ 1219 inl_p(devpriv->amcc + AMCC_OP_REG_IMB4); 1220 /* clear interrupt on amcc s5933 */ 1221 outl(devpriv->amcc_intcsr | INTCSR_INBOX_INTR_STATUS, 1222 devpriv->amcc + AMCC_OP_REG_INTCSR); 1223 1224 status = inw(devpriv->pcibar1 + PCIDAS_CTRL_REG); 1225 1226 /* handle analog output interrupts */ 1227 if (status & PCIDAS_CTRL_AO_INT) 1228 irq_clr |= cb_pcidas_ao_interrupt(dev, status); 1229 1230 /* handle analog input interrupts */ 1231 if (status & PCIDAS_CTRL_AI_INT) 1232 irq_clr |= cb_pcidas_ai_interrupt(dev, status); 1233 1234 if (irq_clr) { 1235 unsigned long flags; 1236 1237 spin_lock_irqsave(&dev->spinlock, flags); 1238 outw(devpriv->ctrl | irq_clr, 1239 devpriv->pcibar1 + PCIDAS_CTRL_REG); 1240 spin_unlock_irqrestore(&dev->spinlock, flags); 1241 } 1242 1243 return IRQ_HANDLED; 1244 } 1245 1246 static int cb_pcidas_auto_attach(struct comedi_device *dev, 1247 unsigned long context) 1248 { 1249 struct pci_dev *pcidev = comedi_to_pci_dev(dev); 1250 const struct cb_pcidas_board *board = NULL; 1251 struct cb_pcidas_private *devpriv; 1252 struct comedi_subdevice *s; 1253 int i; 1254 int ret; 1255 1256 if (context < ARRAY_SIZE(cb_pcidas_boards)) 1257 board = &cb_pcidas_boards[context]; 1258 if (!board) 1259 return -ENODEV; 1260 dev->board_ptr = board; 1261 dev->board_name = board->name; 1262 1263 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1264 if (!devpriv) 1265 return -ENOMEM; 1266 1267 ret = comedi_pci_enable(dev); 1268 if (ret) 1269 return ret; 1270 1271 devpriv->amcc = pci_resource_start(pcidev, 0); 1272 devpriv->pcibar1 = pci_resource_start(pcidev, 1); 1273 devpriv->pcibar2 = pci_resource_start(pcidev, 2); 1274 dev->iobase = pci_resource_start(pcidev, 3); 1275 if (board->has_ao) 1276 devpriv->pcibar4 = pci_resource_start(pcidev, 4); 1277 1278 /* disable and clear interrupts on amcc s5933 */ 1279 outl(INTCSR_INBOX_INTR_STATUS, 1280 devpriv->amcc + AMCC_OP_REG_INTCSR); 1281 1282 ret = request_irq(pcidev->irq, cb_pcidas_interrupt, IRQF_SHARED, 1283 "cb_pcidas", dev); 1284 if (ret) { 1285 dev_dbg(dev->class_dev, "unable to allocate irq %d\n", 1286 pcidev->irq); 1287 return ret; 1288 } 1289 dev->irq = pcidev->irq; 1290 1291 dev->pacer = comedi_8254_io_alloc(dev->iobase + PCIDAS_AI_8254_BASE, 1292 I8254_OSC_BASE_10MHZ, I8254_IO8, 0); 1293 if (IS_ERR(dev->pacer)) 1294 return PTR_ERR(dev->pacer); 1295 1296 devpriv->ao_pacer = 1297 comedi_8254_io_alloc(dev->iobase + PCIDAS_AO_8254_BASE, 1298 I8254_OSC_BASE_10MHZ, I8254_IO8, 0); 1299 if (IS_ERR(devpriv->ao_pacer)) 1300 return PTR_ERR(devpriv->ao_pacer); 1301 1302 ret = comedi_alloc_subdevices(dev, 7); 1303 if (ret) 1304 return ret; 1305 1306 /* Analog Input subdevice */ 1307 s = &dev->subdevices[0]; 1308 s->type = COMEDI_SUBD_AI; 1309 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF; 1310 s->n_chan = 16; 1311 s->maxdata = board->is_16bit ? 0xffff : 0x0fff; 1312 s->range_table = board->use_alt_range ? &cb_pcidas_alt_ranges 1313 : &cb_pcidas_ranges; 1314 s->insn_read = cb_pcidas_ai_insn_read; 1315 s->insn_config = cb_pcidas_ai_insn_config; 1316 if (dev->irq) { 1317 dev->read_subdev = s; 1318 s->subdev_flags |= SDF_CMD_READ; 1319 s->len_chanlist = s->n_chan; 1320 s->do_cmd = cb_pcidas_ai_cmd; 1321 s->do_cmdtest = cb_pcidas_ai_cmdtest; 1322 s->cancel = cb_pcidas_ai_cancel; 1323 } 1324 1325 /* Analog Output subdevice */ 1326 s = &dev->subdevices[1]; 1327 if (board->has_ao) { 1328 s->type = COMEDI_SUBD_AO; 1329 s->subdev_flags = SDF_WRITABLE | SDF_GROUND; 1330 s->n_chan = 2; 1331 s->maxdata = board->is_16bit ? 0xffff : 0x0fff; 1332 s->range_table = &cb_pcidas_ao_ranges; 1333 s->insn_write = (board->has_ao_fifo) 1334 ? cb_pcidas_ao_fifo_insn_write 1335 : cb_pcidas_ao_nofifo_insn_write; 1336 1337 ret = comedi_alloc_subdev_readback(s); 1338 if (ret) 1339 return ret; 1340 1341 if (dev->irq && board->has_ao_fifo) { 1342 dev->write_subdev = s; 1343 s->subdev_flags |= SDF_CMD_WRITE; 1344 s->len_chanlist = s->n_chan; 1345 s->do_cmdtest = cb_pcidas_ao_cmdtest; 1346 s->do_cmd = cb_pcidas_ao_cmd; 1347 s->cancel = cb_pcidas_ao_cancel; 1348 } 1349 } else { 1350 s->type = COMEDI_SUBD_UNUSED; 1351 } 1352 1353 /* 8255 */ 1354 s = &dev->subdevices[2]; 1355 ret = subdev_8255_io_init(dev, s, PCIDAS_8255_BASE); 1356 if (ret) 1357 return ret; 1358 1359 /* Memory subdevice - serial EEPROM */ 1360 s = &dev->subdevices[3]; 1361 s->type = COMEDI_SUBD_MEMORY; 1362 s->subdev_flags = SDF_READABLE | SDF_INTERNAL; 1363 s->n_chan = 256; 1364 s->maxdata = 0xff; 1365 s->insn_read = cb_pcidas_eeprom_insn_read; 1366 1367 /* Calibration subdevice - 8800 caldac */ 1368 s = &dev->subdevices[4]; 1369 s->type = COMEDI_SUBD_CALIB; 1370 s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL; 1371 s->n_chan = 8; 1372 s->maxdata = 0xff; 1373 s->insn_write = cb_pcidas_caldac_insn_write; 1374 1375 ret = comedi_alloc_subdev_readback(s); 1376 if (ret) 1377 return ret; 1378 1379 for (i = 0; i < s->n_chan; i++) { 1380 unsigned int val = s->maxdata / 2; 1381 1382 /* write 11-bit channel/value to caldac */ 1383 cb_pcidas_calib_write(dev, (i << 8) | val, 11, false); 1384 s->readback[i] = val; 1385 } 1386 1387 /* Calibration subdevice - trim potentiometer */ 1388 s = &dev->subdevices[5]; 1389 s->type = COMEDI_SUBD_CALIB; 1390 s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL; 1391 if (board->has_ad8402) { 1392 /* 1393 * pci-das1602/16 have an AD8402 trimpot: 1394 * chan 0 : adc gain 1395 * chan 1 : adc postgain offset 1396 */ 1397 s->n_chan = 2; 1398 s->maxdata = 0xff; 1399 } else { 1400 /* all other boards have an AD7376 trimpot */ 1401 s->n_chan = 1; 1402 s->maxdata = 0x7f; 1403 } 1404 s->insn_write = cb_pcidas_trimpot_insn_write; 1405 1406 ret = comedi_alloc_subdev_readback(s); 1407 if (ret) 1408 return ret; 1409 1410 for (i = 0; i < s->n_chan; i++) { 1411 cb_pcidas_trimpot_write(dev, i, s->maxdata / 2); 1412 s->readback[i] = s->maxdata / 2; 1413 } 1414 1415 /* Calibration subdevice - pci-das1602/16 pregain offset (dac08) */ 1416 s = &dev->subdevices[6]; 1417 if (board->has_dac08) { 1418 s->type = COMEDI_SUBD_CALIB; 1419 s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL; 1420 s->n_chan = 1; 1421 s->maxdata = 0xff; 1422 s->insn_write = cb_pcidas_dac08_insn_write; 1423 1424 ret = comedi_alloc_subdev_readback(s); 1425 if (ret) 1426 return ret; 1427 1428 for (i = 0; i < s->n_chan; i++) { 1429 cb_pcidas_dac08_write(dev, s->maxdata / 2); 1430 s->readback[i] = s->maxdata / 2; 1431 } 1432 } else { 1433 s->type = COMEDI_SUBD_UNUSED; 1434 } 1435 1436 /* make sure mailbox 4 is empty */ 1437 inl(devpriv->amcc + AMCC_OP_REG_IMB4); 1438 /* Set bits to enable incoming mailbox interrupts on amcc s5933. */ 1439 devpriv->amcc_intcsr = INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) | 1440 INTCSR_INBOX_FULL_INT; 1441 /* clear and enable interrupt on amcc s5933 */ 1442 outl(devpriv->amcc_intcsr | INTCSR_INBOX_INTR_STATUS, 1443 devpriv->amcc + AMCC_OP_REG_INTCSR); 1444 1445 return 0; 1446 } 1447 1448 static void cb_pcidas_detach(struct comedi_device *dev) 1449 { 1450 struct cb_pcidas_private *devpriv = dev->private; 1451 1452 if (devpriv) { 1453 if (devpriv->amcc) 1454 outl(INTCSR_INBOX_INTR_STATUS, 1455 devpriv->amcc + AMCC_OP_REG_INTCSR); 1456 if (!IS_ERR(devpriv->ao_pacer)) 1457 kfree(devpriv->ao_pacer); 1458 } 1459 comedi_pci_detach(dev); 1460 } 1461 1462 static struct comedi_driver cb_pcidas_driver = { 1463 .driver_name = "cb_pcidas", 1464 .module = THIS_MODULE, 1465 .auto_attach = cb_pcidas_auto_attach, 1466 .detach = cb_pcidas_detach, 1467 }; 1468 1469 static int cb_pcidas_pci_probe(struct pci_dev *dev, 1470 const struct pci_device_id *id) 1471 { 1472 return comedi_pci_auto_config(dev, &cb_pcidas_driver, 1473 id->driver_data); 1474 } 1475 1476 static const struct pci_device_id cb_pcidas_pci_table[] = { 1477 { PCI_VDEVICE(CB, 0x0001), .driver_data = BOARD_PCIDAS1602_16 }, 1478 { PCI_VDEVICE(CB, 0x000f), .driver_data = BOARD_PCIDAS1200 }, 1479 { PCI_VDEVICE(CB, 0x0010), .driver_data = BOARD_PCIDAS1602_12 }, 1480 { PCI_VDEVICE(CB, 0x0019), .driver_data = BOARD_PCIDAS1200_JR }, 1481 { PCI_VDEVICE(CB, 0x001c), .driver_data = BOARD_PCIDAS1602_16_JR }, 1482 { PCI_VDEVICE(CB, 0x004c), .driver_data = BOARD_PCIDAS1000 }, 1483 { PCI_VDEVICE(CB, 0x001a), .driver_data = BOARD_PCIDAS1001 }, 1484 { PCI_VDEVICE(CB, 0x001b), .driver_data = BOARD_PCIDAS1002 }, 1485 { } 1486 }; 1487 MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table); 1488 1489 static struct pci_driver cb_pcidas_pci_driver = { 1490 .name = "cb_pcidas", 1491 .id_table = cb_pcidas_pci_table, 1492 .probe = cb_pcidas_pci_probe, 1493 .remove = comedi_pci_auto_unconfig, 1494 }; 1495 module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver); 1496 1497 MODULE_AUTHOR("Comedi https://www.comedi.org"); 1498 MODULE_DESCRIPTION("Comedi driver for MeasurementComputing PCI-DAS series"); 1499 MODULE_LICENSE("GPL"); 1500