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