1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * comedi/drivers/ni_labpc_common.c 4 * 5 * Common support code for "ni_labpc", "ni_labpc_pci" and "ni_labpc_cs". 6 * 7 * Copyright (C) 2001-2003 Frank Mori Hess <fmhess@users.sourceforge.net> 8 */ 9 10#include <linux/module.h> 11#include <linux/interrupt.h> 12#include <linux/io.h> 13#include <linux/delay.h> 14#include <linux/slab.h> 15#include <linux/comedi/comedidev.h> 16#include <linux/comedi/comedi_8255.h> 17#include <linux/comedi/comedi_8254.h> 18 19#include "ni_labpc.h" 20#include "ni_labpc_regs.h" 21#include "ni_labpc_isadma.h" 22 23enum scan_mode { 24 MODE_SINGLE_CHAN, 25 MODE_SINGLE_CHAN_INTERVAL, 26 MODE_MULT_CHAN_UP, 27 MODE_MULT_CHAN_DOWN, 28}; 29 30static const struct comedi_lrange range_labpc_plus_ai = { 31 16, { 32 BIP_RANGE(5), 33 BIP_RANGE(4), 34 BIP_RANGE(2.5), 35 BIP_RANGE(1), 36 BIP_RANGE(0.5), 37 BIP_RANGE(0.25), 38 BIP_RANGE(0.1), 39 BIP_RANGE(0.05), 40 UNI_RANGE(10), 41 UNI_RANGE(8), 42 UNI_RANGE(5), 43 UNI_RANGE(2), 44 UNI_RANGE(1), 45 UNI_RANGE(0.5), 46 UNI_RANGE(0.2), 47 UNI_RANGE(0.1) 48 } 49}; 50 51static const struct comedi_lrange range_labpc_1200_ai = { 52 14, { 53 BIP_RANGE(5), 54 BIP_RANGE(2.5), 55 BIP_RANGE(1), 56 BIP_RANGE(0.5), 57 BIP_RANGE(0.25), 58 BIP_RANGE(0.1), 59 BIP_RANGE(0.05), 60 UNI_RANGE(10), 61 UNI_RANGE(5), 62 UNI_RANGE(2), 63 UNI_RANGE(1), 64 UNI_RANGE(0.5), 65 UNI_RANGE(0.2), 66 UNI_RANGE(0.1) 67 } 68}; 69 70static const struct comedi_lrange range_labpc_ao = { 71 2, { 72 BIP_RANGE(5), 73 UNI_RANGE(10) 74 } 75}; 76 77/* 78 * functions that do inb/outb and readb/writeb so we can use 79 * function pointers to decide which to use 80 */ 81 82#ifdef CONFIG_HAS_IOPORT 83 84static unsigned int labpc_inb(struct comedi_device *dev, unsigned long reg) 85{ 86 return inb(dev->iobase + reg); 87} 88 89static void labpc_outb(struct comedi_device *dev, 90 unsigned int byte, unsigned long reg) 91{ 92 outb(byte, dev->iobase + reg); 93} 94 95#endif /* CONFIG_HAS_IOPORT */ 96 97static unsigned int labpc_readb(struct comedi_device *dev, unsigned long reg) 98{ 99 return readb(dev->mmio + reg); 100} 101 102static void labpc_writeb(struct comedi_device *dev, 103 unsigned int byte, unsigned long reg) 104{ 105 writeb(byte, dev->mmio + reg); 106} 107 108static int labpc_cancel(struct comedi_device *dev, struct comedi_subdevice *s) 109{ 110 struct labpc_private *devpriv = dev->private; 111 unsigned long flags; 112 113 spin_lock_irqsave(&dev->spinlock, flags); 114 devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG); 115 devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG); 116 spin_unlock_irqrestore(&dev->spinlock, flags); 117 118 devpriv->cmd3 = 0; 119 devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG); 120 121 return 0; 122} 123 124static void labpc_ai_set_chan_and_gain(struct comedi_device *dev, 125 enum scan_mode mode, 126 unsigned int chan, 127 unsigned int range, 128 unsigned int aref) 129{ 130 const struct labpc_boardinfo *board = dev->board_ptr; 131 struct labpc_private *devpriv = dev->private; 132 133 if (board->is_labpc1200) { 134 /* 135 * The LabPC-1200 boards do not have a gain 136 * of '0x10'. Skip the range values that would 137 * result in this gain. 138 */ 139 range += (range > 0) + (range > 7); 140 } 141 142 /* munge channel bits for differential/scan disabled mode */ 143 if ((mode == MODE_SINGLE_CHAN || mode == MODE_SINGLE_CHAN_INTERVAL) && 144 aref == AREF_DIFF) 145 chan *= 2; 146 devpriv->cmd1 = CMD1_MA(chan); 147 devpriv->cmd1 |= CMD1_GAIN(range); 148 149 devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG); 150} 151 152static void labpc_setup_cmd6_reg(struct comedi_device *dev, 153 struct comedi_subdevice *s, 154 enum scan_mode mode, 155 enum transfer_type xfer, 156 unsigned int range, 157 unsigned int aref, 158 bool ena_intr) 159{ 160 const struct labpc_boardinfo *board = dev->board_ptr; 161 struct labpc_private *devpriv = dev->private; 162 163 if (!board->is_labpc1200) 164 return; 165 166 /* reference inputs to ground or common? */ 167 if (aref != AREF_GROUND) 168 devpriv->cmd6 |= CMD6_NRSE; 169 else 170 devpriv->cmd6 &= ~CMD6_NRSE; 171 172 /* bipolar or unipolar range? */ 173 if (comedi_range_is_unipolar(s, range)) 174 devpriv->cmd6 |= CMD6_ADCUNI; 175 else 176 devpriv->cmd6 &= ~CMD6_ADCUNI; 177 178 /* interrupt on fifo half full? */ 179 if (xfer == fifo_half_full_transfer) 180 devpriv->cmd6 |= CMD6_HFINTEN; 181 else 182 devpriv->cmd6 &= ~CMD6_HFINTEN; 183 184 /* enable interrupt on counter a1 terminal count? */ 185 if (ena_intr) 186 devpriv->cmd6 |= CMD6_DQINTEN; 187 else 188 devpriv->cmd6 &= ~CMD6_DQINTEN; 189 190 /* are we scanning up or down through channels? */ 191 if (mode == MODE_MULT_CHAN_UP) 192 devpriv->cmd6 |= CMD6_SCANUP; 193 else 194 devpriv->cmd6 &= ~CMD6_SCANUP; 195 196 devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG); 197} 198 199static unsigned int labpc_read_adc_fifo(struct comedi_device *dev) 200{ 201 struct labpc_private *devpriv = dev->private; 202 unsigned int lsb = devpriv->read_byte(dev, ADC_FIFO_REG); 203 unsigned int msb = devpriv->read_byte(dev, ADC_FIFO_REG); 204 205 return (msb << 8) | lsb; 206} 207 208static void labpc_clear_adc_fifo(struct comedi_device *dev) 209{ 210 struct labpc_private *devpriv = dev->private; 211 212 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG); 213 labpc_read_adc_fifo(dev); 214} 215 216static int labpc_ai_eoc(struct comedi_device *dev, 217 struct comedi_subdevice *s, 218 struct comedi_insn *insn, 219 unsigned long context) 220{ 221 struct labpc_private *devpriv = dev->private; 222 223 devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG); 224 if (devpriv->stat1 & STAT1_DAVAIL) 225 return 0; 226 return -EBUSY; 227} 228 229static int labpc_ai_insn_read(struct comedi_device *dev, 230 struct comedi_subdevice *s, 231 struct comedi_insn *insn, 232 unsigned int *data) 233{ 234 struct labpc_private *devpriv = dev->private; 235 unsigned int chan = CR_CHAN(insn->chanspec); 236 unsigned int range = CR_RANGE(insn->chanspec); 237 unsigned int aref = CR_AREF(insn->chanspec); 238 int ret; 239 int i; 240 241 /* disable timed conversions, interrupt generation and dma */ 242 labpc_cancel(dev, s); 243 244 labpc_ai_set_chan_and_gain(dev, MODE_SINGLE_CHAN, chan, range, aref); 245 246 labpc_setup_cmd6_reg(dev, s, MODE_SINGLE_CHAN, fifo_not_empty_transfer, 247 range, aref, false); 248 249 /* setup cmd4 register */ 250 devpriv->cmd4 = 0; 251 devpriv->cmd4 |= CMD4_ECLKRCV; 252 /* single-ended/differential */ 253 if (aref == AREF_DIFF) 254 devpriv->cmd4 |= CMD4_SEDIFF; 255 devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG); 256 257 /* initialize pacer counter to prevent any problems */ 258 comedi_8254_set_mode(devpriv->counter, 0, I8254_MODE2 | I8254_BINARY); 259 260 labpc_clear_adc_fifo(dev); 261 262 for (i = 0; i < insn->n; i++) { 263 /* trigger conversion */ 264 devpriv->write_byte(dev, 0x1, ADC_START_CONVERT_REG); 265 266 ret = comedi_timeout(dev, s, insn, labpc_ai_eoc, 0); 267 if (ret) 268 return ret; 269 270 data[i] = labpc_read_adc_fifo(dev); 271 } 272 273 return insn->n; 274} 275 276static bool labpc_use_continuous_mode(const struct comedi_cmd *cmd, 277 enum scan_mode mode) 278{ 279 if (mode == MODE_SINGLE_CHAN || cmd->scan_begin_src == TRIG_FOLLOW) 280 return true; 281 282 return false; 283} 284 285static unsigned int labpc_ai_convert_period(const struct comedi_cmd *cmd, 286 enum scan_mode mode) 287{ 288 if (cmd->convert_src != TRIG_TIMER) 289 return 0; 290 291 if (mode == MODE_SINGLE_CHAN && cmd->scan_begin_src == TRIG_TIMER) 292 return cmd->scan_begin_arg; 293 294 return cmd->convert_arg; 295} 296 297static void labpc_set_ai_convert_period(struct comedi_cmd *cmd, 298 enum scan_mode mode, unsigned int ns) 299{ 300 if (cmd->convert_src != TRIG_TIMER) 301 return; 302 303 if (mode == MODE_SINGLE_CHAN && 304 cmd->scan_begin_src == TRIG_TIMER) { 305 cmd->scan_begin_arg = ns; 306 if (cmd->convert_arg > cmd->scan_begin_arg) 307 cmd->convert_arg = cmd->scan_begin_arg; 308 } else { 309 cmd->convert_arg = ns; 310 } 311} 312 313static unsigned int labpc_ai_scan_period(const struct comedi_cmd *cmd, 314 enum scan_mode mode) 315{ 316 if (cmd->scan_begin_src != TRIG_TIMER) 317 return 0; 318 319 if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER) 320 return 0; 321 322 return cmd->scan_begin_arg; 323} 324 325static void labpc_set_ai_scan_period(struct comedi_cmd *cmd, 326 enum scan_mode mode, unsigned int ns) 327{ 328 if (cmd->scan_begin_src != TRIG_TIMER) 329 return; 330 331 if (mode == MODE_SINGLE_CHAN && cmd->convert_src == TRIG_TIMER) 332 return; 333 334 cmd->scan_begin_arg = ns; 335} 336 337/* figures out what counter values to use based on command */ 338static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd, 339 enum scan_mode mode) 340{ 341 struct comedi_8254 *pacer = dev->pacer; 342 unsigned int convert_period = labpc_ai_convert_period(cmd, mode); 343 unsigned int scan_period = labpc_ai_scan_period(cmd, mode); 344 unsigned int base_period; 345 346 /* 347 * If both convert and scan triggers are TRIG_TIMER, then they 348 * both rely on counter b0. If only one TRIG_TIMER is used, we 349 * can use the generic cascaded timing functions. 350 */ 351 if (convert_period && scan_period) { 352 /* 353 * pick the lowest divisor value we can (for maximum input 354 * clock speed on convert and scan counters) 355 */ 356 pacer->next_div1 = (scan_period - 1) / 357 (pacer->osc_base * I8254_MAX_COUNT) + 1; 358 359 comedi_check_trigger_arg_min(&pacer->next_div1, 2); 360 comedi_check_trigger_arg_max(&pacer->next_div1, 361 I8254_MAX_COUNT); 362 363 base_period = pacer->osc_base * pacer->next_div1; 364 365 /* set a0 for conversion frequency and b1 for scan frequency */ 366 switch (cmd->flags & CMDF_ROUND_MASK) { 367 default: 368 case CMDF_ROUND_NEAREST: 369 pacer->next_div = DIV_ROUND_CLOSEST(convert_period, 370 base_period); 371 pacer->next_div2 = DIV_ROUND_CLOSEST(scan_period, 372 base_period); 373 break; 374 case CMDF_ROUND_UP: 375 pacer->next_div = DIV_ROUND_UP(convert_period, 376 base_period); 377 pacer->next_div2 = DIV_ROUND_UP(scan_period, 378 base_period); 379 break; 380 case CMDF_ROUND_DOWN: 381 pacer->next_div = convert_period / base_period; 382 pacer->next_div2 = scan_period / base_period; 383 break; 384 } 385 /* make sure a0 and b1 values are acceptable */ 386 comedi_check_trigger_arg_min(&pacer->next_div, 2); 387 comedi_check_trigger_arg_max(&pacer->next_div, I8254_MAX_COUNT); 388 comedi_check_trigger_arg_min(&pacer->next_div2, 2); 389 comedi_check_trigger_arg_max(&pacer->next_div2, 390 I8254_MAX_COUNT); 391 392 /* write corrected timings to command */ 393 labpc_set_ai_convert_period(cmd, mode, 394 base_period * pacer->next_div); 395 labpc_set_ai_scan_period(cmd, mode, 396 base_period * pacer->next_div2); 397 } else if (scan_period) { 398 /* 399 * calculate cascaded counter values 400 * that give desired scan timing 401 * (pacer->next_div2 / pacer->next_div1) 402 */ 403 comedi_8254_cascade_ns_to_timer(pacer, &scan_period, 404 cmd->flags); 405 labpc_set_ai_scan_period(cmd, mode, scan_period); 406 } else if (convert_period) { 407 /* 408 * calculate cascaded counter values 409 * that give desired conversion timing 410 * (pacer->next_div / pacer->next_div1) 411 */ 412 comedi_8254_cascade_ns_to_timer(pacer, &convert_period, 413 cmd->flags); 414 /* transfer div2 value so correct timer gets updated */ 415 pacer->next_div = pacer->next_div2; 416 labpc_set_ai_convert_period(cmd, mode, convert_period); 417 } 418} 419 420static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd *cmd) 421{ 422 unsigned int chan0; 423 unsigned int chan1; 424 425 if (cmd->chanlist_len == 1) 426 return MODE_SINGLE_CHAN; 427 428 /* chanlist may be NULL during cmdtest */ 429 if (!cmd->chanlist) 430 return MODE_MULT_CHAN_UP; 431 432 chan0 = CR_CHAN(cmd->chanlist[0]); 433 chan1 = CR_CHAN(cmd->chanlist[1]); 434 435 if (chan0 < chan1) 436 return MODE_MULT_CHAN_UP; 437 438 if (chan0 > chan1) 439 return MODE_MULT_CHAN_DOWN; 440 441 return MODE_SINGLE_CHAN_INTERVAL; 442} 443 444static int labpc_ai_check_chanlist(struct comedi_device *dev, 445 struct comedi_subdevice *s, 446 struct comedi_cmd *cmd) 447{ 448 enum scan_mode mode = labpc_ai_scan_mode(cmd); 449 unsigned int chan0 = CR_CHAN(cmd->chanlist[0]); 450 unsigned int range0 = CR_RANGE(cmd->chanlist[0]); 451 unsigned int aref0 = CR_AREF(cmd->chanlist[0]); 452 int i; 453 454 for (i = 0; i < cmd->chanlist_len; i++) { 455 unsigned int chan = CR_CHAN(cmd->chanlist[i]); 456 unsigned int range = CR_RANGE(cmd->chanlist[i]); 457 unsigned int aref = CR_AREF(cmd->chanlist[i]); 458 459 switch (mode) { 460 case MODE_SINGLE_CHAN: 461 break; 462 case MODE_SINGLE_CHAN_INTERVAL: 463 if (chan != chan0) { 464 dev_dbg(dev->class_dev, 465 "channel scanning order specified in chanlist is not supported by hardware\n"); 466 return -EINVAL; 467 } 468 break; 469 case MODE_MULT_CHAN_UP: 470 if (chan != i) { 471 dev_dbg(dev->class_dev, 472 "channel scanning order specified in chanlist is not supported by hardware\n"); 473 return -EINVAL; 474 } 475 break; 476 case MODE_MULT_CHAN_DOWN: 477 if (chan != (cmd->chanlist_len - i - 1)) { 478 dev_dbg(dev->class_dev, 479 "channel scanning order specified in chanlist is not supported by hardware\n"); 480 return -EINVAL; 481 } 482 break; 483 } 484 485 if (range != range0) { 486 dev_dbg(dev->class_dev, 487 "entries in chanlist must all have the same range\n"); 488 return -EINVAL; 489 } 490 491 if (aref != aref0) { 492 dev_dbg(dev->class_dev, 493 "entries in chanlist must all have the same reference\n"); 494 return -EINVAL; 495 } 496 } 497 498 return 0; 499} 500 501static int labpc_ai_cmdtest(struct comedi_device *dev, 502 struct comedi_subdevice *s, struct comedi_cmd *cmd) 503{ 504 const struct labpc_boardinfo *board = dev->board_ptr; 505 int err = 0; 506 int tmp, tmp2; 507 unsigned int stop_mask; 508 enum scan_mode mode; 509 510 /* Step 1 : check if triggers are trivially valid */ 511 512 err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT); 513 err |= comedi_check_trigger_src(&cmd->scan_begin_src, 514 TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT); 515 err |= comedi_check_trigger_src(&cmd->convert_src, 516 TRIG_TIMER | TRIG_EXT); 517 err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT); 518 519 stop_mask = TRIG_COUNT | TRIG_NONE; 520 if (board->is_labpc1200) 521 stop_mask |= TRIG_EXT; 522 err |= comedi_check_trigger_src(&cmd->stop_src, stop_mask); 523 524 if (err) 525 return 1; 526 527 /* Step 2a : make sure trigger sources are unique */ 528 529 err |= comedi_check_trigger_is_unique(cmd->start_src); 530 err |= comedi_check_trigger_is_unique(cmd->scan_begin_src); 531 err |= comedi_check_trigger_is_unique(cmd->convert_src); 532 err |= comedi_check_trigger_is_unique(cmd->stop_src); 533 534 /* Step 2b : and mutually compatible */ 535 536 /* can't have external stop and start triggers at once */ 537 if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT) 538 err++; 539 540 if (err) 541 return 2; 542 543 /* Step 3: check if arguments are trivially valid */ 544 545 switch (cmd->start_src) { 546 case TRIG_NOW: 547 err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0); 548 break; 549 case TRIG_EXT: 550 /* start_arg value is ignored */ 551 break; 552 } 553 554 if (!cmd->chanlist_len) 555 err |= -EINVAL; 556 err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg, 557 cmd->chanlist_len); 558 559 if (cmd->convert_src == TRIG_TIMER) { 560 err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 561 board->ai_speed); 562 } 563 564 /* make sure scan timing is not too fast */ 565 if (cmd->scan_begin_src == TRIG_TIMER) { 566 if (cmd->convert_src == TRIG_TIMER) { 567 err |= comedi_check_trigger_arg_min( 568 &cmd->scan_begin_arg, 569 cmd->convert_arg * cmd->chanlist_len); 570 } 571 err |= comedi_check_trigger_arg_min( 572 &cmd->scan_begin_arg, 573 board->ai_speed * cmd->chanlist_len); 574 } 575 576 switch (cmd->stop_src) { 577 case TRIG_COUNT: 578 err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1); 579 break; 580 case TRIG_NONE: 581 err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0); 582 break; 583 /* 584 * TRIG_EXT doesn't care since it doesn't 585 * trigger off a numbered channel 586 */ 587 default: 588 break; 589 } 590 591 if (err) 592 return 3; 593 594 /* step 4: fix up any arguments */ 595 596 tmp = cmd->convert_arg; 597 tmp2 = cmd->scan_begin_arg; 598 mode = labpc_ai_scan_mode(cmd); 599 labpc_adc_timing(dev, cmd, mode); 600 if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg) 601 err++; 602 603 if (err) 604 return 4; 605 606 /* Step 5: check channel list if it exists */ 607 if (cmd->chanlist && cmd->chanlist_len > 0) 608 err |= labpc_ai_check_chanlist(dev, s, cmd); 609 610 if (err) 611 return 5; 612 613 return 0; 614} 615 616static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) 617{ 618 const struct labpc_boardinfo *board = dev->board_ptr; 619 struct labpc_private *devpriv = dev->private; 620 struct comedi_async *async = s->async; 621 struct comedi_cmd *cmd = &async->cmd; 622 enum scan_mode mode = labpc_ai_scan_mode(cmd); 623 unsigned int chanspec = (mode == MODE_MULT_CHAN_UP) ? 624 cmd->chanlist[cmd->chanlist_len - 1] : 625 cmd->chanlist[0]; 626 unsigned int chan = CR_CHAN(chanspec); 627 unsigned int range = CR_RANGE(chanspec); 628 unsigned int aref = CR_AREF(chanspec); 629 enum transfer_type xfer; 630 unsigned long flags; 631 632 /* make sure board is disabled before setting up acquisition */ 633 labpc_cancel(dev, s); 634 635 /* initialize software conversion count */ 636 if (cmd->stop_src == TRIG_COUNT) 637 devpriv->count = cmd->stop_arg * cmd->chanlist_len; 638 639 /* setup hardware conversion counter */ 640 if (cmd->stop_src == TRIG_EXT) { 641 /* 642 * load counter a1 with count of 3 643 * (pc+ manual says this is minimum allowed) using mode 0 644 */ 645 comedi_8254_load(devpriv->counter, 1, 646 3, I8254_MODE0 | I8254_BINARY); 647 } else { 648 /* just put counter a1 in mode 0 to set its output low */ 649 comedi_8254_set_mode(devpriv->counter, 1, 650 I8254_MODE0 | I8254_BINARY); 651 } 652 653 /* figure out what method we will use to transfer data */ 654 if (devpriv->dma && 655 (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0) { 656 /* 657 * dma unsafe at RT priority, 658 * and too much setup time for CMDF_WAKE_EOS 659 */ 660 xfer = isa_dma_transfer; 661 } else if (board->is_labpc1200 && 662 (cmd->flags & CMDF_WAKE_EOS) == 0 && 663 (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) { 664 /* 665 * pc-plus has no fifo-half full interrupt 666 * wake-end-of-scan should interrupt on fifo not empty 667 * make sure we are taking more than just a few points 668 */ 669 xfer = fifo_half_full_transfer; 670 } else { 671 xfer = fifo_not_empty_transfer; 672 } 673 devpriv->current_transfer = xfer; 674 675 labpc_ai_set_chan_and_gain(dev, mode, chan, range, aref); 676 677 labpc_setup_cmd6_reg(dev, s, mode, xfer, range, aref, 678 (cmd->stop_src == TRIG_EXT)); 679 680 /* manual says to set scan enable bit on second pass */ 681 if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) { 682 devpriv->cmd1 |= CMD1_SCANEN; 683 /* 684 * Need a brief delay before enabling scan, or scan 685 * list will get screwed when you switch between 686 * scan up to scan down mode - dunno why. 687 */ 688 udelay(1); 689 devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG); 690 } 691 692 devpriv->write_byte(dev, cmd->chanlist_len, INTERVAL_COUNT_REG); 693 /* load count */ 694 devpriv->write_byte(dev, 0x1, INTERVAL_STROBE_REG); 695 696 if (cmd->convert_src == TRIG_TIMER || 697 cmd->scan_begin_src == TRIG_TIMER) { 698 struct comedi_8254 *pacer = dev->pacer; 699 struct comedi_8254 *counter = devpriv->counter; 700 701 comedi_8254_update_divisors(pacer); 702 703 /* set up pacing */ 704 comedi_8254_load(pacer, 0, pacer->divisor1, 705 I8254_MODE3 | I8254_BINARY); 706 707 /* set up conversion pacing */ 708 comedi_8254_set_mode(counter, 0, I8254_MODE2 | I8254_BINARY); 709 if (labpc_ai_convert_period(cmd, mode)) 710 comedi_8254_write(counter, 0, pacer->divisor); 711 712 /* set up scan pacing */ 713 if (labpc_ai_scan_period(cmd, mode)) 714 comedi_8254_load(pacer, 1, pacer->divisor2, 715 I8254_MODE2 | I8254_BINARY); 716 } 717 718 labpc_clear_adc_fifo(dev); 719 720 if (xfer == isa_dma_transfer) 721 labpc_setup_dma(dev, s); 722 723 /* enable error interrupts */ 724 devpriv->cmd3 |= CMD3_ERRINTEN; 725 /* enable fifo not empty interrupt? */ 726 if (xfer == fifo_not_empty_transfer) 727 devpriv->cmd3 |= CMD3_FIFOINTEN; 728 devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG); 729 730 /* setup any external triggering/pacing (cmd4 register) */ 731 devpriv->cmd4 = 0; 732 if (cmd->convert_src != TRIG_EXT) 733 devpriv->cmd4 |= CMD4_ECLKRCV; 734 /* 735 * XXX should discard first scan when using interval scanning 736 * since manual says it is not synced with scan clock. 737 */ 738 if (!labpc_use_continuous_mode(cmd, mode)) { 739 devpriv->cmd4 |= CMD4_INTSCAN; 740 if (cmd->scan_begin_src == TRIG_EXT) 741 devpriv->cmd4 |= CMD4_EOIRCV; 742 } 743 /* single-ended/differential */ 744 if (aref == AREF_DIFF) 745 devpriv->cmd4 |= CMD4_SEDIFF; 746 devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG); 747 748 /* startup acquisition */ 749 750 spin_lock_irqsave(&dev->spinlock, flags); 751 752 /* use 2 cascaded counters for pacing */ 753 devpriv->cmd2 |= CMD2_TBSEL; 754 755 devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG); 756 if (cmd->start_src == TRIG_EXT) 757 devpriv->cmd2 |= CMD2_HWTRIG; 758 else 759 devpriv->cmd2 |= CMD2_SWTRIG; 760 if (cmd->stop_src == TRIG_EXT) 761 devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG); 762 763 devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG); 764 765 spin_unlock_irqrestore(&dev->spinlock, flags); 766 767 return 0; 768} 769 770/* read all available samples from ai fifo */ 771static int labpc_drain_fifo(struct comedi_device *dev) 772{ 773 struct labpc_private *devpriv = dev->private; 774 struct comedi_async *async = dev->read_subdev->async; 775 struct comedi_cmd *cmd = &async->cmd; 776 unsigned short data; 777 const int timeout = 10000; 778 unsigned int i; 779 780 devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG); 781 782 for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout; 783 i++) { 784 /* quit if we have all the data we want */ 785 if (cmd->stop_src == TRIG_COUNT) { 786 if (devpriv->count == 0) 787 break; 788 devpriv->count--; 789 } 790 data = labpc_read_adc_fifo(dev); 791 comedi_buf_write_samples(dev->read_subdev, &data, 1); 792 devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG); 793 } 794 if (i == timeout) { 795 dev_err(dev->class_dev, "ai timeout, fifo never empties\n"); 796 async->events |= COMEDI_CB_ERROR; 797 return -1; 798 } 799 800 return 0; 801} 802 803/* 804 * Makes sure all data acquired by board is transferred to comedi (used 805 * when acquisition is terminated by stop_src == TRIG_EXT). 806 */ 807static void labpc_drain_dregs(struct comedi_device *dev) 808{ 809 struct labpc_private *devpriv = dev->private; 810 811 if (devpriv->current_transfer == isa_dma_transfer) 812 labpc_drain_dma(dev); 813 814 labpc_drain_fifo(dev); 815} 816 817/* interrupt service routine */ 818static irqreturn_t labpc_interrupt(int irq, void *d) 819{ 820 struct comedi_device *dev = d; 821 const struct labpc_boardinfo *board = dev->board_ptr; 822 struct labpc_private *devpriv = dev->private; 823 struct comedi_subdevice *s = dev->read_subdev; 824 struct comedi_async *async; 825 struct comedi_cmd *cmd; 826 827 if (!dev->attached) { 828 dev_err(dev->class_dev, "premature interrupt\n"); 829 return IRQ_HANDLED; 830 } 831 832 async = s->async; 833 cmd = &async->cmd; 834 835 /* read board status */ 836 devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG); 837 if (board->is_labpc1200) 838 devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG); 839 840 if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW | 841 STAT1_OVERRUN | STAT1_DAVAIL)) == 0 && 842 (devpriv->stat2 & STAT2_OUTA1) == 0 && 843 (devpriv->stat2 & STAT2_FIFONHF)) { 844 return IRQ_NONE; 845 } 846 847 if (devpriv->stat1 & STAT1_OVERRUN) { 848 /* clear error interrupt */ 849 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG); 850 async->events |= COMEDI_CB_ERROR; 851 comedi_handle_events(dev, s); 852 dev_err(dev->class_dev, "overrun\n"); 853 return IRQ_HANDLED; 854 } 855 856 if (devpriv->current_transfer == isa_dma_transfer) 857 labpc_handle_dma_status(dev); 858 else 859 labpc_drain_fifo(dev); 860 861 if (devpriv->stat1 & STAT1_CNTINT) { 862 dev_err(dev->class_dev, "handled timer interrupt?\n"); 863 /* clear it */ 864 devpriv->write_byte(dev, 0x1, TIMER_CLEAR_REG); 865 } 866 867 if (devpriv->stat1 & STAT1_OVERFLOW) { 868 /* clear error interrupt */ 869 devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG); 870 async->events |= COMEDI_CB_ERROR; 871 comedi_handle_events(dev, s); 872 dev_err(dev->class_dev, "overflow\n"); 873 return IRQ_HANDLED; 874 } 875 /* handle external stop trigger */ 876 if (cmd->stop_src == TRIG_EXT) { 877 if (devpriv->stat2 & STAT2_OUTA1) { 878 labpc_drain_dregs(dev); 879 async->events |= COMEDI_CB_EOA; 880 } 881 } 882 883 /* TRIG_COUNT end of acquisition */ 884 if (cmd->stop_src == TRIG_COUNT) { 885 if (devpriv->count == 0) 886 async->events |= COMEDI_CB_EOA; 887 } 888 889 comedi_handle_events(dev, s); 890 return IRQ_HANDLED; 891} 892 893static void labpc_ao_write(struct comedi_device *dev, 894 struct comedi_subdevice *s, 895 unsigned int chan, unsigned int val) 896{ 897 struct labpc_private *devpriv = dev->private; 898 899 devpriv->write_byte(dev, val & 0xff, DAC_LSB_REG(chan)); 900 devpriv->write_byte(dev, (val >> 8) & 0xff, DAC_MSB_REG(chan)); 901 902 s->readback[chan] = val; 903} 904 905static int labpc_ao_insn_write(struct comedi_device *dev, 906 struct comedi_subdevice *s, 907 struct comedi_insn *insn, 908 unsigned int *data) 909{ 910 const struct labpc_boardinfo *board = dev->board_ptr; 911 struct labpc_private *devpriv = dev->private; 912 unsigned int channel; 913 unsigned int range; 914 unsigned int i; 915 unsigned long flags; 916 917 channel = CR_CHAN(insn->chanspec); 918 919 /* 920 * Turn off pacing of analog output channel. 921 * NOTE: hardware bug in daqcard-1200 means pacing cannot 922 * be independently enabled/disabled for its the two channels. 923 */ 924 spin_lock_irqsave(&dev->spinlock, flags); 925 devpriv->cmd2 &= ~CMD2_LDAC(channel); 926 devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG); 927 spin_unlock_irqrestore(&dev->spinlock, flags); 928 929 /* set range */ 930 if (board->is_labpc1200) { 931 range = CR_RANGE(insn->chanspec); 932 if (comedi_range_is_unipolar(s, range)) 933 devpriv->cmd6 |= CMD6_DACUNI(channel); 934 else 935 devpriv->cmd6 &= ~CMD6_DACUNI(channel); 936 /* write to register */ 937 devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG); 938 } 939 /* send data */ 940 for (i = 0; i < insn->n; i++) 941 labpc_ao_write(dev, s, channel, data[i]); 942 943 return insn->n; 944} 945 946/* lowlevel write to eeprom/dac */ 947static void labpc_serial_out(struct comedi_device *dev, unsigned int value, 948 unsigned int value_width) 949{ 950 struct labpc_private *devpriv = dev->private; 951 int i; 952 953 for (i = 1; i <= value_width; i++) { 954 /* clear serial clock */ 955 devpriv->cmd5 &= ~CMD5_SCLK; 956 /* send bits most significant bit first */ 957 if (value & (1 << (value_width - i))) 958 devpriv->cmd5 |= CMD5_SDATA; 959 else 960 devpriv->cmd5 &= ~CMD5_SDATA; 961 udelay(1); 962 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 963 /* set clock to load bit */ 964 devpriv->cmd5 |= CMD5_SCLK; 965 udelay(1); 966 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 967 } 968} 969 970/* lowlevel read from eeprom */ 971static unsigned int labpc_serial_in(struct comedi_device *dev) 972{ 973 struct labpc_private *devpriv = dev->private; 974 unsigned int value = 0; 975 int i; 976 const int value_width = 8; /* number of bits wide values are */ 977 978 for (i = 1; i <= value_width; i++) { 979 /* set serial clock */ 980 devpriv->cmd5 |= CMD5_SCLK; 981 udelay(1); 982 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 983 /* clear clock bit */ 984 devpriv->cmd5 &= ~CMD5_SCLK; 985 udelay(1); 986 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 987 /* read bits most significant bit first */ 988 udelay(1); 989 devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG); 990 if (devpriv->stat2 & STAT2_PROMOUT) 991 value |= 1 << (value_width - i); 992 } 993 994 return value; 995} 996 997static unsigned int labpc_eeprom_read(struct comedi_device *dev, 998 unsigned int address) 999{ 1000 struct labpc_private *devpriv = dev->private; 1001 unsigned int value; 1002 /* bits to tell eeprom to expect a read */ 1003 const int read_instruction = 0x3; 1004 /* 8 bit write lengths to eeprom */ 1005 const int write_length = 8; 1006 1007 /* enable read/write to eeprom */ 1008 devpriv->cmd5 &= ~CMD5_EEPROMCS; 1009 udelay(1); 1010 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1011 devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT); 1012 udelay(1); 1013 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1014 1015 /* send read instruction */ 1016 labpc_serial_out(dev, read_instruction, write_length); 1017 /* send 8 bit address to read from */ 1018 labpc_serial_out(dev, address, write_length); 1019 /* read result */ 1020 value = labpc_serial_in(dev); 1021 1022 /* disable read/write to eeprom */ 1023 devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT); 1024 udelay(1); 1025 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1026 1027 return value; 1028} 1029 1030static unsigned int labpc_eeprom_read_status(struct comedi_device *dev) 1031{ 1032 struct labpc_private *devpriv = dev->private; 1033 unsigned int value; 1034 const int read_status_instruction = 0x5; 1035 const int write_length = 8; /* 8 bit write lengths to eeprom */ 1036 1037 /* enable read/write to eeprom */ 1038 devpriv->cmd5 &= ~CMD5_EEPROMCS; 1039 udelay(1); 1040 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1041 devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT); 1042 udelay(1); 1043 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1044 1045 /* send read status instruction */ 1046 labpc_serial_out(dev, read_status_instruction, write_length); 1047 /* read result */ 1048 value = labpc_serial_in(dev); 1049 1050 /* disable read/write to eeprom */ 1051 devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT); 1052 udelay(1); 1053 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1054 1055 return value; 1056} 1057 1058static void labpc_eeprom_write(struct comedi_device *dev, 1059 unsigned int address, unsigned int value) 1060{ 1061 struct labpc_private *devpriv = dev->private; 1062 const int write_enable_instruction = 0x6; 1063 const int write_instruction = 0x2; 1064 const int write_length = 8; /* 8 bit write lengths to eeprom */ 1065 1066 /* enable read/write to eeprom */ 1067 devpriv->cmd5 &= ~CMD5_EEPROMCS; 1068 udelay(1); 1069 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1070 devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT); 1071 udelay(1); 1072 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1073 1074 /* send write_enable instruction */ 1075 labpc_serial_out(dev, write_enable_instruction, write_length); 1076 devpriv->cmd5 &= ~CMD5_EEPROMCS; 1077 udelay(1); 1078 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1079 1080 /* send write instruction */ 1081 devpriv->cmd5 |= CMD5_EEPROMCS; 1082 udelay(1); 1083 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1084 labpc_serial_out(dev, write_instruction, write_length); 1085 /* send 8 bit address to write to */ 1086 labpc_serial_out(dev, address, write_length); 1087 /* write value */ 1088 labpc_serial_out(dev, value, write_length); 1089 devpriv->cmd5 &= ~CMD5_EEPROMCS; 1090 udelay(1); 1091 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1092 1093 /* disable read/write to eeprom */ 1094 devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT); 1095 udelay(1); 1096 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1097} 1098 1099/* writes to 8 bit calibration dacs */ 1100static void write_caldac(struct comedi_device *dev, unsigned int channel, 1101 unsigned int value) 1102{ 1103 struct labpc_private *devpriv = dev->private; 1104 1105 /* clear caldac load bit and make sure we don't write to eeprom */ 1106 devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT); 1107 udelay(1); 1108 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1109 1110 /* write 4 bit channel */ 1111 labpc_serial_out(dev, channel, 4); 1112 /* write 8 bit caldac value */ 1113 labpc_serial_out(dev, value, 8); 1114 1115 /* set and clear caldac bit to load caldac value */ 1116 devpriv->cmd5 |= CMD5_CALDACLD; 1117 udelay(1); 1118 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1119 devpriv->cmd5 &= ~CMD5_CALDACLD; 1120 udelay(1); 1121 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1122} 1123 1124static int labpc_calib_insn_write(struct comedi_device *dev, 1125 struct comedi_subdevice *s, 1126 struct comedi_insn *insn, 1127 unsigned int *data) 1128{ 1129 unsigned int chan = CR_CHAN(insn->chanspec); 1130 1131 /* 1132 * Only write the last data value to the caldac. Preceding 1133 * data would be overwritten anyway. 1134 */ 1135 if (insn->n > 0) { 1136 unsigned int val = data[insn->n - 1]; 1137 1138 if (s->readback[chan] != val) { 1139 write_caldac(dev, chan, val); 1140 s->readback[chan] = val; 1141 } 1142 } 1143 1144 return insn->n; 1145} 1146 1147static int labpc_eeprom_ready(struct comedi_device *dev, 1148 struct comedi_subdevice *s, 1149 struct comedi_insn *insn, 1150 unsigned long context) 1151{ 1152 unsigned int status; 1153 1154 /* make sure there isn't already a write in progress */ 1155 status = labpc_eeprom_read_status(dev); 1156 if ((status & 0x1) == 0) 1157 return 0; 1158 return -EBUSY; 1159} 1160 1161static int labpc_eeprom_insn_write(struct comedi_device *dev, 1162 struct comedi_subdevice *s, 1163 struct comedi_insn *insn, 1164 unsigned int *data) 1165{ 1166 unsigned int chan = CR_CHAN(insn->chanspec); 1167 int ret; 1168 1169 /* only allow writes to user area of eeprom */ 1170 if (chan < 16 || chan > 127) 1171 return -EINVAL; 1172 1173 /* 1174 * Only write the last data value to the eeprom. Preceding 1175 * data would be overwritten anyway. 1176 */ 1177 if (insn->n > 0) { 1178 unsigned int val = data[insn->n - 1]; 1179 1180 ret = comedi_timeout(dev, s, insn, labpc_eeprom_ready, 0); 1181 if (ret) 1182 return ret; 1183 1184 labpc_eeprom_write(dev, chan, val); 1185 s->readback[chan] = val; 1186 } 1187 1188 return insn->n; 1189} 1190 1191int labpc_common_attach(struct comedi_device *dev, 1192 unsigned int irq, unsigned long isr_flags) 1193{ 1194 const struct labpc_boardinfo *board = dev->board_ptr; 1195 struct labpc_private *devpriv; 1196 struct comedi_subdevice *s; 1197 int ret; 1198 int i; 1199 1200 devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv)); 1201 if (!devpriv) 1202 return -ENOMEM; 1203 1204 if (dev->mmio) { 1205 devpriv->read_byte = labpc_readb; 1206 devpriv->write_byte = labpc_writeb; 1207 } else { 1208#ifdef CONFIG_HAS_IOPORT 1209 devpriv->read_byte = labpc_inb; 1210 devpriv->write_byte = labpc_outb; 1211#else 1212 return -ENXIO; 1213#endif 1214 } 1215 1216 /* initialize board's command registers */ 1217 devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG); 1218 devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG); 1219 devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG); 1220 devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG); 1221 if (board->is_labpc1200) { 1222 devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG); 1223 devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG); 1224 } 1225 1226 if (irq) { 1227 ret = request_irq(irq, labpc_interrupt, isr_flags, 1228 dev->board_name, dev); 1229 if (ret == 0) 1230 dev->irq = irq; 1231 } 1232 1233 if (dev->mmio) { 1234 dev->pacer = 1235 comedi_8254_mm_alloc(dev->mmio + COUNTER_B_BASE_REG, 1236 I8254_OSC_BASE_2MHZ, I8254_IO8, 0); 1237 devpriv->counter = 1238 comedi_8254_mm_alloc(dev->mmio + COUNTER_A_BASE_REG, 1239 I8254_OSC_BASE_2MHZ, I8254_IO8, 0); 1240 } else { 1241 dev->pacer = 1242 comedi_8254_io_alloc(dev->iobase + COUNTER_B_BASE_REG, 1243 I8254_OSC_BASE_2MHZ, I8254_IO8, 0); 1244 devpriv->counter = 1245 comedi_8254_io_alloc(dev->iobase + COUNTER_A_BASE_REG, 1246 I8254_OSC_BASE_2MHZ, I8254_IO8, 0); 1247 } 1248 if (IS_ERR(dev->pacer)) 1249 return PTR_ERR(dev->pacer); 1250 if (IS_ERR(devpriv->counter)) 1251 return PTR_ERR(devpriv->counter); 1252 1253 ret = comedi_alloc_subdevices(dev, 5); 1254 if (ret) 1255 return ret; 1256 1257 /* analog input subdevice */ 1258 s = &dev->subdevices[0]; 1259 s->type = COMEDI_SUBD_AI; 1260 s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF; 1261 s->n_chan = 8; 1262 s->len_chanlist = 8; 1263 s->maxdata = 0x0fff; 1264 s->range_table = board->is_labpc1200 ? 1265 &range_labpc_1200_ai : &range_labpc_plus_ai; 1266 s->insn_read = labpc_ai_insn_read; 1267 if (dev->irq) { 1268 dev->read_subdev = s; 1269 s->subdev_flags |= SDF_CMD_READ; 1270 s->do_cmd = labpc_ai_cmd; 1271 s->do_cmdtest = labpc_ai_cmdtest; 1272 s->cancel = labpc_cancel; 1273 } 1274 1275 /* analog output */ 1276 s = &dev->subdevices[1]; 1277 if (board->has_ao) { 1278 s->type = COMEDI_SUBD_AO; 1279 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND; 1280 s->n_chan = 2; 1281 s->maxdata = 0x0fff; 1282 s->range_table = &range_labpc_ao; 1283 s->insn_write = labpc_ao_insn_write; 1284 1285 ret = comedi_alloc_subdev_readback(s); 1286 if (ret) 1287 return ret; 1288 1289 /* initialize analog outputs to a known value */ 1290 for (i = 0; i < s->n_chan; i++) 1291 labpc_ao_write(dev, s, i, s->maxdata / 2); 1292 } else { 1293 s->type = COMEDI_SUBD_UNUSED; 1294 } 1295 1296 /* 8255 dio */ 1297 s = &dev->subdevices[2]; 1298 if (dev->mmio) 1299 ret = subdev_8255_mm_init(dev, s, DIO_BASE_REG); 1300 else 1301 ret = subdev_8255_io_init(dev, s, DIO_BASE_REG); 1302 if (ret) 1303 return ret; 1304 1305 /* calibration subdevices for boards that have one */ 1306 s = &dev->subdevices[3]; 1307 if (board->is_labpc1200) { 1308 s->type = COMEDI_SUBD_CALIB; 1309 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 1310 s->n_chan = 16; 1311 s->maxdata = 0xff; 1312 s->insn_write = labpc_calib_insn_write; 1313 1314 ret = comedi_alloc_subdev_readback(s); 1315 if (ret) 1316 return ret; 1317 1318 for (i = 0; i < s->n_chan; i++) { 1319 write_caldac(dev, i, s->maxdata / 2); 1320 s->readback[i] = s->maxdata / 2; 1321 } 1322 } else { 1323 s->type = COMEDI_SUBD_UNUSED; 1324 } 1325 1326 /* EEPROM (256 bytes) */ 1327 s = &dev->subdevices[4]; 1328 if (board->is_labpc1200) { 1329 s->type = COMEDI_SUBD_MEMORY; 1330 s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL; 1331 s->n_chan = 256; 1332 s->maxdata = 0xff; 1333 s->insn_write = labpc_eeprom_insn_write; 1334 1335 ret = comedi_alloc_subdev_readback(s); 1336 if (ret) 1337 return ret; 1338 1339 for (i = 0; i < s->n_chan; i++) 1340 s->readback[i] = labpc_eeprom_read(dev, i); 1341 } else { 1342 s->type = COMEDI_SUBD_UNUSED; 1343 } 1344 1345 return 0; 1346} 1347EXPORT_SYMBOL_GPL(labpc_common_attach); 1348 1349void labpc_common_detach(struct comedi_device *dev) 1350{ 1351 struct labpc_private *devpriv = dev->private; 1352 1353 if (devpriv) { 1354 if (!IS_ERR(devpriv->counter)) 1355 kfree(devpriv->counter); 1356 } 1357} 1358EXPORT_SYMBOL_GPL(labpc_common_detach); 1359 1360static int __init labpc_common_init(void) 1361{ 1362 return 0; 1363} 1364module_init(labpc_common_init); 1365 1366static void __exit labpc_common_exit(void) 1367{ 1368} 1369module_exit(labpc_common_exit); 1370 1371MODULE_AUTHOR("Comedi https://www.comedi.org"); 1372MODULE_DESCRIPTION("Comedi helper for ni_labpc, ni_labpc_pci, ni_labpc_cs"); 1373MODULE_LICENSE("GPL"); 1374