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