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