linux/drivers/staging/comedi/drivers/rtd520.c
<<
>>
Prefs
   1/*
   2 * comedi/drivers/rtd520.c
   3 * Comedi driver for Real Time Devices (RTD) PCI4520/DM7520
   4 *
   5 * COMEDI - Linux Control and Measurement Device Interface
   6 * Copyright (C) 2001 David A. Schleef <ds@schleef.org>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; either version 2 of the License, or
  11 * (at your option) any later version.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16 * GNU General Public License for more details.
  17 */
  18
  19/*
  20 * Driver: rtd520
  21 * Description: Real Time Devices PCI4520/DM7520
  22 * Devices: (Real Time Devices) DM7520HR-1 [DM7520]
  23 *          (Real Time Devices) DM7520HR-8 [DM7520]
  24 *          (Real Time Devices) PCI4520 [PCI4520]
  25 *          (Real Time Devices) PCI4520-8 [PCI4520]
  26 * Author: Dan Christian
  27 * Status: Works. Only tested on DM7520-8. Not SMP safe.
  28 *
  29 * Configuration options: not applicable, uses PCI auto config
  30 */
  31
  32/*
  33 * Created by Dan Christian, NASA Ames Research Center.
  34 *
  35 * The PCI4520 is a PCI card. The DM7520 is a PC/104-plus card.
  36 * Both have:
  37 *   8/16 12 bit ADC with FIFO and channel gain table
  38 *   8 bits high speed digital out (for external MUX) (or 8 in or 8 out)
  39 *   8 bits high speed digital in with FIFO and interrupt on change (or 8 IO)
  40 *   2 12 bit DACs with FIFOs
  41 *   2 bits output
  42 *   2 bits input
  43 *   bus mastering DMA
  44 *   timers: ADC sample, pacer, burst, about, delay, DA1, DA2
  45 *   sample counter
  46 *   3 user timer/counters (8254)
  47 *   external interrupt
  48 *
  49 * The DM7520 has slightly fewer features (fewer gain steps).
  50 *
  51 * These boards can support external multiplexors and multi-board
  52 * synchronization, but this driver doesn't support that.
  53 *
  54 * Board docs: http://www.rtdusa.com/PC104/DM/analog%20IO/dm7520.htm
  55 * Data sheet: http://www.rtdusa.com/pdf/dm7520.pdf
  56 * Example source: http://www.rtdusa.com/examples/dm/dm7520.zip
  57 * Call them and ask for the register level manual.
  58 * PCI chip: http://www.plxtech.com/products/io/pci9080
  59 *
  60 * Notes:
  61 * This board is memory mapped. There is some IO stuff, but it isn't needed.
  62 *
  63 * I use a pretty loose naming style within the driver (rtd_blah).
  64 * All externally visible names should be rtd520_blah.
  65 * I use camelCase for structures (and inside them).
  66 * I may also use upper CamelCase for function names (old habit).
  67 *
  68 * This board is somewhat related to the RTD PCI4400 board.
  69 *
  70 * I borrowed heavily from the ni_mio_common, ni_atmio16d, mite, and
  71 * das1800, since they have the best documented code. Driver cb_pcidas64.c
  72 * uses the same DMA controller.
  73 *
  74 * As far as I can tell, the About interrupt doesn't work if Sample is
  75 * also enabled. It turns out that About really isn't needed, since
  76 * we always count down samples read.
  77 *
  78 * There was some timer/counter code, but it didn't follow the right API.
  79 */
  80
  81/*
  82 * driver status:
  83 *
  84 * Analog-In supports instruction and command mode.
  85 *
  86 * With DMA, you can sample at 1.15Mhz with 70% idle on a 400Mhz K6-2
  87 * (single channel, 64K read buffer). I get random system lockups when
  88 * using DMA with ALI-15xx based systems. I haven't been able to test
  89 * any other chipsets. The lockups happen soon after the start of an
  90 * acquistion, not in the middle of a long run.
  91 *
  92 * Without DMA, you can do 620Khz sampling with 20% idle on a 400Mhz K6-2
  93 * (with a 256K read buffer).
  94 *
  95 * Digital-IO and Analog-Out only support instruction mode.
  96 */
  97
  98#include <linux/module.h>
  99#include <linux/pci.h>
 100#include <linux/delay.h>
 101#include <linux/interrupt.h>
 102
 103#include "../comedidev.h"
 104
 105#include "comedi_fc.h"
 106#include "plx9080.h"
 107
 108/*
 109 * Local Address Space 0 Offsets
 110 */
 111#define LAS0_USER_IO            0x0008  /* User I/O */
 112#define LAS0_ADC                0x0010  /* FIFO Status/Software A/D Start */
 113#define FS_DAC1_NOT_EMPTY       (1 << 0)        /* DAC1 FIFO not empty */
 114#define FS_DAC1_HEMPTY          (1 << 1)        /* DAC1 FIFO half empty */
 115#define FS_DAC1_NOT_FULL        (1 << 2)        /* DAC1 FIFO not full */
 116#define FS_DAC2_NOT_EMPTY       (1 << 4)        /* DAC2 FIFO not empty */
 117#define FS_DAC2_HEMPTY          (1 << 5)        /* DAC2 FIFO half empty */
 118#define FS_DAC2_NOT_FULL        (1 << 6)        /* DAC2 FIFO not full */
 119#define FS_ADC_NOT_EMPTY        (1 << 8)        /* ADC FIFO not empty */
 120#define FS_ADC_HEMPTY           (1 << 9)        /* ADC FIFO half empty */
 121#define FS_ADC_NOT_FULL         (1 << 10)       /* ADC FIFO not full */
 122#define FS_DIN_NOT_EMPTY        (1 << 12)       /* DIN FIFO not empty */
 123#define FS_DIN_HEMPTY           (1 << 13)       /* DIN FIFO half empty */
 124#define FS_DIN_NOT_FULL         (1 << 14)       /* DIN FIFO not full */
 125#define LAS0_DAC1               0x0014  /* Software D/A1 Update (w) */
 126#define LAS0_DAC2               0x0018  /* Software D/A2 Update (w) */
 127#define LAS0_DAC                0x0024  /* Software Simultaneous Update (w) */
 128#define LAS0_PACER              0x0028  /* Software Pacer Start/Stop */
 129#define LAS0_TIMER              0x002c  /* Timer Status/HDIN Software Trig. */
 130#define LAS0_IT                 0x0030  /* Interrupt Status/Enable */
 131#define IRQM_ADC_FIFO_WRITE     (1 << 0)        /* ADC FIFO Write */
 132#define IRQM_CGT_RESET          (1 << 1)        /* Reset CGT */
 133#define IRQM_CGT_PAUSE          (1 << 3)        /* Pause CGT */
 134#define IRQM_ADC_ABOUT_CNT      (1 << 4)        /* About Counter out */
 135#define IRQM_ADC_DELAY_CNT      (1 << 5)        /* Delay Counter out */
 136#define IRQM_ADC_SAMPLE_CNT     (1 << 6)        /* ADC Sample Counter */
 137#define IRQM_DAC1_UCNT          (1 << 7)        /* DAC1 Update Counter */
 138#define IRQM_DAC2_UCNT          (1 << 8)        /* DAC2 Update Counter */
 139#define IRQM_UTC1               (1 << 9)        /* User TC1 out */
 140#define IRQM_UTC1_INV           (1 << 10)       /* User TC1 out, inverted */
 141#define IRQM_UTC2               (1 << 11)       /* User TC2 out */
 142#define IRQM_DIGITAL_IT         (1 << 12)       /* Digital Interrupt */
 143#define IRQM_EXTERNAL_IT        (1 << 13)       /* External Interrupt */
 144#define IRQM_ETRIG_RISING       (1 << 14)       /* Ext Trigger rising-edge */
 145#define IRQM_ETRIG_FALLING      (1 << 15)       /* Ext Trigger falling-edge */
 146#define LAS0_CLEAR              0x0034  /* Clear/Set Interrupt Clear Mask */
 147#define LAS0_OVERRUN            0x0038  /* Pending interrupts/Clear Overrun */
 148#define LAS0_PCLK               0x0040  /* Pacer Clock (24bit) */
 149#define LAS0_BCLK               0x0044  /* Burst Clock (10bit) */
 150#define LAS0_ADC_SCNT           0x0048  /* A/D Sample counter (10bit) */
 151#define LAS0_DAC1_UCNT          0x004c  /* D/A1 Update counter (10 bit) */
 152#define LAS0_DAC2_UCNT          0x0050  /* D/A2 Update counter (10 bit) */
 153#define LAS0_DCNT               0x0054  /* Delay counter (16 bit) */
 154#define LAS0_ACNT               0x0058  /* About counter (16 bit) */
 155#define LAS0_DAC_CLK            0x005c  /* DAC clock (16bit) */
 156#define LAS0_UTC0               0x0060  /* 8254 TC Counter 0 */
 157#define LAS0_UTC1               0x0064  /* 8254 TC Counter 1 */
 158#define LAS0_UTC2               0x0068  /* 8254 TC Counter 2 */
 159#define LAS0_UTC_CTRL           0x006c  /* 8254 TC Control */
 160#define LAS0_DIO0               0x0070  /* Digital I/O Port 0 */
 161#define LAS0_DIO1               0x0074  /* Digital I/O Port 1 */
 162#define LAS0_DIO0_CTRL          0x0078  /* Digital I/O Control */
 163#define LAS0_DIO_STATUS         0x007c  /* Digital I/O Status */
 164#define LAS0_BOARD_RESET        0x0100  /* Board reset */
 165#define LAS0_DMA0_SRC           0x0104  /* DMA 0 Sources select */
 166#define LAS0_DMA1_SRC           0x0108  /* DMA 1 Sources select */
 167#define LAS0_ADC_CONVERSION     0x010c  /* A/D Conversion Signal select */
 168#define LAS0_BURST_START        0x0110  /* Burst Clock Start Trigger select */
 169#define LAS0_PACER_START        0x0114  /* Pacer Clock Start Trigger select */
 170#define LAS0_PACER_STOP         0x0118  /* Pacer Clock Stop Trigger select */
 171#define LAS0_ACNT_STOP_ENABLE   0x011c  /* About Counter Stop Enable */
 172#define LAS0_PACER_REPEAT       0x0120  /* Pacer Start Trigger Mode select */
 173#define LAS0_DIN_START          0x0124  /* HiSpd DI Sampling Signal select */
 174#define LAS0_DIN_FIFO_CLEAR     0x0128  /* Digital Input FIFO Clear */
 175#define LAS0_ADC_FIFO_CLEAR     0x012c  /* A/D FIFO Clear */
 176#define LAS0_CGT_WRITE          0x0130  /* Channel Gain Table Write */
 177#define LAS0_CGL_WRITE          0x0134  /* Channel Gain Latch Write */
 178#define LAS0_CG_DATA            0x0138  /* Digital Table Write */
 179#define LAS0_CGT_ENABLE         0x013c  /* Channel Gain Table Enable */
 180#define LAS0_CG_ENABLE          0x0140  /* Digital Table Enable */
 181#define LAS0_CGT_PAUSE          0x0144  /* Table Pause Enable */
 182#define LAS0_CGT_RESET          0x0148  /* Reset Channel Gain Table */
 183#define LAS0_CGT_CLEAR          0x014c  /* Clear Channel Gain Table */
 184#define LAS0_DAC1_CTRL          0x0150  /* D/A1 output type/range */
 185#define LAS0_DAC1_SRC           0x0154  /* D/A1 update source */
 186#define LAS0_DAC1_CYCLE         0x0158  /* D/A1 cycle mode */
 187#define LAS0_DAC1_RESET         0x015c  /* D/A1 FIFO reset */
 188#define LAS0_DAC1_FIFO_CLEAR    0x0160  /* D/A1 FIFO clear */
 189#define LAS0_DAC2_CTRL          0x0164  /* D/A2 output type/range */
 190#define LAS0_DAC2_SRC           0x0168  /* D/A2 update source */
 191#define LAS0_DAC2_CYCLE         0x016c  /* D/A2 cycle mode */
 192#define LAS0_DAC2_RESET         0x0170  /* D/A2 FIFO reset */
 193#define LAS0_DAC2_FIFO_CLEAR    0x0174  /* D/A2 FIFO clear */
 194#define LAS0_ADC_SCNT_SRC       0x0178  /* A/D Sample Counter Source select */
 195#define LAS0_PACER_SELECT       0x0180  /* Pacer Clock select */
 196#define LAS0_SBUS0_SRC          0x0184  /* SyncBus 0 Source select */
 197#define LAS0_SBUS0_ENABLE       0x0188  /* SyncBus 0 enable */
 198#define LAS0_SBUS1_SRC          0x018c  /* SyncBus 1 Source select */
 199#define LAS0_SBUS1_ENABLE       0x0190  /* SyncBus 1 enable */
 200#define LAS0_SBUS2_SRC          0x0198  /* SyncBus 2 Source select */
 201#define LAS0_SBUS2_ENABLE       0x019c  /* SyncBus 2 enable */
 202#define LAS0_ETRG_POLARITY      0x01a4  /* Ext. Trigger polarity select */
 203#define LAS0_EINT_POLARITY      0x01a8  /* Ext. Interrupt polarity select */
 204#define LAS0_UTC0_CLOCK         0x01ac  /* UTC0 Clock select */
 205#define LAS0_UTC0_GATE          0x01b0  /* UTC0 Gate select */
 206#define LAS0_UTC1_CLOCK         0x01b4  /* UTC1 Clock select */
 207#define LAS0_UTC1_GATE          0x01b8  /* UTC1 Gate select */
 208#define LAS0_UTC2_CLOCK         0x01bc  /* UTC2 Clock select */
 209#define LAS0_UTC2_GATE          0x01c0  /* UTC2 Gate select */
 210#define LAS0_UOUT0_SELECT       0x01c4  /* User Output 0 source select */
 211#define LAS0_UOUT1_SELECT       0x01c8  /* User Output 1 source select */
 212#define LAS0_DMA0_RESET         0x01cc  /* DMA0 Request state machine reset */
 213#define LAS0_DMA1_RESET         0x01d0  /* DMA1 Request state machine reset */
 214
 215/*
 216 * Local Address Space 1 Offsets
 217 */
 218#define LAS1_ADC_FIFO           0x0000  /* A/D FIFO (16bit) */
 219#define LAS1_HDIO_FIFO          0x0004  /* HiSpd DI FIFO (16bit) */
 220#define LAS1_DAC1_FIFO          0x0008  /* D/A1 FIFO (16bit) */
 221#define LAS1_DAC2_FIFO          0x000c  /* D/A2 FIFO (16bit) */
 222
 223/*======================================================================
 224  Driver specific stuff (tunable)
 225======================================================================*/
 226
 227/* We really only need 2 buffers.  More than that means being much
 228   smarter about knowing which ones are full. */
 229#define DMA_CHAIN_COUNT 2       /* max DMA segments/buffers in a ring (min 2) */
 230
 231/* Target period for periodic transfers.  This sets the user read latency. */
 232/* Note: There are certain rates where we give this up and transfer 1/2 FIFO */
 233/* If this is too low, efficiency is poor */
 234#define TRANS_TARGET_PERIOD 10000000    /* 10 ms (in nanoseconds) */
 235
 236/* Set a practical limit on how long a list to support (affects memory use) */
 237/* The board support a channel list up to the FIFO length (1K or 8K) */
 238#define RTD_MAX_CHANLIST        128     /* max channel list that we allow */
 239
 240/* tuning for ai/ao instruction done polling */
 241#ifdef FAST_SPIN
 242#define WAIT_QUIETLY            /* as nothing, spin on done bit */
 243#define RTD_ADC_TIMEOUT 66000   /* 2 msec at 33mhz bus rate */
 244#define RTD_DAC_TIMEOUT 66000
 245#define RTD_DMA_TIMEOUT 33000   /* 1 msec */
 246#else
 247/* by delaying, power and electrical noise are reduced somewhat */
 248#define WAIT_QUIETLY    udelay(1)
 249#define RTD_ADC_TIMEOUT 2000    /* in usec */
 250#define RTD_DAC_TIMEOUT 2000    /* in usec */
 251#define RTD_DMA_TIMEOUT 1000    /* in usec */
 252#endif
 253
 254/*======================================================================
 255  Board specific stuff
 256======================================================================*/
 257
 258#define RTD_CLOCK_RATE  8000000 /* 8Mhz onboard clock */
 259#define RTD_CLOCK_BASE  125     /* clock period in ns */
 260
 261/* Note: these speed are slower than the spec, but fit the counter resolution*/
 262#define RTD_MAX_SPEED   1625    /* when sampling, in nanoseconds */
 263/* max speed if we don't have to wait for settling */
 264#define RTD_MAX_SPEED_1 875     /* if single channel, in nanoseconds */
 265
 266#define RTD_MIN_SPEED   2097151875      /* (24bit counter) in nanoseconds */
 267/* min speed when only 1 channel (no burst counter) */
 268#define RTD_MIN_SPEED_1 5000000 /* 200Hz, in nanoseconds */
 269
 270/* Setup continuous ring of 1/2 FIFO transfers.  See RTD manual p91 */
 271#define DMA_MODE_BITS (\
 272                       PLX_LOCAL_BUS_16_WIDE_BITS \
 273                       | PLX_DMA_EN_READYIN_BIT \
 274                       | PLX_DMA_LOCAL_BURST_EN_BIT \
 275                       | PLX_EN_CHAIN_BIT \
 276                       | PLX_DMA_INTR_PCI_BIT \
 277                       | PLX_LOCAL_ADDR_CONST_BIT \
 278                       | PLX_DEMAND_MODE_BIT)
 279
 280#define DMA_TRANSFER_BITS (\
 281/* descriptors in PCI memory*/  PLX_DESC_IN_PCI_BIT \
 282/* interrupt at end of block */ | PLX_INTR_TERM_COUNT \
 283/* from board to PCI */         | PLX_XFER_LOCAL_TO_PCI)
 284
 285/*======================================================================
 286  Comedi specific stuff
 287======================================================================*/
 288
 289/*
 290 * The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
 291 */
 292static const struct comedi_lrange rtd_ai_7520_range = {
 293        18, {
 294                /* +-5V input range gain steps */
 295                BIP_RANGE(5.0),
 296                BIP_RANGE(5.0 / 2),
 297                BIP_RANGE(5.0 / 4),
 298                BIP_RANGE(5.0 / 8),
 299                BIP_RANGE(5.0 / 16),
 300                BIP_RANGE(5.0 / 32),
 301                /* +-10V input range gain steps */
 302                BIP_RANGE(10.0),
 303                BIP_RANGE(10.0 / 2),
 304                BIP_RANGE(10.0 / 4),
 305                BIP_RANGE(10.0 / 8),
 306                BIP_RANGE(10.0 / 16),
 307                BIP_RANGE(10.0 / 32),
 308                /* +10V input range gain steps */
 309                UNI_RANGE(10.0),
 310                UNI_RANGE(10.0 / 2),
 311                UNI_RANGE(10.0 / 4),
 312                UNI_RANGE(10.0 / 8),
 313                UNI_RANGE(10.0 / 16),
 314                UNI_RANGE(10.0 / 32),
 315        }
 316};
 317
 318/* PCI4520 has two more gains (6 more entries) */
 319static const struct comedi_lrange rtd_ai_4520_range = {
 320        24, {
 321                /* +-5V input range gain steps */
 322                BIP_RANGE(5.0),
 323                BIP_RANGE(5.0 / 2),
 324                BIP_RANGE(5.0 / 4),
 325                BIP_RANGE(5.0 / 8),
 326                BIP_RANGE(5.0 / 16),
 327                BIP_RANGE(5.0 / 32),
 328                BIP_RANGE(5.0 / 64),
 329                BIP_RANGE(5.0 / 128),
 330                /* +-10V input range gain steps */
 331                BIP_RANGE(10.0),
 332                BIP_RANGE(10.0 / 2),
 333                BIP_RANGE(10.0 / 4),
 334                BIP_RANGE(10.0 / 8),
 335                BIP_RANGE(10.0 / 16),
 336                BIP_RANGE(10.0 / 32),
 337                BIP_RANGE(10.0 / 64),
 338                BIP_RANGE(10.0 / 128),
 339                /* +10V input range gain steps */
 340                UNI_RANGE(10.0),
 341                UNI_RANGE(10.0 / 2),
 342                UNI_RANGE(10.0 / 4),
 343                UNI_RANGE(10.0 / 8),
 344                UNI_RANGE(10.0 / 16),
 345                UNI_RANGE(10.0 / 32),
 346                UNI_RANGE(10.0 / 64),
 347                UNI_RANGE(10.0 / 128),
 348        }
 349};
 350
 351/* Table order matches range values */
 352static const struct comedi_lrange rtd_ao_range = {
 353        4, {
 354                UNI_RANGE(5),
 355                UNI_RANGE(10),
 356                BIP_RANGE(5),
 357                BIP_RANGE(10),
 358        }
 359};
 360
 361enum rtd_boardid {
 362        BOARD_DM7520,
 363        BOARD_PCI4520,
 364};
 365
 366struct rtd_boardinfo {
 367        const char *name;
 368        int range_bip10;        /* start of +-10V range */
 369        int range_uni10;        /* start of +10V range */
 370        const struct comedi_lrange *ai_range;
 371};
 372
 373static const struct rtd_boardinfo rtd520Boards[] = {
 374        [BOARD_DM7520] = {
 375                .name           = "DM7520",
 376                .range_bip10    = 6,
 377                .range_uni10    = 12,
 378                .ai_range       = &rtd_ai_7520_range,
 379        },
 380        [BOARD_PCI4520] = {
 381                .name           = "PCI4520",
 382                .range_bip10    = 8,
 383                .range_uni10    = 16,
 384                .ai_range       = &rtd_ai_4520_range,
 385        },
 386};
 387
 388struct rtd_private {
 389        /* memory mapped board structures */
 390        void __iomem *las0;
 391        void __iomem *las1;
 392        void __iomem *lcfg;
 393
 394        long ai_count;          /* total transfer size (samples) */
 395        int xfer_count;         /* # to transfer data. 0->1/2FIFO */
 396        int flags;              /* flag event modes */
 397
 398        unsigned char chan_is_bipolar[RTD_MAX_CHANLIST / 8];    /* bit array */
 399
 400        unsigned int ao_readback[2];
 401
 402        unsigned fifosz;
 403};
 404
 405/* bit defines for "flags" */
 406#define SEND_EOS        0x01    /* send End Of Scan events */
 407#define DMA0_ACTIVE     0x02    /* DMA0 is active */
 408#define DMA1_ACTIVE     0x04    /* DMA1 is active */
 409
 410/* Macros for accessing channel list bit array */
 411#define CHAN_ARRAY_TEST(array, index) \
 412        (((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
 413#define CHAN_ARRAY_SET(array, index) \
 414        (((array)[(index)/8] |= 1 << ((index) & 0x7)))
 415#define CHAN_ARRAY_CLEAR(array, index) \
 416        (((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
 417
 418/*
 419  Given a desired period and the clock period (both in ns),
 420  return the proper counter value (divider-1).
 421  Sets the original period to be the true value.
 422  Note: you have to check if the value is larger than the counter range!
 423*/
 424static int rtd_ns_to_timer_base(unsigned int *nanosec,
 425                                int round_mode, int base)
 426{
 427        int divider;
 428
 429        switch (round_mode) {
 430        case TRIG_ROUND_NEAREST:
 431        default:
 432                divider = (*nanosec + base / 2) / base;
 433                break;
 434        case TRIG_ROUND_DOWN:
 435                divider = (*nanosec) / base;
 436                break;
 437        case TRIG_ROUND_UP:
 438                divider = (*nanosec + base - 1) / base;
 439                break;
 440        }
 441        if (divider < 2)
 442                divider = 2;    /* min is divide by 2 */
 443
 444        /* Note: we don't check for max, because different timers
 445           have different ranges */
 446
 447        *nanosec = base * divider;
 448        return divider - 1;     /* countdown is divisor+1 */
 449}
 450
 451/*
 452  Given a desired period (in ns),
 453  return the proper counter value (divider-1) for the internal clock.
 454  Sets the original period to be the true value.
 455*/
 456static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
 457{
 458        return rtd_ns_to_timer_base(ns, round_mode, RTD_CLOCK_BASE);
 459}
 460
 461/*
 462  Convert a single comedi channel-gain entry to a RTD520 table entry
 463*/
 464static unsigned short rtd_convert_chan_gain(struct comedi_device *dev,
 465                                            unsigned int chanspec, int index)
 466{
 467        const struct rtd_boardinfo *board = comedi_board(dev);
 468        struct rtd_private *devpriv = dev->private;
 469        unsigned int chan = CR_CHAN(chanspec);
 470        unsigned int range = CR_RANGE(chanspec);
 471        unsigned int aref = CR_AREF(chanspec);
 472        unsigned short r = 0;
 473
 474        r |= chan & 0xf;
 475
 476        /* Note: we also setup the channel list bipolar flag array */
 477        if (range < board->range_bip10) {
 478                /* +-5 range */
 479                r |= 0x000;
 480                r |= (range & 0x7) << 4;
 481                CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
 482        } else if (range < board->range_uni10) {
 483                /* +-10 range */
 484                r |= 0x100;
 485                r |= ((range - board->range_bip10) & 0x7) << 4;
 486                CHAN_ARRAY_SET(devpriv->chan_is_bipolar, index);
 487        } else {
 488                /* +10 range */
 489                r |= 0x200;
 490                r |= ((range - board->range_uni10) & 0x7) << 4;
 491                CHAN_ARRAY_CLEAR(devpriv->chan_is_bipolar, index);
 492        }
 493
 494        switch (aref) {
 495        case AREF_GROUND:       /* on-board ground */
 496                break;
 497
 498        case AREF_COMMON:
 499                r |= 0x80;      /* ref external analog common */
 500                break;
 501
 502        case AREF_DIFF:
 503                r |= 0x400;     /* differential inputs */
 504                break;
 505
 506        case AREF_OTHER:        /* ??? */
 507                break;
 508        }
 509        /*printk ("chan=%d r=%d a=%d -> 0x%x\n",
 510           chan, range, aref, r); */
 511        return r;
 512}
 513
 514/*
 515  Setup the channel-gain table from a comedi list
 516*/
 517static void rtd_load_channelgain_list(struct comedi_device *dev,
 518                                      unsigned int n_chan, unsigned int *list)
 519{
 520        struct rtd_private *devpriv = dev->private;
 521
 522        if (n_chan > 1) {       /* setup channel gain table */
 523                int ii;
 524
 525                writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
 526                writel(1, devpriv->las0 + LAS0_CGT_ENABLE);
 527                for (ii = 0; ii < n_chan; ii++) {
 528                        writel(rtd_convert_chan_gain(dev, list[ii], ii),
 529                                devpriv->las0 + LAS0_CGT_WRITE);
 530                }
 531        } else {                /* just use the channel gain latch */
 532                writel(0, devpriv->las0 + LAS0_CGT_ENABLE);
 533                writel(rtd_convert_chan_gain(dev, list[0], 0),
 534                        devpriv->las0 + LAS0_CGL_WRITE);
 535        }
 536}
 537
 538/* determine fifo size by doing adc conversions until the fifo half
 539empty status flag clears */
 540static int rtd520_probe_fifo_depth(struct comedi_device *dev)
 541{
 542        struct rtd_private *devpriv = dev->private;
 543        unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
 544        unsigned i;
 545        static const unsigned limit = 0x2000;
 546        unsigned fifo_size = 0;
 547
 548        writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
 549        rtd_load_channelgain_list(dev, 1, &chanspec);
 550        /* ADC conversion trigger source: SOFTWARE */
 551        writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
 552        /* convert  samples */
 553        for (i = 0; i < limit; ++i) {
 554                unsigned fifo_status;
 555                /* trigger conversion */
 556                writew(0, devpriv->las0 + LAS0_ADC);
 557                udelay(1);
 558                fifo_status = readl(devpriv->las0 + LAS0_ADC);
 559                if ((fifo_status & FS_ADC_HEMPTY) == 0) {
 560                        fifo_size = 2 * i;
 561                        break;
 562                }
 563        }
 564        if (i == limit) {
 565                dev_info(dev->class_dev, "failed to probe fifo size.\n");
 566                return -EIO;
 567        }
 568        writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
 569        if (fifo_size != 0x400 && fifo_size != 0x2000) {
 570                dev_info(dev->class_dev,
 571                         "unexpected fifo size of %i, expected 1024 or 8192.\n",
 572                         fifo_size);
 573                return -EIO;
 574        }
 575        return fifo_size;
 576}
 577
 578/*
 579  "instructions" read/write data in "one-shot" or "software-triggered"
 580  mode (simplest case).
 581  This doesn't use interrupts.
 582
 583  Note, we don't do any settling delays.  Use a instruction list to
 584  select, delay, then read.
 585 */
 586static int rtd_ai_rinsn(struct comedi_device *dev,
 587                        struct comedi_subdevice *s, struct comedi_insn *insn,
 588                        unsigned int *data)
 589{
 590        struct rtd_private *devpriv = dev->private;
 591        int n, ii;
 592        int stat;
 593
 594        /* clear any old fifo data */
 595        writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
 596
 597        /* write channel to multiplexer and clear channel gain table */
 598        rtd_load_channelgain_list(dev, 1, &insn->chanspec);
 599
 600        /* ADC conversion trigger source: SOFTWARE */
 601        writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
 602
 603        /* convert n samples */
 604        for (n = 0; n < insn->n; n++) {
 605                s16 d;
 606                /* trigger conversion */
 607                writew(0, devpriv->las0 + LAS0_ADC);
 608
 609                for (ii = 0; ii < RTD_ADC_TIMEOUT; ++ii) {
 610                        stat = readl(devpriv->las0 + LAS0_ADC);
 611                        if (stat & FS_ADC_NOT_EMPTY)    /* 1 -> not empty */
 612                                break;
 613                        WAIT_QUIETLY;
 614                }
 615                if (ii >= RTD_ADC_TIMEOUT)
 616                        return -ETIMEDOUT;
 617
 618                /* read data */
 619                d = readw(devpriv->las1 + LAS1_ADC_FIFO);
 620                /*printk ("rtd520: Got 0x%x after %d usec\n", d, ii+1); */
 621                d = d >> 3;     /* low 3 bits are marker lines */
 622                if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar, 0))
 623                        /* convert to comedi unsigned data */
 624                        data[n] = d + 2048;
 625                else
 626                        data[n] = d;
 627        }
 628
 629        /* return the number of samples read/written */
 630        return n;
 631}
 632
 633/*
 634  Get what we know is there.... Fast!
 635  This uses 1/2 the bus cycles of read_dregs (below).
 636
 637  The manual claims that we can do a lword read, but it doesn't work here.
 638*/
 639static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s,
 640                     int count)
 641{
 642        struct rtd_private *devpriv = dev->private;
 643        int ii;
 644
 645        for (ii = 0; ii < count; ii++) {
 646                short sample;
 647                s16 d;
 648
 649                if (0 == devpriv->ai_count) {   /* done */
 650                        d = readw(devpriv->las1 + LAS1_ADC_FIFO);
 651                        continue;
 652                }
 653
 654                d = readw(devpriv->las1 + LAS1_ADC_FIFO);
 655                d = d >> 3;     /* low 3 bits are marker lines */
 656                if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
 657                                    s->async->cur_chan)) {
 658                        /* convert to comedi unsigned data */
 659                        sample = d + 2048;
 660                } else
 661                        sample = d;
 662
 663                if (!comedi_buf_put(s->async, sample))
 664                        return -1;
 665
 666                if (devpriv->ai_count > 0)      /* < 0, means read forever */
 667                        devpriv->ai_count--;
 668        }
 669        return 0;
 670}
 671
 672/*
 673  unknown amout of data is waiting in fifo.
 674*/
 675static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
 676{
 677        struct rtd_private *devpriv = dev->private;
 678
 679        while (readl(devpriv->las0 + LAS0_ADC) & FS_ADC_NOT_EMPTY) {
 680                short sample;
 681                s16 d = readw(devpriv->las1 + LAS1_ADC_FIFO);
 682
 683                if (0 == devpriv->ai_count) {   /* done */
 684                        continue;       /* read rest */
 685                }
 686
 687                d = d >> 3;     /* low 3 bits are marker lines */
 688                if (CHAN_ARRAY_TEST(devpriv->chan_is_bipolar,
 689                                    s->async->cur_chan)) {
 690                        /* convert to comedi unsigned data */
 691                        sample = d + 2048;
 692                } else
 693                        sample = d;
 694
 695                if (!comedi_buf_put(s->async, sample))
 696                        return -1;
 697
 698                if (devpriv->ai_count > 0)      /* < 0, means read forever */
 699                        devpriv->ai_count--;
 700        }
 701        return 0;
 702}
 703
 704/*
 705  Handle all rtd520 interrupts.
 706  Runs atomically and is never re-entered.
 707  This is a "slow handler";  other interrupts may be active.
 708  The data conversion may someday happen in a "bottom half".
 709*/
 710static irqreturn_t rtd_interrupt(int irq, void *d)
 711{
 712        struct comedi_device *dev = d;
 713        struct comedi_subdevice *s = &dev->subdevices[0];
 714        struct rtd_private *devpriv = dev->private;
 715        u32 overrun;
 716        u16 status;
 717        u16 fifo_status;
 718
 719        if (!dev->attached)
 720                return IRQ_NONE;
 721
 722        fifo_status = readl(devpriv->las0 + LAS0_ADC);
 723        /* check for FIFO full, this automatically halts the ADC! */
 724        if (!(fifo_status & FS_ADC_NOT_FULL))   /* 0 -> full */
 725                goto xfer_abort;
 726
 727        status = readw(devpriv->las0 + LAS0_IT);
 728        /* if interrupt was not caused by our board, or handled above */
 729        if (0 == status)
 730                return IRQ_HANDLED;
 731
 732        if (status & IRQM_ADC_ABOUT_CNT) {      /* sample count -> read FIFO */
 733                /*
 734                 * since the priority interrupt controller may have queued
 735                 * a sample counter interrupt, even though we have already
 736                 * finished, we must handle the possibility that there is
 737                 * no data here
 738                 */
 739                if (!(fifo_status & FS_ADC_HEMPTY)) {
 740                        /* FIFO half full */
 741                        if (ai_read_n(dev, s, devpriv->fifosz / 2) < 0)
 742                                goto xfer_abort;
 743
 744                        if (0 == devpriv->ai_count)
 745                                goto xfer_done;
 746
 747                        comedi_event(dev, s);
 748                } else if (devpriv->xfer_count > 0) {
 749                        if (fifo_status & FS_ADC_NOT_EMPTY) {
 750                                /* FIFO not empty */
 751                                if (ai_read_n(dev, s, devpriv->xfer_count) < 0)
 752                                        goto xfer_abort;
 753
 754                                if (0 == devpriv->ai_count)
 755                                        goto xfer_done;
 756
 757                                comedi_event(dev, s);
 758                        }
 759                }
 760        }
 761
 762        overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
 763        if (overrun)
 764                goto xfer_abort;
 765
 766        /* clear the interrupt */
 767        writew(status, devpriv->las0 + LAS0_CLEAR);
 768        readw(devpriv->las0 + LAS0_CLEAR);
 769        return IRQ_HANDLED;
 770
 771xfer_abort:
 772        writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
 773        s->async->events |= COMEDI_CB_ERROR;
 774        devpriv->ai_count = 0;  /* stop and don't transfer any more */
 775        /* fall into xfer_done */
 776
 777xfer_done:
 778        /* pacer stop source: SOFTWARE */
 779        writel(0, devpriv->las0 + LAS0_PACER_STOP);
 780        writel(0, devpriv->las0 + LAS0_PACER);  /* stop pacer */
 781        writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
 782        writew(0, devpriv->las0 + LAS0_IT);
 783
 784        if (devpriv->ai_count > 0) {    /* there shouldn't be anything left */
 785                fifo_status = readl(devpriv->las0 + LAS0_ADC);
 786                ai_read_dregs(dev, s);  /* read anything left in FIFO */
 787        }
 788
 789        s->async->events |= COMEDI_CB_EOA;      /* signal end to comedi */
 790        comedi_event(dev, s);
 791
 792        /* clear the interrupt */
 793        status = readw(devpriv->las0 + LAS0_IT);
 794        writew(status, devpriv->las0 + LAS0_CLEAR);
 795        readw(devpriv->las0 + LAS0_CLEAR);
 796
 797        fifo_status = readl(devpriv->las0 + LAS0_ADC);
 798        overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
 799
 800        return IRQ_HANDLED;
 801}
 802
 803/*
 804  cmdtest tests a particular command to see if it is valid.
 805  Using the cmdtest ioctl, a user can create a valid cmd
 806  and then have it executed by the cmd ioctl (asynchronously).
 807
 808  cmdtest returns 1,2,3,4 or 0, depending on which tests
 809  the command passes.
 810*/
 811
 812static int rtd_ai_cmdtest(struct comedi_device *dev,
 813                          struct comedi_subdevice *s, struct comedi_cmd *cmd)
 814{
 815        int err = 0;
 816        int tmp;
 817
 818        /* Step 1 : check if triggers are trivially valid */
 819
 820        err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
 821        err |= cfc_check_trigger_src(&cmd->scan_begin_src,
 822                                        TRIG_TIMER | TRIG_EXT);
 823        err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_TIMER | TRIG_EXT);
 824        err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 825        err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 826
 827        if (err)
 828                return 1;
 829
 830        /* Step 2a : make sure trigger sources are unique */
 831
 832        err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
 833        err |= cfc_check_trigger_is_unique(cmd->convert_src);
 834        err |= cfc_check_trigger_is_unique(cmd->stop_src);
 835
 836        /* Step 2b : and mutually compatible */
 837
 838        if (err)
 839                return 2;
 840
 841        /* Step 3: check if arguments are trivially valid */
 842
 843        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
 844
 845        if (cmd->scan_begin_src == TRIG_TIMER) {
 846                /* Note: these are time periods, not actual rates */
 847                if (1 == cmd->chanlist_len) {   /* no scanning */
 848                        if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
 849                                                      RTD_MAX_SPEED_1)) {
 850                                rtd_ns_to_timer(&cmd->scan_begin_arg,
 851                                                TRIG_ROUND_UP);
 852                                err |= -EINVAL;
 853                        }
 854                        if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
 855                                                      RTD_MIN_SPEED_1)) {
 856                                rtd_ns_to_timer(&cmd->scan_begin_arg,
 857                                                TRIG_ROUND_DOWN);
 858                                err |= -EINVAL;
 859                        }
 860                } else {
 861                        if (cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
 862                                                      RTD_MAX_SPEED)) {
 863                                rtd_ns_to_timer(&cmd->scan_begin_arg,
 864                                                TRIG_ROUND_UP);
 865                                err |= -EINVAL;
 866                        }
 867                        if (cfc_check_trigger_arg_max(&cmd->scan_begin_arg,
 868                                                      RTD_MIN_SPEED)) {
 869                                rtd_ns_to_timer(&cmd->scan_begin_arg,
 870                                                TRIG_ROUND_DOWN);
 871                                err |= -EINVAL;
 872                        }
 873                }
 874        } else {
 875                /* external trigger */
 876                /* should be level/edge, hi/lo specification here */
 877                /* should specify multiple external triggers */
 878                err |= cfc_check_trigger_arg_max(&cmd->scan_begin_arg, 9);
 879        }
 880
 881        if (cmd->convert_src == TRIG_TIMER) {
 882                if (1 == cmd->chanlist_len) {   /* no scanning */
 883                        if (cfc_check_trigger_arg_min(&cmd->convert_arg,
 884                                                      RTD_MAX_SPEED_1)) {
 885                                rtd_ns_to_timer(&cmd->convert_arg,
 886                                                TRIG_ROUND_UP);
 887                                err |= -EINVAL;
 888                        }
 889                        if (cfc_check_trigger_arg_max(&cmd->convert_arg,
 890                                                      RTD_MIN_SPEED_1)) {
 891                                rtd_ns_to_timer(&cmd->convert_arg,
 892                                                TRIG_ROUND_DOWN);
 893                                err |= -EINVAL;
 894                        }
 895                } else {
 896                        if (cfc_check_trigger_arg_min(&cmd->convert_arg,
 897                                                      RTD_MAX_SPEED)) {
 898                                rtd_ns_to_timer(&cmd->convert_arg,
 899                                                TRIG_ROUND_UP);
 900                                err |= -EINVAL;
 901                        }
 902                        if (cfc_check_trigger_arg_max(&cmd->convert_arg,
 903                                                      RTD_MIN_SPEED)) {
 904                                rtd_ns_to_timer(&cmd->convert_arg,
 905                                                TRIG_ROUND_DOWN);
 906                                err |= -EINVAL;
 907                        }
 908                }
 909        } else {
 910                /* external trigger */
 911                /* see above */
 912                err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
 913        }
 914
 915        if (cmd->stop_src == TRIG_COUNT) {
 916                /* TODO check for rounding error due to counter wrap */
 917        } else {
 918                /* TRIG_NONE */
 919                err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 920        }
 921
 922        if (err)
 923                return 3;
 924
 925
 926        /* step 4: fix up any arguments */
 927
 928        if (cmd->chanlist_len > RTD_MAX_CHANLIST) {
 929                cmd->chanlist_len = RTD_MAX_CHANLIST;
 930                err++;
 931        }
 932        if (cmd->scan_begin_src == TRIG_TIMER) {
 933                tmp = cmd->scan_begin_arg;
 934                rtd_ns_to_timer(&cmd->scan_begin_arg,
 935                                cmd->flags & TRIG_ROUND_MASK);
 936                if (tmp != cmd->scan_begin_arg)
 937                        err++;
 938
 939        }
 940        if (cmd->convert_src == TRIG_TIMER) {
 941                tmp = cmd->convert_arg;
 942                rtd_ns_to_timer(&cmd->convert_arg,
 943                                cmd->flags & TRIG_ROUND_MASK);
 944                if (tmp != cmd->convert_arg)
 945                        err++;
 946
 947                if (cmd->scan_begin_src == TRIG_TIMER
 948                    && (cmd->scan_begin_arg
 949                        < (cmd->convert_arg * cmd->scan_end_arg))) {
 950                        cmd->scan_begin_arg =
 951                            cmd->convert_arg * cmd->scan_end_arg;
 952                        err++;
 953                }
 954        }
 955
 956        if (err)
 957                return 4;
 958
 959        return 0;
 960}
 961
 962/*
 963  Execute a analog in command with many possible triggering options.
 964  The data get stored in the async structure of the subdevice.
 965  This is usually done by an interrupt handler.
 966  Userland gets to the data using read calls.
 967*/
 968static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 969{
 970        struct rtd_private *devpriv = dev->private;
 971        struct comedi_cmd *cmd = &s->async->cmd;
 972        int timer;
 973
 974        /* stop anything currently running */
 975        /* pacer stop source: SOFTWARE */
 976        writel(0, devpriv->las0 + LAS0_PACER_STOP);
 977        writel(0, devpriv->las0 + LAS0_PACER);  /* stop pacer */
 978        writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
 979        writew(0, devpriv->las0 + LAS0_IT);
 980        writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
 981        writel(0, devpriv->las0 + LAS0_OVERRUN);
 982
 983        /* start configuration */
 984        /* load channel list and reset CGT */
 985        rtd_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
 986
 987        /* setup the common case and override if needed */
 988        if (cmd->chanlist_len > 1) {
 989                /* pacer start source: SOFTWARE */
 990                writel(0, devpriv->las0 + LAS0_PACER_START);
 991                /* burst trigger source: PACER */
 992                writel(1, devpriv->las0 + LAS0_BURST_START);
 993                /* ADC conversion trigger source: BURST */
 994                writel(2, devpriv->las0 + LAS0_ADC_CONVERSION);
 995        } else {                /* single channel */
 996                /* pacer start source: SOFTWARE */
 997                writel(0, devpriv->las0 + LAS0_PACER_START);
 998                /* ADC conversion trigger source: PACER */
 999                writel(1, devpriv->las0 + LAS0_ADC_CONVERSION);
1000        }
1001        writel((devpriv->fifosz / 2 - 1) & 0xffff, devpriv->las0 + LAS0_ACNT);
1002
1003        if (TRIG_TIMER == cmd->scan_begin_src) {
1004                /* scan_begin_arg is in nanoseconds */
1005                /* find out how many samples to wait before transferring */
1006                if (cmd->flags & TRIG_WAKE_EOS) {
1007                        /*
1008                         * this may generate un-sustainable interrupt rates
1009                         * the application is responsible for doing the
1010                         * right thing
1011                         */
1012                        devpriv->xfer_count = cmd->chanlist_len;
1013                        devpriv->flags |= SEND_EOS;
1014                } else {
1015                        /* arrange to transfer data periodically */
1016                        devpriv->xfer_count =
1017                            (TRANS_TARGET_PERIOD * cmd->chanlist_len) /
1018                            cmd->scan_begin_arg;
1019                        if (devpriv->xfer_count < cmd->chanlist_len) {
1020                                /* transfer after each scan (and avoid 0) */
1021                                devpriv->xfer_count = cmd->chanlist_len;
1022                        } else {        /* make a multiple of scan length */
1023                                devpriv->xfer_count =
1024                                    (devpriv->xfer_count +
1025                                     cmd->chanlist_len - 1)
1026                                    / cmd->chanlist_len;
1027                                devpriv->xfer_count *= cmd->chanlist_len;
1028                        }
1029                        devpriv->flags |= SEND_EOS;
1030                }
1031                if (devpriv->xfer_count >= (devpriv->fifosz / 2)) {
1032                        /* out of counter range, use 1/2 fifo instead */
1033                        devpriv->xfer_count = 0;
1034                        devpriv->flags &= ~SEND_EOS;
1035                } else {
1036                        /* interrupt for each transfer */
1037                        writel((devpriv->xfer_count - 1) & 0xffff,
1038                                devpriv->las0 + LAS0_ACNT);
1039                }
1040        } else {                /* unknown timing, just use 1/2 FIFO */
1041                devpriv->xfer_count = 0;
1042                devpriv->flags &= ~SEND_EOS;
1043        }
1044        /* pacer clock source: INTERNAL 8MHz */
1045        writel(1, devpriv->las0 + LAS0_PACER_SELECT);
1046        /* just interrupt, don't stop */
1047        writel(1, devpriv->las0 + LAS0_ACNT_STOP_ENABLE);
1048
1049        /* BUG??? these look like enumerated values, but they are bit fields */
1050
1051        /* First, setup when to stop */
1052        switch (cmd->stop_src) {
1053        case TRIG_COUNT:        /* stop after N scans */
1054                devpriv->ai_count = cmd->stop_arg * cmd->chanlist_len;
1055                if ((devpriv->xfer_count > 0)
1056                    && (devpriv->xfer_count > devpriv->ai_count)) {
1057                        devpriv->xfer_count = devpriv->ai_count;
1058                }
1059                break;
1060
1061        case TRIG_NONE: /* stop when cancel is called */
1062                devpriv->ai_count = -1; /* read forever */
1063                break;
1064        }
1065
1066        /* Scan timing */
1067        switch (cmd->scan_begin_src) {
1068        case TRIG_TIMER:        /* periodic scanning */
1069                timer = rtd_ns_to_timer(&cmd->scan_begin_arg,
1070                                        TRIG_ROUND_NEAREST);
1071                /* set PACER clock */
1072                writel(timer & 0xffffff, devpriv->las0 + LAS0_PCLK);
1073
1074                break;
1075
1076        case TRIG_EXT:
1077                /* pacer start source: EXTERNAL */
1078                writel(1, devpriv->las0 + LAS0_PACER_START);
1079                break;
1080        }
1081
1082        /* Sample timing within a scan */
1083        switch (cmd->convert_src) {
1084        case TRIG_TIMER:        /* periodic */
1085                if (cmd->chanlist_len > 1) {
1086                        /* only needed for multi-channel */
1087                        timer = rtd_ns_to_timer(&cmd->convert_arg,
1088                                                TRIG_ROUND_NEAREST);
1089                        /* setup BURST clock */
1090                        writel(timer & 0x3ff, devpriv->las0 + LAS0_BCLK);
1091                }
1092
1093                break;
1094
1095        case TRIG_EXT:          /* external */
1096                /* burst trigger source: EXTERNAL */
1097                writel(2, devpriv->las0 + LAS0_BURST_START);
1098                break;
1099        }
1100        /* end configuration */
1101
1102        /* This doesn't seem to work.  There is no way to clear an interrupt
1103           that the priority controller has queued! */
1104        writew(~0, devpriv->las0 + LAS0_CLEAR);
1105        readw(devpriv->las0 + LAS0_CLEAR);
1106
1107        /* TODO: allow multiple interrupt sources */
1108        if (devpriv->xfer_count > 0) {  /* transfer every N samples */
1109                writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
1110        } else {                /* 1/2 FIFO transfers */
1111                writew(IRQM_ADC_ABOUT_CNT, devpriv->las0 + LAS0_IT);
1112        }
1113
1114        /* BUG: start_src is ASSUMED to be TRIG_NOW */
1115        /* BUG? it seems like things are running before the "start" */
1116        readl(devpriv->las0 + LAS0_PACER);      /* start pacer */
1117        return 0;
1118}
1119
1120/*
1121  Stop a running data acquisition.
1122*/
1123static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1124{
1125        struct rtd_private *devpriv = dev->private;
1126        u32 overrun;
1127        u16 status;
1128
1129        /* pacer stop source: SOFTWARE */
1130        writel(0, devpriv->las0 + LAS0_PACER_STOP);
1131        writel(0, devpriv->las0 + LAS0_PACER);  /* stop pacer */
1132        writel(0, devpriv->las0 + LAS0_ADC_CONVERSION);
1133        writew(0, devpriv->las0 + LAS0_IT);
1134        devpriv->ai_count = 0;  /* stop and don't transfer any more */
1135        status = readw(devpriv->las0 + LAS0_IT);
1136        overrun = readl(devpriv->las0 + LAS0_OVERRUN) & 0xffff;
1137        return 0;
1138}
1139
1140/*
1141  Output one (or more) analog values to a single port as fast as possible.
1142*/
1143static int rtd_ao_winsn(struct comedi_device *dev,
1144                        struct comedi_subdevice *s, struct comedi_insn *insn,
1145                        unsigned int *data)
1146{
1147        struct rtd_private *devpriv = dev->private;
1148        int i;
1149        int chan = CR_CHAN(insn->chanspec);
1150        int range = CR_RANGE(insn->chanspec);
1151
1152        /* Configure the output range (table index matches the range values) */
1153        writew(range & 7, devpriv->las0 +
1154                ((chan == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL));
1155
1156        /* Writing a list of values to an AO channel is probably not
1157         * very useful, but that's how the interface is defined. */
1158        for (i = 0; i < insn->n; ++i) {
1159                int val = data[i] << 3;
1160                int stat = 0;   /* initialize to avoid bogus warning */
1161                int ii;
1162
1163                /* VERIFY: comedi range and offset conversions */
1164
1165                if ((range > 1) /* bipolar */
1166                    && (data[i] < 2048)) {
1167                        /* offset and sign extend */
1168                        val = (((int)data[i]) - 2048) << 3;
1169                } else {        /* unipolor */
1170                        val = data[i] << 3;
1171                }
1172
1173                /* a typical programming sequence */
1174                writew(val, devpriv->las1 +
1175                        ((chan == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO));
1176                writew(0, devpriv->las0 +
1177                        ((chan == 0) ? LAS0_DAC1 : LAS0_DAC2));
1178
1179                devpriv->ao_readback[chan] = data[i];
1180
1181                for (ii = 0; ii < RTD_DAC_TIMEOUT; ++ii) {
1182                        stat = readl(devpriv->las0 + LAS0_ADC);
1183                        /* 1 -> not empty */
1184                        if (stat & ((0 == chan) ? FS_DAC1_NOT_EMPTY :
1185                                    FS_DAC2_NOT_EMPTY))
1186                                break;
1187                        WAIT_QUIETLY;
1188                }
1189                if (ii >= RTD_DAC_TIMEOUT)
1190                        return -ETIMEDOUT;
1191        }
1192
1193        /* return the number of samples read/written */
1194        return i;
1195}
1196
1197/* AO subdevices should have a read insn as well as a write insn.
1198 * Usually this means copying a value stored in devpriv. */
1199static int rtd_ao_rinsn(struct comedi_device *dev,
1200                        struct comedi_subdevice *s, struct comedi_insn *insn,
1201                        unsigned int *data)
1202{
1203        struct rtd_private *devpriv = dev->private;
1204        int i;
1205        int chan = CR_CHAN(insn->chanspec);
1206
1207        for (i = 0; i < insn->n; i++)
1208                data[i] = devpriv->ao_readback[chan];
1209
1210
1211        return i;
1212}
1213
1214static int rtd_dio_insn_bits(struct comedi_device *dev,
1215                             struct comedi_subdevice *s,
1216                             struct comedi_insn *insn,
1217                             unsigned int *data)
1218{
1219        struct rtd_private *devpriv = dev->private;
1220        unsigned int mask = data[0];
1221        unsigned int bits = data[1];
1222
1223        if (mask) {
1224                s->state &= ~mask;
1225                s->state |= (bits & mask);
1226
1227                writew(s->state & 0xff, devpriv->las0 + LAS0_DIO0);
1228        }
1229
1230        data[1] = readw(devpriv->las0 + LAS0_DIO0) & 0xff;
1231
1232        return insn->n;
1233}
1234
1235static int rtd_dio_insn_config(struct comedi_device *dev,
1236                               struct comedi_subdevice *s,
1237                               struct comedi_insn *insn,
1238                               unsigned int *data)
1239{
1240        struct rtd_private *devpriv = dev->private;
1241        int ret;
1242
1243        ret = comedi_dio_insn_config(dev, s, insn, data, 0);
1244        if (ret)
1245                return ret;
1246
1247        /* TODO support digital match interrupts and strobes */
1248
1249        /* set direction */
1250        writew(0x01, devpriv->las0 + LAS0_DIO_STATUS);
1251        writew(s->io_bits & 0xff, devpriv->las0 + LAS0_DIO0_CTRL);
1252
1253        /* clear interrupts */
1254        writew(0x00, devpriv->las0 + LAS0_DIO_STATUS);
1255
1256        /* port1 can only be all input or all output */
1257
1258        /* there are also 2 user input lines and 2 user output lines */
1259
1260        return insn->n;
1261}
1262
1263static void rtd_reset(struct comedi_device *dev)
1264{
1265        struct rtd_private *devpriv = dev->private;
1266
1267        writel(0, devpriv->las0 + LAS0_BOARD_RESET);
1268        udelay(100);            /* needed? */
1269        writel(0, devpriv->lcfg + PLX_INTRCS_REG);
1270        writew(0, devpriv->las0 + LAS0_IT);
1271        writew(~0, devpriv->las0 + LAS0_CLEAR);
1272        readw(devpriv->las0 + LAS0_CLEAR);
1273}
1274
1275/*
1276 * initialize board, per RTD spec
1277 * also, initialize shadow registers
1278 */
1279static void rtd_init_board(struct comedi_device *dev)
1280{
1281        struct rtd_private *devpriv = dev->private;
1282
1283        rtd_reset(dev);
1284
1285        writel(0, devpriv->las0 + LAS0_OVERRUN);
1286        writel(0, devpriv->las0 + LAS0_CGT_CLEAR);
1287        writel(0, devpriv->las0 + LAS0_ADC_FIFO_CLEAR);
1288        writel(0, devpriv->las0 + LAS0_DAC1_RESET);
1289        writel(0, devpriv->las0 + LAS0_DAC2_RESET);
1290        /* clear digital IO fifo */
1291        writew(0, devpriv->las0 + LAS0_DIO_STATUS);
1292        writeb((0 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
1293        writeb((1 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
1294        writeb((2 << 6) | 0x30, devpriv->las0 + LAS0_UTC_CTRL);
1295        writeb((3 << 6) | 0x00, devpriv->las0 + LAS0_UTC_CTRL);
1296        /* TODO: set user out source ??? */
1297}
1298
1299/* The RTD driver does this */
1300static void rtd_pci_latency_quirk(struct comedi_device *dev,
1301                                  struct pci_dev *pcidev)
1302{
1303        unsigned char pci_latency;
1304
1305        pci_read_config_byte(pcidev, PCI_LATENCY_TIMER, &pci_latency);
1306        if (pci_latency < 32) {
1307                dev_info(dev->class_dev,
1308                        "PCI latency changed from %d to %d\n",
1309                        pci_latency, 32);
1310                pci_write_config_byte(pcidev, PCI_LATENCY_TIMER, 32);
1311        }
1312}
1313
1314static int rtd_auto_attach(struct comedi_device *dev,
1315                           unsigned long context)
1316{
1317        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1318        const struct rtd_boardinfo *board = NULL;
1319        struct rtd_private *devpriv;
1320        struct comedi_subdevice *s;
1321        int ret;
1322
1323        if (context < ARRAY_SIZE(rtd520Boards))
1324                board = &rtd520Boards[context];
1325        if (!board)
1326                return -ENODEV;
1327        dev->board_ptr = board;
1328        dev->board_name = board->name;
1329
1330        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1331        if (!devpriv)
1332                return -ENOMEM;
1333
1334        ret = comedi_pci_enable(dev);
1335        if (ret)
1336                return ret;
1337
1338        devpriv->las0 = pci_ioremap_bar(pcidev, 2);
1339        devpriv->las1 = pci_ioremap_bar(pcidev, 3);
1340        devpriv->lcfg = pci_ioremap_bar(pcidev, 0);
1341        if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg)
1342                return -ENOMEM;
1343
1344        rtd_pci_latency_quirk(dev, pcidev);
1345
1346        if (pcidev->irq) {
1347                ret = request_irq(pcidev->irq, rtd_interrupt, IRQF_SHARED,
1348                                  dev->board_name, dev);
1349                if (ret == 0)
1350                        dev->irq = pcidev->irq;
1351        }
1352
1353        ret = comedi_alloc_subdevices(dev, 4);
1354        if (ret)
1355                return ret;
1356
1357        s = &dev->subdevices[0];
1358        /* analog input subdevice */
1359        s->type         = COMEDI_SUBD_AI;
1360        s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF;
1361        s->n_chan       = 16;
1362        s->maxdata      = 0x0fff;
1363        s->range_table  = board->ai_range;
1364        s->len_chanlist = RTD_MAX_CHANLIST;
1365        s->insn_read    = rtd_ai_rinsn;
1366        if (dev->irq) {
1367                dev->read_subdev = s;
1368                s->subdev_flags |= SDF_CMD_READ;
1369                s->do_cmd       = rtd_ai_cmd;
1370                s->do_cmdtest   = rtd_ai_cmdtest;
1371                s->cancel       = rtd_ai_cancel;
1372        }
1373
1374        s = &dev->subdevices[1];
1375        /* analog output subdevice */
1376        s->type         = COMEDI_SUBD_AO;
1377        s->subdev_flags = SDF_WRITABLE;
1378        s->n_chan       = 2;
1379        s->maxdata      = 0x0fff;
1380        s->range_table  = &rtd_ao_range;
1381        s->insn_write   = rtd_ao_winsn;
1382        s->insn_read    = rtd_ao_rinsn;
1383
1384        s = &dev->subdevices[2];
1385        /* digital i/o subdevice */
1386        s->type         = COMEDI_SUBD_DIO;
1387        s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1388        /* we only support port 0 right now.  Ignoring port 1 and user IO */
1389        s->n_chan       = 8;
1390        s->maxdata      = 1;
1391        s->range_table  = &range_digital;
1392        s->insn_bits    = rtd_dio_insn_bits;
1393        s->insn_config  = rtd_dio_insn_config;
1394
1395        /* timer/counter subdevices (not currently supported) */
1396        s = &dev->subdevices[3];
1397        s->type         = COMEDI_SUBD_COUNTER;
1398        s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
1399        s->n_chan       = 3;
1400        s->maxdata      = 0xffff;
1401
1402        rtd_init_board(dev);
1403
1404        ret = rtd520_probe_fifo_depth(dev);
1405        if (ret < 0)
1406                return ret;
1407        devpriv->fifosz = ret;
1408
1409        if (dev->irq)
1410                writel(ICS_PIE | ICS_PLIE, devpriv->lcfg + PLX_INTRCS_REG);
1411
1412        dev_info(dev->class_dev, "%s attached\n", dev->board_name);
1413
1414        return 0;
1415}
1416
1417static void rtd_detach(struct comedi_device *dev)
1418{
1419        struct rtd_private *devpriv = dev->private;
1420
1421        if (devpriv) {
1422                /* Shut down any board ops by resetting it */
1423                if (devpriv->las0 && devpriv->lcfg)
1424                        rtd_reset(dev);
1425                if (dev->irq) {
1426                        writel(readl(devpriv->lcfg + PLX_INTRCS_REG) &
1427                                ~(ICS_PLIE | ICS_DMA0_E | ICS_DMA1_E),
1428                                devpriv->lcfg + PLX_INTRCS_REG);
1429                        free_irq(dev->irq, dev);
1430                }
1431                if (devpriv->las0)
1432                        iounmap(devpriv->las0);
1433                if (devpriv->las1)
1434                        iounmap(devpriv->las1);
1435                if (devpriv->lcfg)
1436                        iounmap(devpriv->lcfg);
1437        }
1438        comedi_pci_disable(dev);
1439}
1440
1441static struct comedi_driver rtd520_driver = {
1442        .driver_name    = "rtd520",
1443        .module         = THIS_MODULE,
1444        .auto_attach    = rtd_auto_attach,
1445        .detach         = rtd_detach,
1446};
1447
1448static int rtd520_pci_probe(struct pci_dev *dev,
1449                            const struct pci_device_id *id)
1450{
1451        return comedi_pci_auto_config(dev, &rtd520_driver, id->driver_data);
1452}
1453
1454static DEFINE_PCI_DEVICE_TABLE(rtd520_pci_table) = {
1455        { PCI_VDEVICE(RTD, 0x7520), BOARD_DM7520 },
1456        { PCI_VDEVICE(RTD, 0x4520), BOARD_PCI4520 },
1457        { 0 }
1458};
1459MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
1460
1461static struct pci_driver rtd520_pci_driver = {
1462        .name           = "rtd520",
1463        .id_table       = rtd520_pci_table,
1464        .probe          = rtd520_pci_probe,
1465        .remove         = comedi_pci_auto_unconfig,
1466};
1467module_comedi_pci_driver(rtd520_driver, rtd520_pci_driver);
1468
1469MODULE_AUTHOR("Comedi http://www.comedi.org");
1470MODULE_DESCRIPTION("Comedi low-level driver");
1471MODULE_LICENSE("GPL");
1472