linux/drivers/comedi/drivers/addi_apci_3120.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * addi_apci_3120.c
   4 * Copyright (C) 2004,2005  ADDI-DATA GmbH for the source code of this module.
   5 *
   6 *      ADDI-DATA GmbH
   7 *      Dieselstrasse 3
   8 *      D-77833 Ottersweier
   9 *      Tel: +19(0)7223/9493-0
  10 *      Fax: +49(0)7223/9493-92
  11 *      http://www.addi-data.com
  12 *      info@addi-data.com
  13 */
  14
  15#include <linux/module.h>
  16#include <linux/interrupt.h>
  17
  18#include "../comedi_pci.h"
  19#include "amcc_s5933.h"
  20
  21/*
  22 * PCI BAR 0 register map (devpriv->amcc)
  23 * see amcc_s5933.h for register and bit defines
  24 */
  25#define APCI3120_FIFO_ADVANCE_ON_BYTE_2         BIT(29)
  26
  27/*
  28 * PCI BAR 1 register map (dev->iobase)
  29 */
  30#define APCI3120_AI_FIFO_REG                    0x00
  31#define APCI3120_CTRL_REG                       0x00
  32#define APCI3120_CTRL_EXT_TRIG                  BIT(15)
  33#define APCI3120_CTRL_GATE(x)                   BIT(12 + (x))
  34#define APCI3120_CTRL_PR(x)                     (((x) & 0xf) << 8)
  35#define APCI3120_CTRL_PA(x)                     (((x) & 0xf) << 0)
  36#define APCI3120_AI_SOFTTRIG_REG                0x02
  37#define APCI3120_STATUS_REG                     0x02
  38#define APCI3120_STATUS_EOC_INT                 BIT(15)
  39#define APCI3120_STATUS_AMCC_INT                BIT(14)
  40#define APCI3120_STATUS_EOS_INT                 BIT(13)
  41#define APCI3120_STATUS_TIMER2_INT              BIT(12)
  42#define APCI3120_STATUS_INT_MASK                (0xf << 12)
  43#define APCI3120_STATUS_TO_DI_BITS(x)           (((x) >> 8) & 0xf)
  44#define APCI3120_STATUS_TO_VERSION(x)           (((x) >> 4) & 0xf)
  45#define APCI3120_STATUS_FIFO_FULL               BIT(2)
  46#define APCI3120_STATUS_FIFO_EMPTY              BIT(1)
  47#define APCI3120_STATUS_DA_READY                BIT(0)
  48#define APCI3120_TIMER_REG                      0x04
  49#define APCI3120_CHANLIST_REG                   0x06
  50#define APCI3120_CHANLIST_INDEX(x)              (((x) & 0xf) << 8)
  51#define APCI3120_CHANLIST_UNIPOLAR              BIT(7)
  52#define APCI3120_CHANLIST_GAIN(x)               (((x) & 0x3) << 4)
  53#define APCI3120_CHANLIST_MUX(x)                (((x) & 0xf) << 0)
  54#define APCI3120_AO_REG(x)                      (0x08 + (((x) / 4) * 2))
  55#define APCI3120_AO_MUX(x)                      (((x) & 0x3) << 14)
  56#define APCI3120_AO_DATA(x)                     ((x) << 0)
  57#define APCI3120_TIMER_MODE_REG                 0x0c
  58#define APCI3120_TIMER_MODE(_t, _m)             ((_m) << ((_t) * 2))
  59#define APCI3120_TIMER_MODE0                    0  /* I8254_MODE0 */
  60#define APCI3120_TIMER_MODE2                    1  /* I8254_MODE2 */
  61#define APCI3120_TIMER_MODE4                    2  /* I8254_MODE4 */
  62#define APCI3120_TIMER_MODE5                    3  /* I8254_MODE5 */
  63#define APCI3120_TIMER_MODE_MASK(_t)            (3 << ((_t) * 2))
  64#define APCI3120_CTR0_REG                       0x0d
  65#define APCI3120_CTR0_DO_BITS(x)                ((x) << 4)
  66#define APCI3120_CTR0_TIMER_SEL(x)              ((x) << 0)
  67#define APCI3120_MODE_REG                       0x0e
  68#define APCI3120_MODE_TIMER2_CLK(x)             (((x) & 0x3) << 6)
  69#define APCI3120_MODE_TIMER2_CLK_OSC            APCI3120_MODE_TIMER2_CLK(0)
  70#define APCI3120_MODE_TIMER2_CLK_OUT1           APCI3120_MODE_TIMER2_CLK(1)
  71#define APCI3120_MODE_TIMER2_CLK_EOC            APCI3120_MODE_TIMER2_CLK(2)
  72#define APCI3120_MODE_TIMER2_CLK_EOS            APCI3120_MODE_TIMER2_CLK(3)
  73#define APCI3120_MODE_TIMER2_CLK_MASK           APCI3120_MODE_TIMER2_CLK(3)
  74#define APCI3120_MODE_TIMER2_AS(x)              (((x) & 0x3) << 4)
  75#define APCI3120_MODE_TIMER2_AS_TIMER           APCI3120_MODE_TIMER2_AS(0)
  76#define APCI3120_MODE_TIMER2_AS_COUNTER         APCI3120_MODE_TIMER2_AS(1)
  77#define APCI3120_MODE_TIMER2_AS_WDOG            APCI3120_MODE_TIMER2_AS(2)
  78#define APCI3120_MODE_TIMER2_AS_MASK            APCI3120_MODE_TIMER2_AS(3)
  79#define APCI3120_MODE_SCAN_ENA                  BIT(3)
  80#define APCI3120_MODE_TIMER2_IRQ_ENA            BIT(2)
  81#define APCI3120_MODE_EOS_IRQ_ENA               BIT(1)
  82#define APCI3120_MODE_EOC_IRQ_ENA               BIT(0)
  83
  84/*
  85 * PCI BAR 2 register map (devpriv->addon)
  86 */
  87#define APCI3120_ADDON_ADDR_REG                 0x00
  88#define APCI3120_ADDON_DATA_REG                 0x02
  89#define APCI3120_ADDON_CTRL_REG                 0x04
  90#define APCI3120_ADDON_CTRL_AMWEN_ENA           BIT(1)
  91#define APCI3120_ADDON_CTRL_A2P_FIFO_ENA        BIT(0)
  92
  93/*
  94 * Board revisions
  95 */
  96#define APCI3120_REVA                           0xa
  97#define APCI3120_REVB                           0xb
  98#define APCI3120_REVA_OSC_BASE                  70      /* 70ns = 14.29MHz */
  99#define APCI3120_REVB_OSC_BASE                  50      /* 50ns = 20MHz */
 100
 101static const struct comedi_lrange apci3120_ai_range = {
 102        8, {
 103                BIP_RANGE(10),
 104                BIP_RANGE(5),
 105                BIP_RANGE(2),
 106                BIP_RANGE(1),
 107                UNI_RANGE(10),
 108                UNI_RANGE(5),
 109                UNI_RANGE(2),
 110                UNI_RANGE(1)
 111        }
 112};
 113
 114enum apci3120_boardid {
 115        BOARD_APCI3120,
 116        BOARD_APCI3001,
 117};
 118
 119struct apci3120_board {
 120        const char *name;
 121        unsigned int ai_is_16bit:1;
 122        unsigned int has_ao:1;
 123};
 124
 125static const struct apci3120_board apci3120_boardtypes[] = {
 126        [BOARD_APCI3120] = {
 127                .name           = "apci3120",
 128                .ai_is_16bit    = 1,
 129                .has_ao         = 1,
 130        },
 131        [BOARD_APCI3001] = {
 132                .name           = "apci3001",
 133        },
 134};
 135
 136struct apci3120_dmabuf {
 137        unsigned short *virt;
 138        dma_addr_t hw;
 139        unsigned int size;
 140        unsigned int use_size;
 141};
 142
 143struct apci3120_private {
 144        unsigned long amcc;
 145        unsigned long addon;
 146        unsigned int osc_base;
 147        unsigned int use_dma:1;
 148        unsigned int use_double_buffer:1;
 149        unsigned int cur_dmabuf:1;
 150        struct apci3120_dmabuf dmabuf[2];
 151        unsigned char do_bits;
 152        unsigned char timer_mode;
 153        unsigned char mode;
 154        unsigned short ctrl;
 155};
 156
 157static void apci3120_addon_write(struct comedi_device *dev,
 158                                 unsigned int val, unsigned int reg)
 159{
 160        struct apci3120_private *devpriv = dev->private;
 161
 162        /* 16-bit interface for AMCC add-on registers */
 163
 164        outw(reg, devpriv->addon + APCI3120_ADDON_ADDR_REG);
 165        outw(val & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
 166
 167        outw(reg + 2, devpriv->addon + APCI3120_ADDON_ADDR_REG);
 168        outw((val >> 16) & 0xffff, devpriv->addon + APCI3120_ADDON_DATA_REG);
 169}
 170
 171static void apci3120_init_dma(struct comedi_device *dev,
 172                              struct apci3120_dmabuf *dmabuf)
 173{
 174        struct apci3120_private *devpriv = dev->private;
 175
 176        /* AMCC - enable transfer count and reset A2P FIFO */
 177        outl(AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
 178             devpriv->amcc + AMCC_OP_REG_AGCSTS);
 179
 180        /* Add-On - enable transfer count and reset A2P FIFO */
 181        apci3120_addon_write(dev, AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO,
 182                             AMCC_OP_REG_AGCSTS);
 183
 184        /* AMCC - enable transfers and reset A2P flags */
 185        outl(RESET_A2P_FLAGS | EN_A2P_TRANSFERS,
 186             devpriv->amcc + AMCC_OP_REG_MCSR);
 187
 188        /* Add-On - DMA start address */
 189        apci3120_addon_write(dev, dmabuf->hw, AMCC_OP_REG_AMWAR);
 190
 191        /* Add-On - Number of acquisitions */
 192        apci3120_addon_write(dev, dmabuf->use_size, AMCC_OP_REG_AMWTC);
 193
 194        /* AMCC - enable write complete (DMA) and set FIFO advance */
 195        outl(APCI3120_FIFO_ADVANCE_ON_BYTE_2 | AINT_WRITE_COMPL,
 196             devpriv->amcc + AMCC_OP_REG_INTCSR);
 197
 198        /* Add-On - enable DMA */
 199        outw(APCI3120_ADDON_CTRL_AMWEN_ENA | APCI3120_ADDON_CTRL_A2P_FIFO_ENA,
 200             devpriv->addon + APCI3120_ADDON_CTRL_REG);
 201}
 202
 203static void apci3120_setup_dma(struct comedi_device *dev,
 204                               struct comedi_subdevice *s)
 205{
 206        struct apci3120_private *devpriv = dev->private;
 207        struct comedi_cmd *cmd = &s->async->cmd;
 208        struct apci3120_dmabuf *dmabuf0 = &devpriv->dmabuf[0];
 209        struct apci3120_dmabuf *dmabuf1 = &devpriv->dmabuf[1];
 210        unsigned int dmalen0 = dmabuf0->size;
 211        unsigned int dmalen1 = dmabuf1->size;
 212        unsigned int scan_bytes;
 213
 214        scan_bytes = comedi_samples_to_bytes(s, cmd->scan_end_arg);
 215
 216        if (cmd->stop_src == TRIG_COUNT) {
 217                /*
 218                 * Must we fill full first buffer? And must we fill
 219                 * full second buffer when first is once filled?
 220                 */
 221                if (dmalen0 > (cmd->stop_arg * scan_bytes))
 222                        dmalen0 = cmd->stop_arg * scan_bytes;
 223                else if (dmalen1 > (cmd->stop_arg * scan_bytes - dmalen0))
 224                        dmalen1 = cmd->stop_arg * scan_bytes - dmalen0;
 225        }
 226
 227        if (cmd->flags & CMDF_WAKE_EOS) {
 228                /* don't we want wake up every scan? */
 229                if (dmalen0 > scan_bytes) {
 230                        dmalen0 = scan_bytes;
 231                        if (cmd->scan_end_arg & 1)
 232                                dmalen0 += 2;
 233                }
 234                if (dmalen1 > scan_bytes) {
 235                        dmalen1 = scan_bytes;
 236                        if (cmd->scan_end_arg & 1)
 237                                dmalen1 -= 2;
 238                        if (dmalen1 < 4)
 239                                dmalen1 = 4;
 240                }
 241        } else {
 242                /* isn't output buff smaller that our DMA buff? */
 243                if (dmalen0 > s->async->prealloc_bufsz)
 244                        dmalen0 = s->async->prealloc_bufsz;
 245                if (dmalen1 > s->async->prealloc_bufsz)
 246                        dmalen1 = s->async->prealloc_bufsz;
 247        }
 248        dmabuf0->use_size = dmalen0;
 249        dmabuf1->use_size = dmalen1;
 250
 251        apci3120_init_dma(dev, dmabuf0);
 252}
 253
 254/*
 255 * There are three timers on the board. They all use the same base
 256 * clock with a fixed prescaler for each timer. The base clock used
 257 * depends on the board version and type.
 258 *
 259 * APCI-3120 Rev A boards OSC = 14.29MHz base clock (~70ns)
 260 * APCI-3120 Rev B boards OSC = 20MHz base clock (50ns)
 261 * APCI-3001 boards OSC = 20MHz base clock (50ns)
 262 *
 263 * The prescalers for each timer are:
 264 * Timer 0 CLK = OSC/10
 265 * Timer 1 CLK = OSC/1000
 266 * Timer 2 CLK = OSC/1000
 267 */
 268static unsigned int apci3120_ns_to_timer(struct comedi_device *dev,
 269                                         unsigned int timer,
 270                                         unsigned int ns,
 271                                         unsigned int flags)
 272{
 273        struct apci3120_private *devpriv = dev->private;
 274        unsigned int prescale = (timer == 0) ? 10 : 1000;
 275        unsigned int timer_base = devpriv->osc_base * prescale;
 276        unsigned int divisor;
 277
 278        switch (flags & CMDF_ROUND_MASK) {
 279        case CMDF_ROUND_UP:
 280                divisor = DIV_ROUND_UP(ns, timer_base);
 281                break;
 282        case CMDF_ROUND_DOWN:
 283                divisor = ns / timer_base;
 284                break;
 285        case CMDF_ROUND_NEAREST:
 286        default:
 287                divisor = DIV_ROUND_CLOSEST(ns, timer_base);
 288                break;
 289        }
 290
 291        if (timer == 2) {
 292                /* timer 2 is 24-bits */
 293                if (divisor > 0x00ffffff)
 294                        divisor = 0x00ffffff;
 295        } else {
 296                /* timers 0 and 1 are 16-bits */
 297                if (divisor > 0xffff)
 298                        divisor = 0xffff;
 299        }
 300        /* the timers require a minimum divisor of 2 */
 301        if (divisor < 2)
 302                divisor = 2;
 303
 304        return divisor;
 305}
 306
 307static void apci3120_clr_timer2_interrupt(struct comedi_device *dev)
 308{
 309        /* a dummy read of APCI3120_CTR0_REG clears the timer 2 interrupt */
 310        inb(dev->iobase + APCI3120_CTR0_REG);
 311}
 312
 313static void apci3120_timer_write(struct comedi_device *dev,
 314                                 unsigned int timer, unsigned int val)
 315{
 316        struct apci3120_private *devpriv = dev->private;
 317
 318        /* write 16-bit value to timer (lower 16-bits of timer 2) */
 319        outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
 320             APCI3120_CTR0_TIMER_SEL(timer),
 321             dev->iobase + APCI3120_CTR0_REG);
 322        outw(val & 0xffff, dev->iobase + APCI3120_TIMER_REG);
 323
 324        if (timer == 2) {
 325                /* write upper 16-bits to timer 2 */
 326                outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
 327                     APCI3120_CTR0_TIMER_SEL(timer + 1),
 328                     dev->iobase + APCI3120_CTR0_REG);
 329                outw((val >> 16) & 0xffff, dev->iobase + APCI3120_TIMER_REG);
 330        }
 331}
 332
 333static unsigned int apci3120_timer_read(struct comedi_device *dev,
 334                                        unsigned int timer)
 335{
 336        struct apci3120_private *devpriv = dev->private;
 337        unsigned int val;
 338
 339        /* read 16-bit value from timer (lower 16-bits of timer 2) */
 340        outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
 341             APCI3120_CTR0_TIMER_SEL(timer),
 342             dev->iobase + APCI3120_CTR0_REG);
 343        val = inw(dev->iobase + APCI3120_TIMER_REG);
 344
 345        if (timer == 2) {
 346                /* read upper 16-bits from timer 2 */
 347                outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits) |
 348                     APCI3120_CTR0_TIMER_SEL(timer + 1),
 349                     dev->iobase + APCI3120_CTR0_REG);
 350                val |= (inw(dev->iobase + APCI3120_TIMER_REG) << 16);
 351        }
 352
 353        return val;
 354}
 355
 356static void apci3120_timer_set_mode(struct comedi_device *dev,
 357                                    unsigned int timer, unsigned int mode)
 358{
 359        struct apci3120_private *devpriv = dev->private;
 360
 361        devpriv->timer_mode &= ~APCI3120_TIMER_MODE_MASK(timer);
 362        devpriv->timer_mode |= APCI3120_TIMER_MODE(timer, mode);
 363        outb(devpriv->timer_mode, dev->iobase + APCI3120_TIMER_MODE_REG);
 364}
 365
 366static void apci3120_timer_enable(struct comedi_device *dev,
 367                                  unsigned int timer, bool enable)
 368{
 369        struct apci3120_private *devpriv = dev->private;
 370
 371        if (enable)
 372                devpriv->ctrl |= APCI3120_CTRL_GATE(timer);
 373        else
 374                devpriv->ctrl &= ~APCI3120_CTRL_GATE(timer);
 375        outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
 376}
 377
 378static void apci3120_exttrig_enable(struct comedi_device *dev, bool enable)
 379{
 380        struct apci3120_private *devpriv = dev->private;
 381
 382        if (enable)
 383                devpriv->ctrl |= APCI3120_CTRL_EXT_TRIG;
 384        else
 385                devpriv->ctrl &= ~APCI3120_CTRL_EXT_TRIG;
 386        outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
 387}
 388
 389static void apci3120_set_chanlist(struct comedi_device *dev,
 390                                  struct comedi_subdevice *s,
 391                                  int n_chan, unsigned int *chanlist)
 392{
 393        struct apci3120_private *devpriv = dev->private;
 394        int i;
 395
 396        /* set chanlist for scan */
 397        for (i = 0; i < n_chan; i++) {
 398                unsigned int chan = CR_CHAN(chanlist[i]);
 399                unsigned int range = CR_RANGE(chanlist[i]);
 400                unsigned int val;
 401
 402                val = APCI3120_CHANLIST_MUX(chan) |
 403                      APCI3120_CHANLIST_GAIN(range) |
 404                      APCI3120_CHANLIST_INDEX(i);
 405
 406                if (comedi_range_is_unipolar(s, range))
 407                        val |= APCI3120_CHANLIST_UNIPOLAR;
 408
 409                outw(val, dev->iobase + APCI3120_CHANLIST_REG);
 410        }
 411
 412        /* a dummy read of APCI3120_TIMER_MODE_REG resets the ai FIFO */
 413        inw(dev->iobase + APCI3120_TIMER_MODE_REG);
 414
 415        /* set scan length (PR) and scan start (PA) */
 416        devpriv->ctrl = APCI3120_CTRL_PR(n_chan - 1) | APCI3120_CTRL_PA(0);
 417        outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
 418
 419        /* enable chanlist scanning if necessary */
 420        if (n_chan > 1)
 421                devpriv->mode |= APCI3120_MODE_SCAN_ENA;
 422}
 423
 424static void apci3120_interrupt_dma(struct comedi_device *dev,
 425                                   struct comedi_subdevice *s)
 426{
 427        struct apci3120_private *devpriv = dev->private;
 428        struct comedi_async *async = s->async;
 429        struct comedi_cmd *cmd = &async->cmd;
 430        struct apci3120_dmabuf *dmabuf;
 431        unsigned int nbytes;
 432        unsigned int nsamples;
 433
 434        dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
 435
 436        nbytes = dmabuf->use_size - inl(devpriv->amcc + AMCC_OP_REG_MWTC);
 437
 438        if (nbytes < dmabuf->use_size)
 439                dev_err(dev->class_dev, "Interrupted DMA transfer!\n");
 440        if (nbytes & 1) {
 441                dev_err(dev->class_dev, "Odd count of bytes in DMA ring!\n");
 442                async->events |= COMEDI_CB_ERROR;
 443                return;
 444        }
 445
 446        nsamples = comedi_bytes_to_samples(s, nbytes);
 447        if (nsamples) {
 448                comedi_buf_write_samples(s, dmabuf->virt, nsamples);
 449
 450                if (!(cmd->flags & CMDF_WAKE_EOS))
 451                        async->events |= COMEDI_CB_EOS;
 452        }
 453
 454        if ((async->events & COMEDI_CB_CANCEL_MASK) ||
 455            (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg))
 456                return;
 457
 458        if (devpriv->use_double_buffer) {
 459                /* switch DMA buffers for next interrupt */
 460                devpriv->cur_dmabuf = !devpriv->cur_dmabuf;
 461                dmabuf = &devpriv->dmabuf[devpriv->cur_dmabuf];
 462                apci3120_init_dma(dev, dmabuf);
 463        } else {
 464                /* restart DMA if not using double buffering */
 465                apci3120_init_dma(dev, dmabuf);
 466        }
 467}
 468
 469static irqreturn_t apci3120_interrupt(int irq, void *d)
 470{
 471        struct comedi_device *dev = d;
 472        struct apci3120_private *devpriv = dev->private;
 473        struct comedi_subdevice *s = dev->read_subdev;
 474        struct comedi_async *async = s->async;
 475        struct comedi_cmd *cmd = &async->cmd;
 476        unsigned int status;
 477        unsigned int int_amcc;
 478
 479        status = inw(dev->iobase + APCI3120_STATUS_REG);
 480        int_amcc = inl(devpriv->amcc + AMCC_OP_REG_INTCSR);
 481
 482        if (!(status & APCI3120_STATUS_INT_MASK) &&
 483            !(int_amcc & ANY_S593X_INT)) {
 484                dev_err(dev->class_dev, "IRQ from unknown source\n");
 485                return IRQ_NONE;
 486        }
 487
 488        outl(int_amcc | AINT_INT_MASK, devpriv->amcc + AMCC_OP_REG_INTCSR);
 489
 490        if (devpriv->ctrl & APCI3120_CTRL_EXT_TRIG)
 491                apci3120_exttrig_enable(dev, false);
 492
 493        if (int_amcc & MASTER_ABORT_INT)
 494                dev_err(dev->class_dev, "AMCC IRQ - MASTER DMA ABORT!\n");
 495        if (int_amcc & TARGET_ABORT_INT)
 496                dev_err(dev->class_dev, "AMCC IRQ - TARGET DMA ABORT!\n");
 497
 498        if ((status & APCI3120_STATUS_EOS_INT) &&
 499            (devpriv->mode & APCI3120_MODE_EOS_IRQ_ENA)) {
 500                unsigned short val;
 501                int i;
 502
 503                for (i = 0; i < cmd->chanlist_len; i++) {
 504                        val = inw(dev->iobase + APCI3120_AI_FIFO_REG);
 505                        comedi_buf_write_samples(s, &val, 1);
 506                }
 507
 508                devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
 509                outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
 510        }
 511
 512        if (status & APCI3120_STATUS_TIMER2_INT) {
 513                /*
 514                 * for safety...
 515                 * timer2 interrupts are not enabled in the driver
 516                 */
 517                apci3120_clr_timer2_interrupt(dev);
 518        }
 519
 520        if (status & APCI3120_STATUS_AMCC_INT) {
 521                /* AMCC- Clear write complete interrupt (DMA) */
 522                outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
 523
 524                /* do some data transfer */
 525                apci3120_interrupt_dma(dev, s);
 526        }
 527
 528        if (cmd->stop_src == TRIG_COUNT && async->scans_done >= cmd->stop_arg)
 529                async->events |= COMEDI_CB_EOA;
 530
 531        comedi_handle_events(dev, s);
 532
 533        return IRQ_HANDLED;
 534}
 535
 536static int apci3120_ai_cmd(struct comedi_device *dev,
 537                           struct comedi_subdevice *s)
 538{
 539        struct apci3120_private *devpriv = dev->private;
 540        struct comedi_cmd *cmd = &s->async->cmd;
 541        unsigned int divisor;
 542
 543        /* set default mode bits */
 544        devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
 545                        APCI3120_MODE_TIMER2_AS_TIMER;
 546
 547        /* AMCC- Clear write complete interrupt (DMA) */
 548        outl(AINT_WT_COMPLETE, devpriv->amcc + AMCC_OP_REG_INTCSR);
 549
 550        devpriv->cur_dmabuf = 0;
 551
 552        /* load chanlist for command scan */
 553        apci3120_set_chanlist(dev, s, cmd->chanlist_len, cmd->chanlist);
 554
 555        if (cmd->start_src == TRIG_EXT)
 556                apci3120_exttrig_enable(dev, true);
 557
 558        if (cmd->scan_begin_src == TRIG_TIMER) {
 559                /*
 560                 * Timer 1 is used in MODE2 (rate generator) to set the
 561                 * start time for each scan.
 562                 */
 563                divisor = apci3120_ns_to_timer(dev, 1, cmd->scan_begin_arg,
 564                                               cmd->flags);
 565                apci3120_timer_set_mode(dev, 1, APCI3120_TIMER_MODE2);
 566                apci3120_timer_write(dev, 1, divisor);
 567        }
 568
 569        /*
 570         * Timer 0 is used in MODE2 (rate generator) to set the conversion
 571         * time for each acquisition.
 572         */
 573        divisor = apci3120_ns_to_timer(dev, 0, cmd->convert_arg, cmd->flags);
 574        apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE2);
 575        apci3120_timer_write(dev, 0, divisor);
 576
 577        if (devpriv->use_dma)
 578                apci3120_setup_dma(dev, s);
 579        else
 580                devpriv->mode |= APCI3120_MODE_EOS_IRQ_ENA;
 581
 582        /* set mode to enable acquisition */
 583        outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
 584
 585        if (cmd->scan_begin_src == TRIG_TIMER)
 586                apci3120_timer_enable(dev, 1, true);
 587        apci3120_timer_enable(dev, 0, true);
 588
 589        return 0;
 590}
 591
 592static int apci3120_ai_cmdtest(struct comedi_device *dev,
 593                               struct comedi_subdevice *s,
 594                               struct comedi_cmd *cmd)
 595{
 596        unsigned int arg;
 597        int err = 0;
 598
 599        /* Step 1 : check if triggers are trivially valid */
 600
 601        err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
 602        err |= comedi_check_trigger_src(&cmd->scan_begin_src,
 603                                        TRIG_TIMER | TRIG_FOLLOW);
 604        err |= comedi_check_trigger_src(&cmd->convert_src, TRIG_TIMER);
 605        err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 606        err |= comedi_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 607
 608        if (err)
 609                return 1;
 610
 611        /* Step 2a : make sure trigger sources are unique */
 612
 613        err |= comedi_check_trigger_is_unique(cmd->start_src);
 614        err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
 615        err |= comedi_check_trigger_is_unique(cmd->stop_src);
 616
 617        /* Step 2b : and mutually compatible */
 618
 619        if (err)
 620                return 2;
 621
 622        /* Step 3: check if arguments are trivially valid */
 623
 624        err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
 625
 626        if (cmd->scan_begin_src == TRIG_TIMER) {        /* Test Delay timing */
 627                err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg,
 628                                                    100000);
 629        }
 630
 631        /* minimum conversion time per sample is 10us */
 632        err |= comedi_check_trigger_arg_min(&cmd->convert_arg, 10000);
 633
 634        err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
 635        err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
 636                                           cmd->chanlist_len);
 637
 638        if (cmd->stop_src == TRIG_COUNT)
 639                err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
 640        else    /*  TRIG_NONE */
 641                err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
 642
 643        if (err)
 644                return 3;
 645
 646        /* Step 4: fix up any arguments */
 647
 648        if (cmd->scan_begin_src == TRIG_TIMER) {
 649                /* scan begin must be larger than the scan time */
 650                arg = cmd->convert_arg * cmd->scan_end_arg;
 651                err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
 652        }
 653
 654        if (err)
 655                return 4;
 656
 657        /* Step 5: check channel list if it exists */
 658
 659        return 0;
 660}
 661
 662static int apci3120_cancel(struct comedi_device *dev,
 663                           struct comedi_subdevice *s)
 664{
 665        struct apci3120_private *devpriv = dev->private;
 666
 667        /* Add-On - disable DMA */
 668        outw(0, devpriv->addon + 4);
 669
 670        /* Add-On - disable bus master */
 671        apci3120_addon_write(dev, 0, AMCC_OP_REG_AGCSTS);
 672
 673        /* AMCC - disable bus master */
 674        outl(0, devpriv->amcc + AMCC_OP_REG_MCSR);
 675
 676        /* disable all counters, ext trigger, and reset scan */
 677        devpriv->ctrl = 0;
 678        outw(devpriv->ctrl, dev->iobase + APCI3120_CTRL_REG);
 679
 680        /* DISABLE_ALL_INTERRUPT */
 681        devpriv->mode = 0;
 682        outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
 683
 684        inw(dev->iobase + APCI3120_STATUS_REG);
 685        devpriv->cur_dmabuf = 0;
 686
 687        return 0;
 688}
 689
 690static int apci3120_ai_eoc(struct comedi_device *dev,
 691                           struct comedi_subdevice *s,
 692                           struct comedi_insn *insn,
 693                           unsigned long context)
 694{
 695        unsigned int status;
 696
 697        status = inw(dev->iobase + APCI3120_STATUS_REG);
 698        if ((status & APCI3120_STATUS_EOC_INT) == 0)
 699                return 0;
 700        return -EBUSY;
 701}
 702
 703static int apci3120_ai_insn_read(struct comedi_device *dev,
 704                                 struct comedi_subdevice *s,
 705                                 struct comedi_insn *insn,
 706                                 unsigned int *data)
 707{
 708        struct apci3120_private *devpriv = dev->private;
 709        unsigned int divisor;
 710        int ret;
 711        int i;
 712
 713        /* set mode for A/D conversions by software trigger with timer 0 */
 714        devpriv->mode = APCI3120_MODE_TIMER2_CLK_OSC |
 715                        APCI3120_MODE_TIMER2_AS_TIMER;
 716        outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
 717
 718        /* load chanlist for single channel scan */
 719        apci3120_set_chanlist(dev, s, 1, &insn->chanspec);
 720
 721        /*
 722         * Timer 0 is used in MODE4 (software triggered strobe) to set the
 723         * conversion time for each acquisition. Each conversion is triggered
 724         * when the divisor is written to the timer, The conversion is done
 725         * when the EOC bit in the status register is '0'.
 726         */
 727        apci3120_timer_set_mode(dev, 0, APCI3120_TIMER_MODE4);
 728        apci3120_timer_enable(dev, 0, true);
 729
 730        /* fixed conversion time of 10 us */
 731        divisor = apci3120_ns_to_timer(dev, 0, 10000, CMDF_ROUND_NEAREST);
 732
 733        for (i = 0; i < insn->n; i++) {
 734                /* trigger conversion */
 735                apci3120_timer_write(dev, 0, divisor);
 736
 737                ret = comedi_timeout(dev, s, insn, apci3120_ai_eoc, 0);
 738                if (ret)
 739                        return ret;
 740
 741                data[i] = inw(dev->iobase + APCI3120_AI_FIFO_REG);
 742        }
 743
 744        return insn->n;
 745}
 746
 747static int apci3120_ao_ready(struct comedi_device *dev,
 748                             struct comedi_subdevice *s,
 749                             struct comedi_insn *insn,
 750                             unsigned long context)
 751{
 752        unsigned int status;
 753
 754        status = inw(dev->iobase + APCI3120_STATUS_REG);
 755        if (status & APCI3120_STATUS_DA_READY)
 756                return 0;
 757        return -EBUSY;
 758}
 759
 760static int apci3120_ao_insn_write(struct comedi_device *dev,
 761                                  struct comedi_subdevice *s,
 762                                  struct comedi_insn *insn,
 763                                  unsigned int *data)
 764{
 765        unsigned int chan = CR_CHAN(insn->chanspec);
 766        int i;
 767
 768        for (i = 0; i < insn->n; i++) {
 769                unsigned int val = data[i];
 770                int ret;
 771
 772                ret = comedi_timeout(dev, s, insn, apci3120_ao_ready, 0);
 773                if (ret)
 774                        return ret;
 775
 776                outw(APCI3120_AO_MUX(chan) | APCI3120_AO_DATA(val),
 777                     dev->iobase + APCI3120_AO_REG(chan));
 778
 779                s->readback[chan] = val;
 780        }
 781
 782        return insn->n;
 783}
 784
 785static int apci3120_di_insn_bits(struct comedi_device *dev,
 786                                 struct comedi_subdevice *s,
 787                                 struct comedi_insn *insn,
 788                                 unsigned int *data)
 789{
 790        unsigned int status;
 791
 792        status = inw(dev->iobase + APCI3120_STATUS_REG);
 793        data[1] = APCI3120_STATUS_TO_DI_BITS(status);
 794
 795        return insn->n;
 796}
 797
 798static int apci3120_do_insn_bits(struct comedi_device *dev,
 799                                 struct comedi_subdevice *s,
 800                                 struct comedi_insn *insn,
 801                                 unsigned int *data)
 802{
 803        struct apci3120_private *devpriv = dev->private;
 804
 805        if (comedi_dio_update_state(s, data)) {
 806                devpriv->do_bits = s->state;
 807                outb(APCI3120_CTR0_DO_BITS(devpriv->do_bits),
 808                     dev->iobase + APCI3120_CTR0_REG);
 809        }
 810
 811        data[1] = s->state;
 812
 813        return insn->n;
 814}
 815
 816static int apci3120_timer_insn_config(struct comedi_device *dev,
 817                                      struct comedi_subdevice *s,
 818                                      struct comedi_insn *insn,
 819                                      unsigned int *data)
 820{
 821        struct apci3120_private *devpriv = dev->private;
 822        unsigned int divisor;
 823        unsigned int status;
 824        unsigned int mode;
 825        unsigned int timer_mode;
 826
 827        switch (data[0]) {
 828        case INSN_CONFIG_ARM:
 829                apci3120_clr_timer2_interrupt(dev);
 830                divisor = apci3120_ns_to_timer(dev, 2, data[1],
 831                                               CMDF_ROUND_DOWN);
 832                apci3120_timer_write(dev, 2, divisor);
 833                apci3120_timer_enable(dev, 2, true);
 834                break;
 835
 836        case INSN_CONFIG_DISARM:
 837                apci3120_timer_enable(dev, 2, false);
 838                apci3120_clr_timer2_interrupt(dev);
 839                break;
 840
 841        case INSN_CONFIG_GET_COUNTER_STATUS:
 842                data[1] = 0;
 843                data[2] = COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING |
 844                          COMEDI_COUNTER_TERMINAL_COUNT;
 845
 846                if (devpriv->ctrl & APCI3120_CTRL_GATE(2)) {
 847                        data[1] |= COMEDI_COUNTER_ARMED;
 848                        data[1] |= COMEDI_COUNTER_COUNTING;
 849                }
 850                status = inw(dev->iobase + APCI3120_STATUS_REG);
 851                if (status & APCI3120_STATUS_TIMER2_INT) {
 852                        data[1] &= ~COMEDI_COUNTER_COUNTING;
 853                        data[1] |= COMEDI_COUNTER_TERMINAL_COUNT;
 854                }
 855                break;
 856
 857        case INSN_CONFIG_SET_COUNTER_MODE:
 858                switch (data[1]) {
 859                case I8254_MODE0:
 860                        mode = APCI3120_MODE_TIMER2_AS_COUNTER;
 861                        timer_mode = APCI3120_TIMER_MODE0;
 862                        break;
 863                case I8254_MODE2:
 864                        mode = APCI3120_MODE_TIMER2_AS_TIMER;
 865                        timer_mode = APCI3120_TIMER_MODE2;
 866                        break;
 867                case I8254_MODE4:
 868                        mode = APCI3120_MODE_TIMER2_AS_TIMER;
 869                        timer_mode = APCI3120_TIMER_MODE4;
 870                        break;
 871                case I8254_MODE5:
 872                        mode = APCI3120_MODE_TIMER2_AS_WDOG;
 873                        timer_mode = APCI3120_TIMER_MODE5;
 874                        break;
 875                default:
 876                        return -EINVAL;
 877                }
 878                apci3120_timer_enable(dev, 2, false);
 879                apci3120_clr_timer2_interrupt(dev);
 880                apci3120_timer_set_mode(dev, 2, timer_mode);
 881                devpriv->mode &= ~APCI3120_MODE_TIMER2_AS_MASK;
 882                devpriv->mode |= mode;
 883                outb(devpriv->mode, dev->iobase + APCI3120_MODE_REG);
 884                break;
 885
 886        default:
 887                return -EINVAL;
 888        }
 889
 890        return insn->n;
 891}
 892
 893static int apci3120_timer_insn_read(struct comedi_device *dev,
 894                                    struct comedi_subdevice *s,
 895                                    struct comedi_insn *insn,
 896                                    unsigned int *data)
 897{
 898        int i;
 899
 900        for (i = 0; i < insn->n; i++)
 901                data[i] = apci3120_timer_read(dev, 2);
 902
 903        return insn->n;
 904}
 905
 906static void apci3120_dma_alloc(struct comedi_device *dev)
 907{
 908        struct apci3120_private *devpriv = dev->private;
 909        struct apci3120_dmabuf *dmabuf;
 910        int order;
 911        int i;
 912
 913        for (i = 0; i < 2; i++) {
 914                dmabuf = &devpriv->dmabuf[i];
 915                for (order = 2; order >= 0; order--) {
 916                        dmabuf->virt = dma_alloc_coherent(dev->hw_dev,
 917                                                          PAGE_SIZE << order,
 918                                                          &dmabuf->hw,
 919                                                          GFP_KERNEL);
 920                        if (dmabuf->virt)
 921                                break;
 922                }
 923                if (!dmabuf->virt)
 924                        break;
 925                dmabuf->size = PAGE_SIZE << order;
 926
 927                if (i == 0)
 928                        devpriv->use_dma = 1;
 929                if (i == 1)
 930                        devpriv->use_double_buffer = 1;
 931        }
 932}
 933
 934static void apci3120_dma_free(struct comedi_device *dev)
 935{
 936        struct apci3120_private *devpriv = dev->private;
 937        struct apci3120_dmabuf *dmabuf;
 938        int i;
 939
 940        if (!devpriv)
 941                return;
 942
 943        for (i = 0; i < 2; i++) {
 944                dmabuf = &devpriv->dmabuf[i];
 945                if (dmabuf->virt) {
 946                        dma_free_coherent(dev->hw_dev, dmabuf->size,
 947                                          dmabuf->virt, dmabuf->hw);
 948                }
 949        }
 950}
 951
 952static void apci3120_reset(struct comedi_device *dev)
 953{
 954        /* disable all interrupt sources */
 955        outb(0, dev->iobase + APCI3120_MODE_REG);
 956
 957        /* disable all counters, ext trigger, and reset scan */
 958        outw(0, dev->iobase + APCI3120_CTRL_REG);
 959
 960        /* clear interrupt status */
 961        inw(dev->iobase + APCI3120_STATUS_REG);
 962}
 963
 964static int apci3120_auto_attach(struct comedi_device *dev,
 965                                unsigned long context)
 966{
 967        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 968        const struct apci3120_board *board = NULL;
 969        struct apci3120_private *devpriv;
 970        struct comedi_subdevice *s;
 971        unsigned int status;
 972        int ret;
 973
 974        if (context < ARRAY_SIZE(apci3120_boardtypes))
 975                board = &apci3120_boardtypes[context];
 976        if (!board)
 977                return -ENODEV;
 978        dev->board_ptr = board;
 979        dev->board_name = board->name;
 980
 981        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 982        if (!devpriv)
 983                return -ENOMEM;
 984
 985        ret = comedi_pci_enable(dev);
 986        if (ret)
 987                return ret;
 988        pci_set_master(pcidev);
 989
 990        dev->iobase = pci_resource_start(pcidev, 1);
 991        devpriv->amcc = pci_resource_start(pcidev, 0);
 992        devpriv->addon = pci_resource_start(pcidev, 2);
 993
 994        apci3120_reset(dev);
 995
 996        if (pcidev->irq > 0) {
 997                ret = request_irq(pcidev->irq, apci3120_interrupt, IRQF_SHARED,
 998                                  dev->board_name, dev);
 999                if (ret == 0) {
1000                        dev->irq = pcidev->irq;
1001
1002                        apci3120_dma_alloc(dev);
1003                }
1004        }
1005
1006        status = inw(dev->iobase + APCI3120_STATUS_REG);
1007        if (APCI3120_STATUS_TO_VERSION(status) == APCI3120_REVB ||
1008            context == BOARD_APCI3001)
1009                devpriv->osc_base = APCI3120_REVB_OSC_BASE;
1010        else
1011                devpriv->osc_base = APCI3120_REVA_OSC_BASE;
1012
1013        ret = comedi_alloc_subdevices(dev, 5);
1014        if (ret)
1015                return ret;
1016
1017        /* Analog Input subdevice */
1018        s = &dev->subdevices[0];
1019        s->type         = COMEDI_SUBD_AI;
1020        s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
1021        s->n_chan       = 16;
1022        s->maxdata      = board->ai_is_16bit ? 0xffff : 0x0fff;
1023        s->range_table  = &apci3120_ai_range;
1024        s->insn_read    = apci3120_ai_insn_read;
1025        if (dev->irq) {
1026                dev->read_subdev = s;
1027                s->subdev_flags |= SDF_CMD_READ;
1028                s->len_chanlist = s->n_chan;
1029                s->do_cmdtest   = apci3120_ai_cmdtest;
1030                s->do_cmd       = apci3120_ai_cmd;
1031                s->cancel       = apci3120_cancel;
1032        }
1033
1034        /* Analog Output subdevice */
1035        s = &dev->subdevices[1];
1036        if (board->has_ao) {
1037                s->type         = COMEDI_SUBD_AO;
1038                s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
1039                s->n_chan       = 8;
1040                s->maxdata      = 0x3fff;
1041                s->range_table  = &range_bipolar10;
1042                s->insn_write   = apci3120_ao_insn_write;
1043
1044                ret = comedi_alloc_subdev_readback(s);
1045                if (ret)
1046                        return ret;
1047        } else {
1048                s->type         = COMEDI_SUBD_UNUSED;
1049        }
1050
1051        /* Digital Input subdevice */
1052        s = &dev->subdevices[2];
1053        s->type         = COMEDI_SUBD_DI;
1054        s->subdev_flags = SDF_READABLE;
1055        s->n_chan       = 4;
1056        s->maxdata      = 1;
1057        s->range_table  = &range_digital;
1058        s->insn_bits    = apci3120_di_insn_bits;
1059
1060        /* Digital Output subdevice */
1061        s = &dev->subdevices[3];
1062        s->type         = COMEDI_SUBD_DO;
1063        s->subdev_flags = SDF_WRITABLE;
1064        s->n_chan       = 4;
1065        s->maxdata      = 1;
1066        s->range_table  = &range_digital;
1067        s->insn_bits    = apci3120_do_insn_bits;
1068
1069        /* Timer subdevice */
1070        s = &dev->subdevices[4];
1071        s->type         = COMEDI_SUBD_TIMER;
1072        s->subdev_flags = SDF_READABLE;
1073        s->n_chan       = 1;
1074        s->maxdata      = 0x00ffffff;
1075        s->insn_config  = apci3120_timer_insn_config;
1076        s->insn_read    = apci3120_timer_insn_read;
1077
1078        return 0;
1079}
1080
1081static void apci3120_detach(struct comedi_device *dev)
1082{
1083        comedi_pci_detach(dev);
1084        apci3120_dma_free(dev);
1085}
1086
1087static struct comedi_driver apci3120_driver = {
1088        .driver_name    = "addi_apci_3120",
1089        .module         = THIS_MODULE,
1090        .auto_attach    = apci3120_auto_attach,
1091        .detach         = apci3120_detach,
1092};
1093
1094static int apci3120_pci_probe(struct pci_dev *dev,
1095                              const struct pci_device_id *id)
1096{
1097        return comedi_pci_auto_config(dev, &apci3120_driver, id->driver_data);
1098}
1099
1100static const struct pci_device_id apci3120_pci_table[] = {
1101        { PCI_VDEVICE(AMCC, 0x818d), BOARD_APCI3120 },
1102        { PCI_VDEVICE(AMCC, 0x828d), BOARD_APCI3001 },
1103        { 0 }
1104};
1105MODULE_DEVICE_TABLE(pci, apci3120_pci_table);
1106
1107static struct pci_driver apci3120_pci_driver = {
1108        .name           = "addi_apci_3120",
1109        .id_table       = apci3120_pci_table,
1110        .probe          = apci3120_pci_probe,
1111        .remove         = comedi_pci_auto_unconfig,
1112};
1113module_comedi_pci_driver(apci3120_driver, apci3120_pci_driver);
1114
1115MODULE_AUTHOR("Comedi https://www.comedi.org");
1116MODULE_DESCRIPTION("ADDI-DATA APCI-3120, Analog input board");
1117MODULE_LICENSE("GPL");
1118