linux/drivers/staging/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(&cmd->
 564                                                            scan_begin_arg,
 565                                                            cmd->convert_arg *
 566                                                            cmd->chanlist_len);
 567                }
 568                err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
 569                                                    board->ai_speed *
 570                                                    cmd->chanlist_len);
 571        }
 572
 573        switch (cmd->stop_src) {
 574        case TRIG_COUNT:
 575                err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
 576                break;
 577        case TRIG_NONE:
 578                err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
 579                break;
 580                /*
 581                 * TRIG_EXT doesn't care since it doesn't
 582                 * trigger off a numbered channel
 583                 */
 584        default:
 585                break;
 586        }
 587
 588        if (err)
 589                return 3;
 590
 591        /* step 4: fix up any arguments */
 592
 593        tmp = cmd->convert_arg;
 594        tmp2 = cmd->scan_begin_arg;
 595        mode = labpc_ai_scan_mode(cmd);
 596        labpc_adc_timing(dev, cmd, mode);
 597        if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
 598                err++;
 599
 600        if (err)
 601                return 4;
 602
 603        /* Step 5: check channel list if it exists */
 604        if (cmd->chanlist && cmd->chanlist_len > 0)
 605                err |= labpc_ai_check_chanlist(dev, s, cmd);
 606
 607        if (err)
 608                return 5;
 609
 610        return 0;
 611}
 612
 613static int labpc_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 614{
 615        const struct labpc_boardinfo *board = dev->board_ptr;
 616        struct labpc_private *devpriv = dev->private;
 617        struct comedi_async *async = s->async;
 618        struct comedi_cmd *cmd = &async->cmd;
 619        enum scan_mode mode = labpc_ai_scan_mode(cmd);
 620        unsigned int chanspec = (mode == MODE_MULT_CHAN_UP) ?
 621                                cmd->chanlist[cmd->chanlist_len - 1] :
 622                                cmd->chanlist[0];
 623        unsigned int chan = CR_CHAN(chanspec);
 624        unsigned int range = CR_RANGE(chanspec);
 625        unsigned int aref = CR_AREF(chanspec);
 626        enum transfer_type xfer;
 627        unsigned long flags;
 628
 629        /* make sure board is disabled before setting up acquisition */
 630        labpc_cancel(dev, s);
 631
 632        /*  initialize software conversion count */
 633        if (cmd->stop_src == TRIG_COUNT)
 634                devpriv->count = cmd->stop_arg * cmd->chanlist_len;
 635
 636        /*  setup hardware conversion counter */
 637        if (cmd->stop_src == TRIG_EXT) {
 638                /*
 639                 * load counter a1 with count of 3
 640                 * (pc+ manual says this is minimum allowed) using mode 0
 641                 */
 642                comedi_8254_load(devpriv->counter, 1,
 643                                 3, I8254_MODE0 | I8254_BINARY);
 644        } else  {
 645                /* just put counter a1 in mode 0 to set its output low */
 646                comedi_8254_set_mode(devpriv->counter, 1,
 647                                     I8254_MODE0 | I8254_BINARY);
 648        }
 649
 650        /* figure out what method we will use to transfer data */
 651        if (devpriv->dma &&
 652            (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY)) == 0) {
 653                /*
 654                 * dma unsafe at RT priority,
 655                 * and too much setup time for CMDF_WAKE_EOS
 656                 */
 657                xfer = isa_dma_transfer;
 658        } else if (board->is_labpc1200 &&
 659                   (cmd->flags & CMDF_WAKE_EOS) == 0 &&
 660                   (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) {
 661                /*
 662                 * pc-plus has no fifo-half full interrupt
 663                 * wake-end-of-scan should interrupt on fifo not empty
 664                 * make sure we are taking more than just a few points
 665                 */
 666                xfer = fifo_half_full_transfer;
 667        } else {
 668                xfer = fifo_not_empty_transfer;
 669        }
 670        devpriv->current_transfer = xfer;
 671
 672        labpc_ai_set_chan_and_gain(dev, mode, chan, range, aref);
 673
 674        labpc_setup_cmd6_reg(dev, s, mode, xfer, range, aref,
 675                             (cmd->stop_src == TRIG_EXT));
 676
 677        /* manual says to set scan enable bit on second pass */
 678        if (mode == MODE_MULT_CHAN_UP || mode == MODE_MULT_CHAN_DOWN) {
 679                devpriv->cmd1 |= CMD1_SCANEN;
 680                /*
 681                 * Need a brief delay before enabling scan, or scan
 682                 * list will get screwed when you switch between
 683                 * scan up to scan down mode - dunno why.
 684                 */
 685                udelay(1);
 686                devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
 687        }
 688
 689        devpriv->write_byte(dev, cmd->chanlist_len, INTERVAL_COUNT_REG);
 690        /*  load count */
 691        devpriv->write_byte(dev, 0x1, INTERVAL_STROBE_REG);
 692
 693        if (cmd->convert_src == TRIG_TIMER ||
 694            cmd->scan_begin_src == TRIG_TIMER) {
 695                struct comedi_8254 *pacer = dev->pacer;
 696                struct comedi_8254 *counter = devpriv->counter;
 697
 698                comedi_8254_update_divisors(pacer);
 699
 700                /* set up pacing */
 701                comedi_8254_load(pacer, 0, pacer->divisor1,
 702                                 I8254_MODE3 | I8254_BINARY);
 703
 704                /* set up conversion pacing */
 705                comedi_8254_set_mode(counter, 0, I8254_MODE2 | I8254_BINARY);
 706                if (labpc_ai_convert_period(cmd, mode))
 707                        comedi_8254_write(counter, 0, pacer->divisor);
 708
 709                /* set up scan pacing */
 710                if (labpc_ai_scan_period(cmd, mode))
 711                        comedi_8254_load(pacer, 1, pacer->divisor2,
 712                                         I8254_MODE2 | I8254_BINARY);
 713        }
 714
 715        labpc_clear_adc_fifo(dev);
 716
 717        if (xfer == isa_dma_transfer)
 718                labpc_setup_dma(dev, s);
 719
 720        /*  enable error interrupts */
 721        devpriv->cmd3 |= CMD3_ERRINTEN;
 722        /*  enable fifo not empty interrupt? */
 723        if (xfer == fifo_not_empty_transfer)
 724                devpriv->cmd3 |= CMD3_FIFOINTEN;
 725        devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
 726
 727        /*  setup any external triggering/pacing (cmd4 register) */
 728        devpriv->cmd4 = 0;
 729        if (cmd->convert_src != TRIG_EXT)
 730                devpriv->cmd4 |= CMD4_ECLKRCV;
 731        /*
 732         * XXX should discard first scan when using interval scanning
 733         * since manual says it is not synced with scan clock.
 734         */
 735        if (!labpc_use_continuous_mode(cmd, mode)) {
 736                devpriv->cmd4 |= CMD4_INTSCAN;
 737                if (cmd->scan_begin_src == TRIG_EXT)
 738                        devpriv->cmd4 |= CMD4_EOIRCV;
 739        }
 740        /*  single-ended/differential */
 741        if (aref == AREF_DIFF)
 742                devpriv->cmd4 |= CMD4_SEDIFF;
 743        devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
 744
 745        /*  startup acquisition */
 746
 747        spin_lock_irqsave(&dev->spinlock, flags);
 748
 749        /* use 2 cascaded counters for pacing */
 750        devpriv->cmd2 |= CMD2_TBSEL;
 751
 752        devpriv->cmd2 &= ~(CMD2_SWTRIG | CMD2_HWTRIG | CMD2_PRETRIG);
 753        if (cmd->start_src == TRIG_EXT)
 754                devpriv->cmd2 |= CMD2_HWTRIG;
 755        else
 756                devpriv->cmd2 |= CMD2_SWTRIG;
 757        if (cmd->stop_src == TRIG_EXT)
 758                devpriv->cmd2 |= (CMD2_HWTRIG | CMD2_PRETRIG);
 759
 760        devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
 761
 762        spin_unlock_irqrestore(&dev->spinlock, flags);
 763
 764        return 0;
 765}
 766
 767/* read all available samples from ai fifo */
 768static int labpc_drain_fifo(struct comedi_device *dev)
 769{
 770        struct labpc_private *devpriv = dev->private;
 771        struct comedi_async *async = dev->read_subdev->async;
 772        struct comedi_cmd *cmd = &async->cmd;
 773        unsigned short data;
 774        const int timeout = 10000;
 775        unsigned int i;
 776
 777        devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
 778
 779        for (i = 0; (devpriv->stat1 & STAT1_DAVAIL) && i < timeout;
 780             i++) {
 781                /*  quit if we have all the data we want */
 782                if (cmd->stop_src == TRIG_COUNT) {
 783                        if (devpriv->count == 0)
 784                                break;
 785                        devpriv->count--;
 786                }
 787                data = labpc_read_adc_fifo(dev);
 788                comedi_buf_write_samples(dev->read_subdev, &data, 1);
 789                devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
 790        }
 791        if (i == timeout) {
 792                dev_err(dev->class_dev, "ai timeout, fifo never empties\n");
 793                async->events |= COMEDI_CB_ERROR;
 794                return -1;
 795        }
 796
 797        return 0;
 798}
 799
 800/*
 801 * Makes sure all data acquired by board is transferred to comedi (used
 802 * when acquisition is terminated by stop_src == TRIG_EXT).
 803 */
 804static void labpc_drain_dregs(struct comedi_device *dev)
 805{
 806        struct labpc_private *devpriv = dev->private;
 807
 808        if (devpriv->current_transfer == isa_dma_transfer)
 809                labpc_drain_dma(dev);
 810
 811        labpc_drain_fifo(dev);
 812}
 813
 814/* interrupt service routine */
 815static irqreturn_t labpc_interrupt(int irq, void *d)
 816{
 817        struct comedi_device *dev = d;
 818        const struct labpc_boardinfo *board = dev->board_ptr;
 819        struct labpc_private *devpriv = dev->private;
 820        struct comedi_subdevice *s = dev->read_subdev;
 821        struct comedi_async *async;
 822        struct comedi_cmd *cmd;
 823
 824        if (!dev->attached) {
 825                dev_err(dev->class_dev, "premature interrupt\n");
 826                return IRQ_HANDLED;
 827        }
 828
 829        async = s->async;
 830        cmd = &async->cmd;
 831
 832        /* read board status */
 833        devpriv->stat1 = devpriv->read_byte(dev, STAT1_REG);
 834        if (board->is_labpc1200)
 835                devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
 836
 837        if ((devpriv->stat1 & (STAT1_GATA0 | STAT1_CNTINT | STAT1_OVERFLOW |
 838                               STAT1_OVERRUN | STAT1_DAVAIL)) == 0 &&
 839            (devpriv->stat2 & STAT2_OUTA1) == 0 &&
 840            (devpriv->stat2 & STAT2_FIFONHF)) {
 841                return IRQ_NONE;
 842        }
 843
 844        if (devpriv->stat1 & STAT1_OVERRUN) {
 845                /* clear error interrupt */
 846                devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
 847                async->events |= COMEDI_CB_ERROR;
 848                comedi_handle_events(dev, s);
 849                dev_err(dev->class_dev, "overrun\n");
 850                return IRQ_HANDLED;
 851        }
 852
 853        if (devpriv->current_transfer == isa_dma_transfer)
 854                labpc_handle_dma_status(dev);
 855        else
 856                labpc_drain_fifo(dev);
 857
 858        if (devpriv->stat1 & STAT1_CNTINT) {
 859                dev_err(dev->class_dev, "handled timer interrupt?\n");
 860                /*  clear it */
 861                devpriv->write_byte(dev, 0x1, TIMER_CLEAR_REG);
 862        }
 863
 864        if (devpriv->stat1 & STAT1_OVERFLOW) {
 865                /*  clear error interrupt */
 866                devpriv->write_byte(dev, 0x1, ADC_FIFO_CLEAR_REG);
 867                async->events |= COMEDI_CB_ERROR;
 868                comedi_handle_events(dev, s);
 869                dev_err(dev->class_dev, "overflow\n");
 870                return IRQ_HANDLED;
 871        }
 872        /*  handle external stop trigger */
 873        if (cmd->stop_src == TRIG_EXT) {
 874                if (devpriv->stat2 & STAT2_OUTA1) {
 875                        labpc_drain_dregs(dev);
 876                        async->events |= COMEDI_CB_EOA;
 877                }
 878        }
 879
 880        /* TRIG_COUNT end of acquisition */
 881        if (cmd->stop_src == TRIG_COUNT) {
 882                if (devpriv->count == 0)
 883                        async->events |= COMEDI_CB_EOA;
 884        }
 885
 886        comedi_handle_events(dev, s);
 887        return IRQ_HANDLED;
 888}
 889
 890static void labpc_ao_write(struct comedi_device *dev,
 891                           struct comedi_subdevice *s,
 892                           unsigned int chan, unsigned int val)
 893{
 894        struct labpc_private *devpriv = dev->private;
 895
 896        devpriv->write_byte(dev, val & 0xff, DAC_LSB_REG(chan));
 897        devpriv->write_byte(dev, (val >> 8) & 0xff, DAC_MSB_REG(chan));
 898
 899        s->readback[chan] = val;
 900}
 901
 902static int labpc_ao_insn_write(struct comedi_device *dev,
 903                               struct comedi_subdevice *s,
 904                               struct comedi_insn *insn,
 905                               unsigned int *data)
 906{
 907        const struct labpc_boardinfo *board = dev->board_ptr;
 908        struct labpc_private *devpriv = dev->private;
 909        unsigned int channel;
 910        unsigned int range;
 911        unsigned int i;
 912        unsigned long flags;
 913
 914        channel = CR_CHAN(insn->chanspec);
 915
 916        /*
 917         * Turn off pacing of analog output channel.
 918         * NOTE: hardware bug in daqcard-1200 means pacing cannot
 919         * be independently enabled/disabled for its the two channels.
 920         */
 921        spin_lock_irqsave(&dev->spinlock, flags);
 922        devpriv->cmd2 &= ~CMD2_LDAC(channel);
 923        devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
 924        spin_unlock_irqrestore(&dev->spinlock, flags);
 925
 926        /* set range */
 927        if (board->is_labpc1200) {
 928                range = CR_RANGE(insn->chanspec);
 929                if (comedi_range_is_unipolar(s, range))
 930                        devpriv->cmd6 |= CMD6_DACUNI(channel);
 931                else
 932                        devpriv->cmd6 &= ~CMD6_DACUNI(channel);
 933                /*  write to register */
 934                devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
 935        }
 936        /* send data */
 937        for (i = 0; i < insn->n; i++)
 938                labpc_ao_write(dev, s, channel, data[i]);
 939
 940        return insn->n;
 941}
 942
 943/* lowlevel write to eeprom/dac */
 944static void labpc_serial_out(struct comedi_device *dev, unsigned int value,
 945                             unsigned int value_width)
 946{
 947        struct labpc_private *devpriv = dev->private;
 948        int i;
 949
 950        for (i = 1; i <= value_width; i++) {
 951                /*  clear serial clock */
 952                devpriv->cmd5 &= ~CMD5_SCLK;
 953                /*  send bits most significant bit first */
 954                if (value & (1 << (value_width - i)))
 955                        devpriv->cmd5 |= CMD5_SDATA;
 956                else
 957                        devpriv->cmd5 &= ~CMD5_SDATA;
 958                udelay(1);
 959                devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
 960                /*  set clock to load bit */
 961                devpriv->cmd5 |= CMD5_SCLK;
 962                udelay(1);
 963                devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
 964        }
 965}
 966
 967/* lowlevel read from eeprom */
 968static unsigned int labpc_serial_in(struct comedi_device *dev)
 969{
 970        struct labpc_private *devpriv = dev->private;
 971        unsigned int value = 0;
 972        int i;
 973        const int value_width = 8;      /*  number of bits wide values are */
 974
 975        for (i = 1; i <= value_width; i++) {
 976                /*  set serial clock */
 977                devpriv->cmd5 |= CMD5_SCLK;
 978                udelay(1);
 979                devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
 980                /*  clear clock bit */
 981                devpriv->cmd5 &= ~CMD5_SCLK;
 982                udelay(1);
 983                devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
 984                /*  read bits most significant bit first */
 985                udelay(1);
 986                devpriv->stat2 = devpriv->read_byte(dev, STAT2_REG);
 987                if (devpriv->stat2 & STAT2_PROMOUT)
 988                        value |= 1 << (value_width - i);
 989        }
 990
 991        return value;
 992}
 993
 994static unsigned int labpc_eeprom_read(struct comedi_device *dev,
 995                                      unsigned int address)
 996{
 997        struct labpc_private *devpriv = dev->private;
 998        unsigned int value;
 999        /*  bits to tell eeprom to expect a read */
1000        const int read_instruction = 0x3;
1001        /*  8 bit write lengths to eeprom */
1002        const int write_length = 8;
1003
1004        /*  enable read/write to eeprom */
1005        devpriv->cmd5 &= ~CMD5_EEPROMCS;
1006        udelay(1);
1007        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1008        devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
1009        udelay(1);
1010        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1011
1012        /*  send read instruction */
1013        labpc_serial_out(dev, read_instruction, write_length);
1014        /*  send 8 bit address to read from */
1015        labpc_serial_out(dev, address, write_length);
1016        /*  read result */
1017        value = labpc_serial_in(dev);
1018
1019        /*  disable read/write to eeprom */
1020        devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
1021        udelay(1);
1022        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1023
1024        return value;
1025}
1026
1027static unsigned int labpc_eeprom_read_status(struct comedi_device *dev)
1028{
1029        struct labpc_private *devpriv = dev->private;
1030        unsigned int value;
1031        const int read_status_instruction = 0x5;
1032        const int write_length = 8;     /*  8 bit write lengths to eeprom */
1033
1034        /*  enable read/write to eeprom */
1035        devpriv->cmd5 &= ~CMD5_EEPROMCS;
1036        udelay(1);
1037        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1038        devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
1039        udelay(1);
1040        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1041
1042        /*  send read status instruction */
1043        labpc_serial_out(dev, read_status_instruction, write_length);
1044        /*  read result */
1045        value = labpc_serial_in(dev);
1046
1047        /*  disable read/write to eeprom */
1048        devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
1049        udelay(1);
1050        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1051
1052        return value;
1053}
1054
1055static void labpc_eeprom_write(struct comedi_device *dev,
1056                               unsigned int address, unsigned int value)
1057{
1058        struct labpc_private *devpriv = dev->private;
1059        const int write_enable_instruction = 0x6;
1060        const int write_instruction = 0x2;
1061        const int write_length = 8;     /*  8 bit write lengths to eeprom */
1062
1063        /*  enable read/write to eeprom */
1064        devpriv->cmd5 &= ~CMD5_EEPROMCS;
1065        udelay(1);
1066        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1067        devpriv->cmd5 |= (CMD5_EEPROMCS | CMD5_WRTPRT);
1068        udelay(1);
1069        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1070
1071        /*  send write_enable instruction */
1072        labpc_serial_out(dev, write_enable_instruction, write_length);
1073        devpriv->cmd5 &= ~CMD5_EEPROMCS;
1074        udelay(1);
1075        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1076
1077        /*  send write instruction */
1078        devpriv->cmd5 |= CMD5_EEPROMCS;
1079        udelay(1);
1080        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1081        labpc_serial_out(dev, write_instruction, write_length);
1082        /*  send 8 bit address to write to */
1083        labpc_serial_out(dev, address, write_length);
1084        /*  write value */
1085        labpc_serial_out(dev, value, write_length);
1086        devpriv->cmd5 &= ~CMD5_EEPROMCS;
1087        udelay(1);
1088        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1089
1090        /*  disable read/write to eeprom */
1091        devpriv->cmd5 &= ~(CMD5_EEPROMCS | CMD5_WRTPRT);
1092        udelay(1);
1093        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1094}
1095
1096/* writes to 8 bit calibration dacs */
1097static void write_caldac(struct comedi_device *dev, unsigned int channel,
1098                         unsigned int value)
1099{
1100        struct labpc_private *devpriv = dev->private;
1101
1102        /*  clear caldac load bit and make sure we don't write to eeprom */
1103        devpriv->cmd5 &= ~(CMD5_CALDACLD | CMD5_EEPROMCS | CMD5_WRTPRT);
1104        udelay(1);
1105        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1106
1107        /*  write 4 bit channel */
1108        labpc_serial_out(dev, channel, 4);
1109        /*  write 8 bit caldac value */
1110        labpc_serial_out(dev, value, 8);
1111
1112        /*  set and clear caldac bit to load caldac value */
1113        devpriv->cmd5 |= CMD5_CALDACLD;
1114        udelay(1);
1115        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1116        devpriv->cmd5 &= ~CMD5_CALDACLD;
1117        udelay(1);
1118        devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1119}
1120
1121static int labpc_calib_insn_write(struct comedi_device *dev,
1122                                  struct comedi_subdevice *s,
1123                                  struct comedi_insn *insn,
1124                                  unsigned int *data)
1125{
1126        unsigned int chan = CR_CHAN(insn->chanspec);
1127
1128        /*
1129         * Only write the last data value to the caldac. Preceding
1130         * data would be overwritten anyway.
1131         */
1132        if (insn->n > 0) {
1133                unsigned int val = data[insn->n - 1];
1134
1135                if (s->readback[chan] != val) {
1136                        write_caldac(dev, chan, val);
1137                        s->readback[chan] = val;
1138                }
1139        }
1140
1141        return insn->n;
1142}
1143
1144static int labpc_eeprom_ready(struct comedi_device *dev,
1145                              struct comedi_subdevice *s,
1146                              struct comedi_insn *insn,
1147                              unsigned long context)
1148{
1149        unsigned int status;
1150
1151        /* make sure there isn't already a write in progress */
1152        status = labpc_eeprom_read_status(dev);
1153        if ((status & 0x1) == 0)
1154                return 0;
1155        return -EBUSY;
1156}
1157
1158static int labpc_eeprom_insn_write(struct comedi_device *dev,
1159                                   struct comedi_subdevice *s,
1160                                   struct comedi_insn *insn,
1161                                   unsigned int *data)
1162{
1163        unsigned int chan = CR_CHAN(insn->chanspec);
1164        int ret;
1165
1166        /* only allow writes to user area of eeprom */
1167        if (chan < 16 || chan > 127)
1168                return -EINVAL;
1169
1170        /*
1171         * Only write the last data value to the eeprom. Preceding
1172         * data would be overwritten anyway.
1173         */
1174        if (insn->n > 0) {
1175                unsigned int val = data[insn->n - 1];
1176
1177                ret = comedi_timeout(dev, s, insn, labpc_eeprom_ready, 0);
1178                if (ret)
1179                        return ret;
1180
1181                labpc_eeprom_write(dev, chan, val);
1182                s->readback[chan] = val;
1183        }
1184
1185        return insn->n;
1186}
1187
1188int labpc_common_attach(struct comedi_device *dev,
1189                        unsigned int irq, unsigned long isr_flags)
1190{
1191        const struct labpc_boardinfo *board = dev->board_ptr;
1192        struct labpc_private *devpriv;
1193        struct comedi_subdevice *s;
1194        int ret;
1195        int i;
1196
1197        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1198        if (!devpriv)
1199                return -ENOMEM;
1200
1201        if (dev->mmio) {
1202                devpriv->read_byte = labpc_readb;
1203                devpriv->write_byte = labpc_writeb;
1204        } else {
1205                devpriv->read_byte = labpc_inb;
1206                devpriv->write_byte = labpc_outb;
1207        }
1208
1209        /* initialize board's command registers */
1210        devpriv->write_byte(dev, devpriv->cmd1, CMD1_REG);
1211        devpriv->write_byte(dev, devpriv->cmd2, CMD2_REG);
1212        devpriv->write_byte(dev, devpriv->cmd3, CMD3_REG);
1213        devpriv->write_byte(dev, devpriv->cmd4, CMD4_REG);
1214        if (board->is_labpc1200) {
1215                devpriv->write_byte(dev, devpriv->cmd5, CMD5_REG);
1216                devpriv->write_byte(dev, devpriv->cmd6, CMD6_REG);
1217        }
1218
1219        if (irq) {
1220                ret = request_irq(irq, labpc_interrupt, isr_flags,
1221                                  dev->board_name, dev);
1222                if (ret == 0)
1223                        dev->irq = irq;
1224        }
1225
1226        if (dev->mmio) {
1227                dev->pacer = comedi_8254_mm_init(dev->mmio + COUNTER_B_BASE_REG,
1228                                                 I8254_OSC_BASE_2MHZ,
1229                                                 I8254_IO8, 0);
1230                devpriv->counter = comedi_8254_mm_init(dev->mmio +
1231                                                       COUNTER_A_BASE_REG,
1232                                                       I8254_OSC_BASE_2MHZ,
1233                                                       I8254_IO8, 0);
1234        } else {
1235                dev->pacer = comedi_8254_init(dev->iobase + COUNTER_B_BASE_REG,
1236                                              I8254_OSC_BASE_2MHZ,
1237                                              I8254_IO8, 0);
1238                devpriv->counter = comedi_8254_init(dev->iobase +
1239                                                    COUNTER_A_BASE_REG,
1240                                                    I8254_OSC_BASE_2MHZ,
1241                                                    I8254_IO8, 0);
1242        }
1243        if (!dev->pacer || !devpriv->counter)
1244                return -ENOMEM;
1245
1246        ret = comedi_alloc_subdevices(dev, 5);
1247        if (ret)
1248                return ret;
1249
1250        /* analog input subdevice */
1251        s = &dev->subdevices[0];
1252        s->type         = COMEDI_SUBD_AI;
1253        s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1254        s->n_chan       = 8;
1255        s->len_chanlist = 8;
1256        s->maxdata      = 0x0fff;
1257        s->range_table  = board->is_labpc1200 ?
1258                          &range_labpc_1200_ai : &range_labpc_plus_ai;
1259        s->insn_read    = labpc_ai_insn_read;
1260        if (dev->irq) {
1261                dev->read_subdev = s;
1262                s->subdev_flags |= SDF_CMD_READ;
1263                s->do_cmd       = labpc_ai_cmd;
1264                s->do_cmdtest   = labpc_ai_cmdtest;
1265                s->cancel       = labpc_cancel;
1266        }
1267
1268        /* analog output */
1269        s = &dev->subdevices[1];
1270        if (board->has_ao) {
1271                s->type         = COMEDI_SUBD_AO;
1272                s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1273                s->n_chan       = 2;
1274                s->maxdata      = 0x0fff;
1275                s->range_table  = &range_labpc_ao;
1276                s->insn_write   = labpc_ao_insn_write;
1277
1278                ret = comedi_alloc_subdev_readback(s);
1279                if (ret)
1280                        return ret;
1281
1282                /* initialize analog outputs to a known value */
1283                for (i = 0; i < s->n_chan; i++)
1284                        labpc_ao_write(dev, s, i, s->maxdata / 2);
1285        } else {
1286                s->type         = COMEDI_SUBD_UNUSED;
1287        }
1288
1289        /* 8255 dio */
1290        s = &dev->subdevices[2];
1291        if (dev->mmio)
1292                ret = subdev_8255_mm_init(dev, s, NULL, DIO_BASE_REG);
1293        else
1294                ret = subdev_8255_init(dev, s, NULL, DIO_BASE_REG);
1295        if (ret)
1296                return ret;
1297
1298        /*  calibration subdevices for boards that have one */
1299        s = &dev->subdevices[3];
1300        if (board->is_labpc1200) {
1301                s->type         = COMEDI_SUBD_CALIB;
1302                s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1303                s->n_chan       = 16;
1304                s->maxdata      = 0xff;
1305                s->insn_write   = labpc_calib_insn_write;
1306
1307                ret = comedi_alloc_subdev_readback(s);
1308                if (ret)
1309                        return ret;
1310
1311                for (i = 0; i < s->n_chan; i++) {
1312                        write_caldac(dev, i, s->maxdata / 2);
1313                        s->readback[i] = s->maxdata / 2;
1314                }
1315        } else {
1316                s->type         = COMEDI_SUBD_UNUSED;
1317        }
1318
1319        /* EEPROM (256 bytes) */
1320        s = &dev->subdevices[4];
1321        if (board->is_labpc1200) {
1322                s->type         = COMEDI_SUBD_MEMORY;
1323                s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1324                s->n_chan       = 256;
1325                s->maxdata      = 0xff;
1326                s->insn_write   = labpc_eeprom_insn_write;
1327
1328                ret = comedi_alloc_subdev_readback(s);
1329                if (ret)
1330                        return ret;
1331
1332                for (i = 0; i < s->n_chan; i++)
1333                        s->readback[i] = labpc_eeprom_read(dev, i);
1334        } else {
1335                s->type         = COMEDI_SUBD_UNUSED;
1336        }
1337
1338        return 0;
1339}
1340EXPORT_SYMBOL_GPL(labpc_common_attach);
1341
1342void labpc_common_detach(struct comedi_device *dev)
1343{
1344        struct labpc_private *devpriv = dev->private;
1345
1346        if (devpriv)
1347                kfree(devpriv->counter);
1348}
1349EXPORT_SYMBOL_GPL(labpc_common_detach);
1350
1351static int __init labpc_common_init(void)
1352{
1353        return 0;
1354}
1355module_init(labpc_common_init);
1356
1357static void __exit labpc_common_exit(void)
1358{
1359}
1360module_exit(labpc_common_exit);
1361
1362MODULE_AUTHOR("Comedi http://www.comedi.org");
1363MODULE_DESCRIPTION("Comedi helper for ni_labpc, ni_labpc_pci, ni_labpc_cs");
1364MODULE_LICENSE("GPL");
1365