linux/drivers/comedi/drivers/das1800.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Comedi driver for Keithley DAS-1700/DAS-1800 series boards
   4 * Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
   5 *
   6 * COMEDI - Linux Control and Measurement Device Interface
   7 * Copyright (C) 2000 David A. Schleef <ds@schleef.org>
   8 */
   9
  10/*
  11 * Driver: das1800
  12 * Description: Keithley Metrabyte DAS1800 (& compatibles)
  13 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
  14 * Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
  15 *   DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
  16 *   DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
  17 *   DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
  18 *   DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
  19 *   DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
  20 *   DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
  21 *   DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
  22 *   DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
  23 *   DAS-1802AO (das-1802ao)
  24 * Status: works
  25 *
  26 * Configuration options:
  27 *   [0] - I/O port base address
  28 *   [1] - IRQ (optional, required for analog input cmd support)
  29 *   [2] - DMA0 (optional, requires irq)
  30 *   [3] - DMA1 (optional, requires irq and dma0)
  31 *
  32 * analog input cmd triggers supported:
  33 *
  34 *   start_src          TRIG_NOW        command starts immediately
  35 *                      TRIG_EXT        command starts on external pin TGIN
  36 *
  37 *   scan_begin_src     TRIG_FOLLOW     paced/external scans start immediately
  38 *                      TRIG_TIMER      burst scans start periodically
  39 *                      TRIG_EXT        burst scans start on external pin XPCLK
  40 *
  41 *   scan_end_src       TRIG_COUNT      scan ends after last channel
  42 *
  43 *   convert_src        TRIG_TIMER      paced/burst conversions are timed
  44 *                      TRIG_EXT        conversions on external pin XPCLK
  45 *                                      (requires scan_begin_src == TRIG_FOLLOW)
  46 *
  47 *   stop_src           TRIG_COUNT      command stops after stop_arg scans
  48 *                      TRIG_EXT        command stops on external pin TGIN
  49 *                      TRIG_NONE       command runs until canceled
  50 *
  51 * If TRIG_EXT is used for both the start_src and stop_src, the first TGIN
  52 * trigger starts the command, and the second trigger will stop it. If only
  53 * one is TRIG_EXT, the first trigger will either stop or start the command.
  54 * The external pin TGIN is normally set for negative edge triggering. It
  55 * can be set to positive edge with the CR_INVERT flag. If TRIG_EXT is used
  56 * for both the start_src and stop_src they must have the same polarity.
  57 *
  58 * Minimum conversion speed is limited to 64 microseconds (convert_arg <= 64000)
  59 * for 'burst' scans. This limitation does not apply for 'paced' scans. The
  60 * maximum conversion speed is limited by the board (convert_arg >= ai_speed).
  61 * Maximum conversion speeds are not always achievable depending on the
  62 * board setup (see user manual).
  63 *
  64 * NOTES:
  65 * Only the DAS-1801ST has been tested by me.
  66 * Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
  67 *
  68 * The waveform analog output on the 'ao' cards is not supported.
  69 * If you need it, send me (Frank Hess) an email.
  70 */
  71
  72#include <linux/module.h>
  73#include <linux/interrupt.h>
  74#include <linux/slab.h>
  75#include <linux/io.h>
  76
  77#include "../comedidev.h"
  78
  79#include "comedi_isadma.h"
  80#include "comedi_8254.h"
  81
  82/* misc. defines */
  83#define DAS1800_SIZE           16       /* uses 16 io addresses */
  84#define FIFO_SIZE              1024     /*  1024 sample fifo */
  85#define DMA_BUF_SIZE           0x1ff00  /*  size in bytes of dma buffers */
  86
  87/* Registers for the das1800 */
  88#define DAS1800_FIFO            0x0
  89#define DAS1800_QRAM            0x0
  90#define DAS1800_DAC             0x0
  91#define DAS1800_SELECT          0x2
  92#define   ADC                     0x0
  93#define   QRAM                    0x1
  94#define   DAC(a)                  (0x2 + a)
  95#define DAS1800_DIGITAL         0x3
  96#define DAS1800_CONTROL_A       0x4
  97#define   FFEN                    0x1
  98#define   CGEN                    0x4
  99#define   CGSL                    0x8
 100#define   TGEN                    0x10
 101#define   TGSL                    0x20
 102#define   TGPL                    0x40
 103#define   ATEN                    0x80
 104#define DAS1800_CONTROL_B       0x5
 105#define   DMA_CH5                 0x1
 106#define   DMA_CH6                 0x2
 107#define   DMA_CH7                 0x3
 108#define   DMA_CH5_CH6             0x5
 109#define   DMA_CH6_CH7             0x6
 110#define   DMA_CH7_CH5             0x7
 111#define   DMA_ENABLED             0x3
 112#define   DMA_DUAL                0x4
 113#define   IRQ3                    0x8
 114#define   IRQ5                    0x10
 115#define   IRQ7                    0x18
 116#define   IRQ10                   0x28
 117#define   IRQ11                   0x30
 118#define   IRQ15                   0x38
 119#define   FIMD                    0x40
 120#define DAS1800_CONTROL_C       0X6
 121#define   IPCLK                   0x1
 122#define   XPCLK                   0x3
 123#define   BMDE                    0x4
 124#define   CMEN                    0x8
 125#define   UQEN                    0x10
 126#define   SD                      0x40
 127#define   UB                      0x80
 128#define DAS1800_STATUS          0x7
 129#define   INT                     0x1
 130#define   DMATC                   0x2
 131#define   CT0TC                   0x8
 132#define   OVF                     0x10
 133#define   FHF                     0x20
 134#define   FNE                     0x40
 135#define   CVEN                    0x80
 136#define   CVEN_MASK               0x40
 137#define   CLEAR_INTR_MASK         (CVEN_MASK | 0x1f)
 138#define DAS1800_BURST_LENGTH    0x8
 139#define DAS1800_BURST_RATE      0x9
 140#define DAS1800_QRAM_ADDRESS    0xa
 141#define DAS1800_COUNTER         0xc
 142
 143#define IOBASE2                   0x400
 144
 145static const struct comedi_lrange das1801_ai_range = {
 146        8, {
 147                BIP_RANGE(5),           /* bipolar gain = 1 */
 148                BIP_RANGE(1),           /* bipolar gain = 10 */
 149                BIP_RANGE(0.1),         /* bipolar gain = 50 */
 150                BIP_RANGE(0.02),        /* bipolar gain = 250 */
 151                UNI_RANGE(5),           /* unipolar gain = 1 */
 152                UNI_RANGE(1),           /* unipolar gain = 10 */
 153                UNI_RANGE(0.1),         /* unipolar gain = 50 */
 154                UNI_RANGE(0.02)         /* unipolar gain = 250 */
 155        }
 156};
 157
 158static const struct comedi_lrange das1802_ai_range = {
 159        8, {
 160                BIP_RANGE(10),          /* bipolar gain = 1 */
 161                BIP_RANGE(5),           /* bipolar gain = 2 */
 162                BIP_RANGE(2.5),         /* bipolar gain = 4 */
 163                BIP_RANGE(1.25),        /* bipolar gain = 8 */
 164                UNI_RANGE(10),          /* unipolar gain = 1 */
 165                UNI_RANGE(5),           /* unipolar gain = 2 */
 166                UNI_RANGE(2.5),         /* unipolar gain = 4 */
 167                UNI_RANGE(1.25)         /* unipolar gain = 8 */
 168        }
 169};
 170
 171/*
 172 * The waveform analog outputs on the 'ao' boards are not currently
 173 * supported. They have a comedi_lrange of:
 174 * { 2, { BIP_RANGE(10), BIP_RANGE(5) } }
 175 */
 176
 177enum das1800_boardid {
 178        BOARD_DAS1701ST,
 179        BOARD_DAS1701ST_DA,
 180        BOARD_DAS1702ST,
 181        BOARD_DAS1702ST_DA,
 182        BOARD_DAS1702HR,
 183        BOARD_DAS1702HR_DA,
 184        BOARD_DAS1701AO,
 185        BOARD_DAS1702AO,
 186        BOARD_DAS1801ST,
 187        BOARD_DAS1801ST_DA,
 188        BOARD_DAS1802ST,
 189        BOARD_DAS1802ST_DA,
 190        BOARD_DAS1802HR,
 191        BOARD_DAS1802HR_DA,
 192        BOARD_DAS1801HC,
 193        BOARD_DAS1802HC,
 194        BOARD_DAS1801AO,
 195        BOARD_DAS1802AO
 196};
 197
 198/* board probe id values (hi byte of the digital input register) */
 199#define DAS1800_ID_ST_DA                0x3
 200#define DAS1800_ID_HR_DA                0x4
 201#define DAS1800_ID_AO                   0x5
 202#define DAS1800_ID_HR                   0x6
 203#define DAS1800_ID_ST                   0x7
 204#define DAS1800_ID_HC                   0x8
 205
 206struct das1800_board {
 207        const char *name;
 208        unsigned char id;
 209        unsigned int ai_speed;
 210        unsigned int is_01_series:1;
 211};
 212
 213static const struct das1800_board das1800_boards[] = {
 214        [BOARD_DAS1701ST] = {
 215                .name           = "das-1701st",
 216                .id             = DAS1800_ID_ST,
 217                .ai_speed       = 6250,
 218                .is_01_series   = 1,
 219        },
 220        [BOARD_DAS1701ST_DA] = {
 221                .name           = "das-1701st-da",
 222                .id             = DAS1800_ID_ST_DA,
 223                .ai_speed       = 6250,
 224                .is_01_series   = 1,
 225        },
 226        [BOARD_DAS1702ST] = {
 227                .name           = "das-1702st",
 228                .id             = DAS1800_ID_ST,
 229                .ai_speed       = 6250,
 230        },
 231        [BOARD_DAS1702ST_DA] = {
 232                .name           = "das-1702st-da",
 233                .id             = DAS1800_ID_ST_DA,
 234                .ai_speed       = 6250,
 235        },
 236        [BOARD_DAS1702HR] = {
 237                .name           = "das-1702hr",
 238                .id             = DAS1800_ID_HR,
 239                .ai_speed       = 20000,
 240        },
 241        [BOARD_DAS1702HR_DA] = {
 242                .name           = "das-1702hr-da",
 243                .id             = DAS1800_ID_HR_DA,
 244                .ai_speed       = 20000,
 245        },
 246        [BOARD_DAS1701AO] = {
 247                .name           = "das-1701ao",
 248                .id             = DAS1800_ID_AO,
 249                .ai_speed       = 6250,
 250                .is_01_series   = 1,
 251        },
 252        [BOARD_DAS1702AO] = {
 253                .name           = "das-1702ao",
 254                .id             = DAS1800_ID_AO,
 255                .ai_speed       = 6250,
 256        },
 257        [BOARD_DAS1801ST] = {
 258                .name           = "das-1801st",
 259                .id             = DAS1800_ID_ST,
 260                .ai_speed       = 3000,
 261                .is_01_series   = 1,
 262        },
 263        [BOARD_DAS1801ST_DA] = {
 264                .name           = "das-1801st-da",
 265                .id             = DAS1800_ID_ST_DA,
 266                .ai_speed       = 3000,
 267                .is_01_series   = 1,
 268        },
 269        [BOARD_DAS1802ST] = {
 270                .name           = "das-1802st",
 271                .id             = DAS1800_ID_ST,
 272                .ai_speed       = 3000,
 273        },
 274        [BOARD_DAS1802ST_DA] = {
 275                .name           = "das-1802st-da",
 276                .id             = DAS1800_ID_ST_DA,
 277                .ai_speed       = 3000,
 278        },
 279        [BOARD_DAS1802HR] = {
 280                .name           = "das-1802hr",
 281                .id             = DAS1800_ID_HR,
 282                .ai_speed       = 10000,
 283        },
 284        [BOARD_DAS1802HR_DA] = {
 285                .name           = "das-1802hr-da",
 286                .id             = DAS1800_ID_HR_DA,
 287                .ai_speed       = 10000,
 288        },
 289        [BOARD_DAS1801HC] = {
 290                .name           = "das-1801hc",
 291                .id             = DAS1800_ID_HC,
 292                .ai_speed       = 3000,
 293                .is_01_series   = 1,
 294        },
 295        [BOARD_DAS1802HC] = {
 296                .name           = "das-1802hc",
 297                .id             = DAS1800_ID_HC,
 298                .ai_speed       = 3000,
 299        },
 300        [BOARD_DAS1801AO] = {
 301                .name           = "das-1801ao",
 302                .id             = DAS1800_ID_AO,
 303                .ai_speed       = 3000,
 304                .is_01_series   = 1,
 305        },
 306        [BOARD_DAS1802AO] = {
 307                .name           = "das-1802ao",
 308                .id             = DAS1800_ID_AO,
 309                .ai_speed       = 3000,
 310        },
 311};
 312
 313struct das1800_private {
 314        struct comedi_isadma *dma;
 315        int irq_dma_bits;
 316        int dma_bits;
 317        unsigned short *fifo_buf;
 318        unsigned long iobase2;
 319        bool ai_is_unipolar;
 320};
 321
 322static void das1800_ai_munge(struct comedi_device *dev,
 323                             struct comedi_subdevice *s,
 324                             void *data, unsigned int num_bytes,
 325                             unsigned int start_chan_index)
 326{
 327        struct das1800_private *devpriv = dev->private;
 328        unsigned short *array = data;
 329        unsigned int num_samples = comedi_bytes_to_samples(s, num_bytes);
 330        unsigned int i;
 331
 332        if (devpriv->ai_is_unipolar)
 333                return;
 334
 335        for (i = 0; i < num_samples; i++)
 336                array[i] = comedi_offset_munge(s, array[i]);
 337}
 338
 339static void das1800_handle_fifo_half_full(struct comedi_device *dev,
 340                                          struct comedi_subdevice *s)
 341{
 342        struct das1800_private *devpriv = dev->private;
 343        unsigned int nsamples = comedi_nsamples_left(s, FIFO_SIZE / 2);
 344
 345        insw(dev->iobase + DAS1800_FIFO, devpriv->fifo_buf, nsamples);
 346        comedi_buf_write_samples(s, devpriv->fifo_buf, nsamples);
 347}
 348
 349static void das1800_handle_fifo_not_empty(struct comedi_device *dev,
 350                                          struct comedi_subdevice *s)
 351{
 352        struct comedi_cmd *cmd = &s->async->cmd;
 353        unsigned short dpnt;
 354
 355        while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
 356                dpnt = inw(dev->iobase + DAS1800_FIFO);
 357                comedi_buf_write_samples(s, &dpnt, 1);
 358
 359                if (cmd->stop_src == TRIG_COUNT &&
 360                    s->async->scans_done >= cmd->stop_arg)
 361                        break;
 362        }
 363}
 364
 365static void das1800_flush_dma_channel(struct comedi_device *dev,
 366                                      struct comedi_subdevice *s,
 367                                      struct comedi_isadma_desc *desc)
 368{
 369        unsigned int residue = comedi_isadma_disable(desc->chan);
 370        unsigned int nbytes = desc->size - residue;
 371        unsigned int nsamples;
 372
 373        /*  figure out how many points to read */
 374        nsamples = comedi_bytes_to_samples(s, nbytes);
 375        nsamples = comedi_nsamples_left(s, nsamples);
 376
 377        comedi_buf_write_samples(s, desc->virt_addr, nsamples);
 378}
 379
 380static void das1800_flush_dma(struct comedi_device *dev,
 381                              struct comedi_subdevice *s)
 382{
 383        struct das1800_private *devpriv = dev->private;
 384        struct comedi_isadma *dma = devpriv->dma;
 385        struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
 386        const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
 387
 388        das1800_flush_dma_channel(dev, s, desc);
 389
 390        if (dual_dma) {
 391                /*  switch to other channel and flush it */
 392                dma->cur_dma = 1 - dma->cur_dma;
 393                desc = &dma->desc[dma->cur_dma];
 394                das1800_flush_dma_channel(dev, s, desc);
 395        }
 396
 397        /*  get any remaining samples in fifo */
 398        das1800_handle_fifo_not_empty(dev, s);
 399}
 400
 401static void das1800_handle_dma(struct comedi_device *dev,
 402                               struct comedi_subdevice *s, unsigned int status)
 403{
 404        struct das1800_private *devpriv = dev->private;
 405        struct comedi_isadma *dma = devpriv->dma;
 406        struct comedi_isadma_desc *desc = &dma->desc[dma->cur_dma];
 407        const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
 408
 409        das1800_flush_dma_channel(dev, s, desc);
 410
 411        /* re-enable dma channel */
 412        comedi_isadma_program(desc);
 413
 414        if (status & DMATC) {
 415                /*  clear DMATC interrupt bit */
 416                outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
 417                /*  switch dma channels for next time, if appropriate */
 418                if (dual_dma)
 419                        dma->cur_dma = 1 - dma->cur_dma;
 420        }
 421}
 422
 423static int das1800_ai_cancel(struct comedi_device *dev,
 424                             struct comedi_subdevice *s)
 425{
 426        struct das1800_private *devpriv = dev->private;
 427        struct comedi_isadma *dma = devpriv->dma;
 428        struct comedi_isadma_desc *desc;
 429        int i;
 430
 431        /* disable and stop conversions */
 432        outb(0x0, dev->iobase + DAS1800_STATUS);
 433        outb(0x0, dev->iobase + DAS1800_CONTROL_B);
 434        outb(0x0, dev->iobase + DAS1800_CONTROL_A);
 435
 436        if (dma) {
 437                for (i = 0; i < 2; i++) {
 438                        desc = &dma->desc[i];
 439                        if (desc->chan)
 440                                comedi_isadma_disable(desc->chan);
 441                }
 442        }
 443
 444        return 0;
 445}
 446
 447static void das1800_ai_handler(struct comedi_device *dev)
 448{
 449        struct das1800_private *devpriv = dev->private;
 450        struct comedi_subdevice *s = dev->read_subdev;
 451        struct comedi_async *async = s->async;
 452        struct comedi_cmd *cmd = &async->cmd;
 453        unsigned int status = inb(dev->iobase + DAS1800_STATUS);
 454
 455        /* select adc register (spinlock is already held) */
 456        outb(ADC, dev->iobase + DAS1800_SELECT);
 457
 458        /* get samples with dma, fifo, or polled as necessary */
 459        if (devpriv->irq_dma_bits & DMA_ENABLED)
 460                das1800_handle_dma(dev, s, status);
 461        else if (status & FHF)
 462                das1800_handle_fifo_half_full(dev, s);
 463        else if (status & FNE)
 464                das1800_handle_fifo_not_empty(dev, s);
 465
 466        /* if the card's fifo has overflowed */
 467        if (status & OVF) {
 468                /*  clear OVF interrupt bit */
 469                outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
 470                dev_err(dev->class_dev, "FIFO overflow\n");
 471                async->events |= COMEDI_CB_ERROR;
 472                comedi_handle_events(dev, s);
 473                return;
 474        }
 475        /*  stop taking data if appropriate */
 476        /* stop_src TRIG_EXT */
 477        if (status & CT0TC) {
 478                /*  clear CT0TC interrupt bit */
 479                outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
 480                /* get all remaining samples before quitting */
 481                if (devpriv->irq_dma_bits & DMA_ENABLED)
 482                        das1800_flush_dma(dev, s);
 483                else
 484                        das1800_handle_fifo_not_empty(dev, s);
 485                async->events |= COMEDI_CB_EOA;
 486        } else if (cmd->stop_src == TRIG_COUNT &&
 487                   async->scans_done >= cmd->stop_arg) {
 488                async->events |= COMEDI_CB_EOA;
 489        }
 490
 491        comedi_handle_events(dev, s);
 492}
 493
 494static int das1800_ai_poll(struct comedi_device *dev,
 495                           struct comedi_subdevice *s)
 496{
 497        unsigned long flags;
 498
 499        /*
 500         * Protects the indirect addressing selected by DAS1800_SELECT
 501         * in das1800_ai_handler() also prevents race with das1800_interrupt().
 502         */
 503        spin_lock_irqsave(&dev->spinlock, flags);
 504
 505        das1800_ai_handler(dev);
 506
 507        spin_unlock_irqrestore(&dev->spinlock, flags);
 508
 509        return comedi_buf_n_bytes_ready(s);
 510}
 511
 512static irqreturn_t das1800_interrupt(int irq, void *d)
 513{
 514        struct comedi_device *dev = d;
 515        unsigned int status;
 516
 517        if (!dev->attached) {
 518                dev_err(dev->class_dev, "premature interrupt\n");
 519                return IRQ_HANDLED;
 520        }
 521
 522        /*
 523         * Protects the indirect addressing selected by DAS1800_SELECT
 524         * in das1800_ai_handler() also prevents race with das1800_ai_poll().
 525         */
 526        spin_lock(&dev->spinlock);
 527
 528        status = inb(dev->iobase + DAS1800_STATUS);
 529
 530        /* if interrupt was not caused by das-1800 */
 531        if (!(status & INT)) {
 532                spin_unlock(&dev->spinlock);
 533                return IRQ_NONE;
 534        }
 535        /* clear the interrupt status bit INT */
 536        outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
 537        /*  handle interrupt */
 538        das1800_ai_handler(dev);
 539
 540        spin_unlock(&dev->spinlock);
 541        return IRQ_HANDLED;
 542}
 543
 544static int das1800_ai_fixup_paced_timing(struct comedi_device *dev,
 545                                         struct comedi_cmd *cmd)
 546{
 547        unsigned int arg = cmd->convert_arg;
 548
 549        /*
 550         * Paced mode:
 551         *      scan_begin_src is TRIG_FOLLOW
 552         *      convert_src is TRIG_TIMER
 553         *
 554         * The convert_arg sets the pacer sample acquisition time.
 555         * The max acquisition speed is limited to the boards
 556         * 'ai_speed' (this was already verified). The min speed is
 557         * limited by the cascaded 8254 timer.
 558         */
 559        comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
 560        return comedi_check_trigger_arg_is(&cmd->convert_arg, arg);
 561}
 562
 563static int das1800_ai_fixup_burst_timing(struct comedi_device *dev,
 564                                         struct comedi_cmd *cmd)
 565{
 566        unsigned int arg = cmd->convert_arg;
 567        int err = 0;
 568
 569        /*
 570         * Burst mode:
 571         *      scan_begin_src is TRIG_TIMER or TRIG_EXT
 572         *      convert_src is TRIG_TIMER
 573         *
 574         * The convert_arg sets burst sample acquisition time.
 575         * The max acquisition speed is limited to the boards
 576         * 'ai_speed' (this was already verified). The min speed is
 577         * limiited to 64 microseconds,
 578         */
 579        err |= comedi_check_trigger_arg_max(&arg, 64000);
 580
 581        /* round to microseconds then verify */
 582        switch (cmd->flags & CMDF_ROUND_MASK) {
 583        case CMDF_ROUND_NEAREST:
 584        default:
 585                arg = DIV_ROUND_CLOSEST(arg, 1000);
 586                break;
 587        case CMDF_ROUND_DOWN:
 588                arg = arg / 1000;
 589                break;
 590        case CMDF_ROUND_UP:
 591                arg = DIV_ROUND_UP(arg, 1000);
 592                break;
 593        }
 594        err |= comedi_check_trigger_arg_is(&cmd->convert_arg, arg * 1000);
 595
 596        /*
 597         * The pacer can be used to set the scan sample rate. The max scan
 598         * speed is limited by the conversion speed and the number of channels
 599         * to convert. The min speed is limited by the cascaded 8254 timer.
 600         */
 601        if (cmd->scan_begin_src == TRIG_TIMER) {
 602                arg = cmd->convert_arg * cmd->chanlist_len;
 603                err |= comedi_check_trigger_arg_min(&cmd->scan_begin_arg, arg);
 604
 605                arg = cmd->scan_begin_arg;
 606                comedi_8254_cascade_ns_to_timer(dev->pacer, &arg, cmd->flags);
 607                err |= comedi_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
 608        }
 609
 610        return err;
 611}
 612
 613static int das1800_ai_check_chanlist(struct comedi_device *dev,
 614                                     struct comedi_subdevice *s,
 615                                     struct comedi_cmd *cmd)
 616{
 617        unsigned int range = CR_RANGE(cmd->chanlist[0]);
 618        bool unipolar0 = comedi_range_is_unipolar(s, range);
 619        int i;
 620
 621        for (i = 1; i < cmd->chanlist_len; i++) {
 622                range = CR_RANGE(cmd->chanlist[i]);
 623
 624                if (unipolar0 != comedi_range_is_unipolar(s, range)) {
 625                        dev_dbg(dev->class_dev,
 626                                "unipolar and bipolar ranges cannot be mixed in the chanlist\n");
 627                        return -EINVAL;
 628                }
 629        }
 630
 631        return 0;
 632}
 633
 634static int das1800_ai_cmdtest(struct comedi_device *dev,
 635                              struct comedi_subdevice *s,
 636                              struct comedi_cmd *cmd)
 637{
 638        const struct das1800_board *board = dev->board_ptr;
 639        int err = 0;
 640
 641        /* Step 1 : check if triggers are trivially valid */
 642
 643        err |= comedi_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
 644        err |= comedi_check_trigger_src(&cmd->scan_begin_src,
 645                                        TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
 646        err |= comedi_check_trigger_src(&cmd->convert_src,
 647                                        TRIG_TIMER | TRIG_EXT);
 648        err |= comedi_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 649        err |= comedi_check_trigger_src(&cmd->stop_src,
 650                                        TRIG_COUNT | TRIG_EXT | TRIG_NONE);
 651
 652        if (err)
 653                return 1;
 654
 655        /* Step 2a : make sure trigger sources are unique */
 656
 657        err |= comedi_check_trigger_is_unique(cmd->start_src);
 658        err |= comedi_check_trigger_is_unique(cmd->scan_begin_src);
 659        err |= comedi_check_trigger_is_unique(cmd->convert_src);
 660        err |= comedi_check_trigger_is_unique(cmd->stop_src);
 661
 662        /* Step 2b : and mutually compatible */
 663
 664        /* burst scans must use timed conversions */
 665        if (cmd->scan_begin_src != TRIG_FOLLOW &&
 666            cmd->convert_src != TRIG_TIMER)
 667                err |= -EINVAL;
 668
 669        /* the external pin TGIN must use the same polarity */
 670        if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
 671                err |= comedi_check_trigger_arg_is(&cmd->start_arg,
 672                                                   cmd->stop_arg);
 673
 674        if (err)
 675                return 2;
 676
 677        /* Step 3: check if arguments are trivially valid */
 678
 679        if (cmd->start_arg == TRIG_NOW)
 680                err |= comedi_check_trigger_arg_is(&cmd->start_arg, 0);
 681
 682        if (cmd->convert_src == TRIG_TIMER) {
 683                err |= comedi_check_trigger_arg_min(&cmd->convert_arg,
 684                                                    board->ai_speed);
 685        }
 686
 687        err |= comedi_check_trigger_arg_min(&cmd->chanlist_len, 1);
 688        err |= comedi_check_trigger_arg_is(&cmd->scan_end_arg,
 689                                           cmd->chanlist_len);
 690
 691        switch (cmd->stop_src) {
 692        case TRIG_COUNT:
 693                err |= comedi_check_trigger_arg_min(&cmd->stop_arg, 1);
 694                break;
 695        case TRIG_NONE:
 696                err |= comedi_check_trigger_arg_is(&cmd->stop_arg, 0);
 697                break;
 698        default:
 699                break;
 700        }
 701
 702        if (err)
 703                return 3;
 704
 705        /* Step 4: fix up any arguments */
 706
 707        if (cmd->convert_src == TRIG_TIMER) {
 708                if (cmd->scan_begin_src == TRIG_FOLLOW)
 709                        err |= das1800_ai_fixup_paced_timing(dev, cmd);
 710                else /* TRIG_TIMER or TRIG_EXT */
 711                        err |= das1800_ai_fixup_burst_timing(dev, cmd);
 712        }
 713
 714        if (err)
 715                return 4;
 716
 717        /* Step 5: check channel list if it exists */
 718        if (cmd->chanlist && cmd->chanlist_len > 0)
 719                err |= das1800_ai_check_chanlist(dev, s, cmd);
 720
 721        if (err)
 722                return 5;
 723
 724        return 0;
 725}
 726
 727static unsigned char das1800_ai_chanspec_bits(struct comedi_subdevice *s,
 728                                              unsigned int chanspec)
 729{
 730        unsigned int range = CR_RANGE(chanspec);
 731        unsigned int aref = CR_AREF(chanspec);
 732        unsigned char bits;
 733
 734        bits = UQEN;
 735        if (aref != AREF_DIFF)
 736                bits |= SD;
 737        if (aref == AREF_COMMON)
 738                bits |= CMEN;
 739        if (comedi_range_is_unipolar(s, range))
 740                bits |= UB;
 741
 742        return bits;
 743}
 744
 745static unsigned int das1800_ai_transfer_size(struct comedi_device *dev,
 746                                             struct comedi_subdevice *s,
 747                                             unsigned int maxbytes,
 748                                             unsigned int ns)
 749{
 750        struct comedi_cmd *cmd = &s->async->cmd;
 751        unsigned int max_samples = comedi_bytes_to_samples(s, maxbytes);
 752        unsigned int samples;
 753
 754        samples = max_samples;
 755
 756        /* for timed modes, make dma buffer fill in 'ns' time */
 757        switch (cmd->scan_begin_src) {
 758        case TRIG_FOLLOW:       /* not in burst mode */
 759                if (cmd->convert_src == TRIG_TIMER)
 760                        samples = ns / cmd->convert_arg;
 761                break;
 762        case TRIG_TIMER:
 763                samples = ns / (cmd->scan_begin_arg * cmd->chanlist_len);
 764                break;
 765        }
 766
 767        /* limit samples to what is remaining in the command */
 768        samples = comedi_nsamples_left(s, samples);
 769
 770        if (samples > max_samples)
 771                samples = max_samples;
 772        if (samples < 1)
 773                samples = 1;
 774
 775        return comedi_samples_to_bytes(s, samples);
 776}
 777
 778static void das1800_ai_setup_dma(struct comedi_device *dev,
 779                                 struct comedi_subdevice *s)
 780{
 781        struct das1800_private *devpriv = dev->private;
 782        struct comedi_isadma *dma = devpriv->dma;
 783        struct comedi_isadma_desc *desc;
 784        unsigned int bytes;
 785
 786        if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
 787                return;
 788
 789        dma->cur_dma = 0;
 790        desc = &dma->desc[0];
 791
 792        /* determine a dma transfer size to fill buffer in 0.3 sec */
 793        bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000);
 794
 795        desc->size = bytes;
 796        comedi_isadma_program(desc);
 797
 798        /* set up dual dma if appropriate */
 799        if (devpriv->irq_dma_bits & DMA_DUAL) {
 800                desc = &dma->desc[1];
 801                desc->size = bytes;
 802                comedi_isadma_program(desc);
 803        }
 804}
 805
 806static void das1800_ai_set_chanlist(struct comedi_device *dev,
 807                                    unsigned int *chanlist, unsigned int len)
 808{
 809        unsigned long flags;
 810        unsigned int i;
 811
 812        /* protects the indirect addressing selected by DAS1800_SELECT */
 813        spin_lock_irqsave(&dev->spinlock, flags);
 814
 815        /* select QRAM register and set start address */
 816        outb(QRAM, dev->iobase + DAS1800_SELECT);
 817        outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
 818
 819        /* make channel / gain list */
 820        for (i = 0; i < len; i++) {
 821                unsigned int chan = CR_CHAN(chanlist[i]);
 822                unsigned int range = CR_RANGE(chanlist[i]);
 823                unsigned short val;
 824
 825                val = chan | ((range & 0x3) << 8);
 826                outw(val, dev->iobase + DAS1800_QRAM);
 827        }
 828
 829        /* finish write to QRAM */
 830        outb(len - 1, dev->iobase + DAS1800_QRAM_ADDRESS);
 831
 832        spin_unlock_irqrestore(&dev->spinlock, flags);
 833}
 834
 835static int das1800_ai_cmd(struct comedi_device *dev,
 836                          struct comedi_subdevice *s)
 837{
 838        struct das1800_private *devpriv = dev->private;
 839        int control_a, control_c;
 840        struct comedi_async *async = s->async;
 841        const struct comedi_cmd *cmd = &async->cmd;
 842        unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
 843
 844        /*
 845         * Disable dma on CMDF_WAKE_EOS, or CMDF_PRIORITY (because dma in
 846         * handler is unsafe at hard real-time priority).
 847         */
 848        if (cmd->flags & (CMDF_WAKE_EOS | CMDF_PRIORITY))
 849                devpriv->irq_dma_bits &= ~DMA_ENABLED;
 850        else
 851                devpriv->irq_dma_bits |= devpriv->dma_bits;
 852        /*  interrupt on end of conversion for CMDF_WAKE_EOS */
 853        if (cmd->flags & CMDF_WAKE_EOS) {
 854                /*  interrupt fifo not empty */
 855                devpriv->irq_dma_bits &= ~FIMD;
 856        } else {
 857                /*  interrupt fifo half full */
 858                devpriv->irq_dma_bits |= FIMD;
 859        }
 860
 861        das1800_ai_cancel(dev, s);
 862
 863        devpriv->ai_is_unipolar = comedi_range_is_unipolar(s, range0);
 864
 865        control_a = FFEN;
 866        if (cmd->stop_src == TRIG_EXT)
 867                control_a |= ATEN;
 868        if (cmd->start_src == TRIG_EXT)
 869                control_a |= TGEN | CGSL;
 870        else /* TRIG_NOW */
 871                control_a |= CGEN;
 872        if (control_a & (ATEN | TGEN)) {
 873                if ((cmd->start_arg & CR_INVERT) || (cmd->stop_arg & CR_INVERT))
 874                        control_a |= TGPL;
 875        }
 876
 877        control_c = das1800_ai_chanspec_bits(s, cmd->chanlist[0]);
 878        /* set clock source to internal or external */
 879        if (cmd->scan_begin_src == TRIG_FOLLOW) {
 880                /* not in burst mode */
 881                if (cmd->convert_src == TRIG_TIMER) {
 882                        /* trig on cascaded counters */
 883                        control_c |= IPCLK;
 884                } else { /* TRIG_EXT */
 885                        /* trig on falling edge of external trigger */
 886                        control_c |= XPCLK;
 887                }
 888        } else if (cmd->scan_begin_src == TRIG_TIMER) {
 889                /* burst mode with internal pacer clock */
 890                control_c |= BMDE | IPCLK;
 891        } else { /* TRIG_EXT */
 892                /* burst mode with external trigger */
 893                control_c |= BMDE | XPCLK;
 894        }
 895
 896        das1800_ai_set_chanlist(dev, cmd->chanlist, cmd->chanlist_len);
 897
 898        /* setup cascaded counters for conversion/scan frequency */
 899        if ((cmd->scan_begin_src == TRIG_FOLLOW ||
 900             cmd->scan_begin_src == TRIG_TIMER) &&
 901            cmd->convert_src == TRIG_TIMER) {
 902                comedi_8254_update_divisors(dev->pacer);
 903                comedi_8254_pacer_enable(dev->pacer, 1, 2, true);
 904        }
 905
 906        /* setup counter 0 for 'about triggering' */
 907        if (cmd->stop_src == TRIG_EXT)
 908                comedi_8254_load(dev->pacer, 0, 1, I8254_MODE0 | I8254_BINARY);
 909
 910        das1800_ai_setup_dma(dev, s);
 911        outb(control_c, dev->iobase + DAS1800_CONTROL_C);
 912        /*  set conversion rate and length for burst mode */
 913        if (control_c & BMDE) {
 914                outb(cmd->convert_arg / 1000 - 1,       /* microseconds - 1 */
 915                     dev->iobase + DAS1800_BURST_RATE);
 916                outb(cmd->chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
 917        }
 918
 919        /* enable and start conversions */
 920        outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B);
 921        outb(control_a, dev->iobase + DAS1800_CONTROL_A);
 922        outb(CVEN, dev->iobase + DAS1800_STATUS);
 923
 924        return 0;
 925}
 926
 927static int das1800_ai_eoc(struct comedi_device *dev,
 928                          struct comedi_subdevice *s,
 929                          struct comedi_insn *insn,
 930                          unsigned long context)
 931{
 932        unsigned char status;
 933
 934        status = inb(dev->iobase + DAS1800_STATUS);
 935        if (status & FNE)
 936                return 0;
 937        return -EBUSY;
 938}
 939
 940static int das1800_ai_insn_read(struct comedi_device *dev,
 941                                struct comedi_subdevice *s,
 942                                struct comedi_insn *insn,
 943                                unsigned int *data)
 944{
 945        unsigned int range = CR_RANGE(insn->chanspec);
 946        bool is_unipolar = comedi_range_is_unipolar(s, range);
 947        int ret = 0;
 948        int n;
 949        unsigned short dpnt;
 950        unsigned long flags;
 951
 952        outb(das1800_ai_chanspec_bits(s, insn->chanspec),
 953             dev->iobase + DAS1800_CONTROL_C);          /* software pacer */
 954        outb(CVEN, dev->iobase + DAS1800_STATUS);       /* enable conversions */
 955        outb(0x0, dev->iobase + DAS1800_CONTROL_A);     /* reset fifo */
 956        outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
 957
 958        das1800_ai_set_chanlist(dev, &insn->chanspec, 1);
 959
 960        /* protects the indirect addressing selected by DAS1800_SELECT */
 961        spin_lock_irqsave(&dev->spinlock, flags);
 962
 963        /* select ai fifo register */
 964        outb(ADC, dev->iobase + DAS1800_SELECT);
 965
 966        for (n = 0; n < insn->n; n++) {
 967                /* trigger conversion */
 968                outb(0, dev->iobase + DAS1800_FIFO);
 969
 970                ret = comedi_timeout(dev, s, insn, das1800_ai_eoc, 0);
 971                if (ret)
 972                        break;
 973
 974                dpnt = inw(dev->iobase + DAS1800_FIFO);
 975                if (!is_unipolar)
 976                        dpnt = comedi_offset_munge(s, dpnt);
 977                data[n] = dpnt;
 978        }
 979        spin_unlock_irqrestore(&dev->spinlock, flags);
 980
 981        return ret ? ret : insn->n;
 982}
 983
 984static int das1800_ao_insn_write(struct comedi_device *dev,
 985                                 struct comedi_subdevice *s,
 986                                 struct comedi_insn *insn,
 987                                 unsigned int *data)
 988{
 989        unsigned int chan = CR_CHAN(insn->chanspec);
 990        unsigned int update_chan = s->n_chan - 1;
 991        unsigned long flags;
 992        int i;
 993
 994        /* protects the indirect addressing selected by DAS1800_SELECT */
 995        spin_lock_irqsave(&dev->spinlock, flags);
 996
 997        for (i = 0; i < insn->n; i++) {
 998                unsigned int val = data[i];
 999
1000                s->readback[chan] = val;
1001
1002                val = comedi_offset_munge(s, val);
1003
1004                /* load this channel (and update if it's the last channel) */
1005                outb(DAC(chan), dev->iobase + DAS1800_SELECT);
1006                outw(val, dev->iobase + DAS1800_DAC);
1007
1008                /* update all channels */
1009                if (chan != update_chan) {
1010                        val = comedi_offset_munge(s, s->readback[update_chan]);
1011
1012                        outb(DAC(update_chan), dev->iobase + DAS1800_SELECT);
1013                        outw(val, dev->iobase + DAS1800_DAC);
1014                }
1015        }
1016        spin_unlock_irqrestore(&dev->spinlock, flags);
1017
1018        return insn->n;
1019}
1020
1021static int das1800_di_insn_bits(struct comedi_device *dev,
1022                                struct comedi_subdevice *s,
1023                                struct comedi_insn *insn,
1024                                unsigned int *data)
1025{
1026        data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
1027        data[0] = 0;
1028
1029        return insn->n;
1030}
1031
1032static int das1800_do_insn_bits(struct comedi_device *dev,
1033                                struct comedi_subdevice *s,
1034                                struct comedi_insn *insn,
1035                                unsigned int *data)
1036{
1037        if (comedi_dio_update_state(s, data))
1038                outb(s->state, dev->iobase + DAS1800_DIGITAL);
1039
1040        data[1] = s->state;
1041
1042        return insn->n;
1043}
1044
1045static void das1800_init_dma(struct comedi_device *dev,
1046                             struct comedi_devconfig *it)
1047{
1048        struct das1800_private *devpriv = dev->private;
1049        unsigned int *dma_chan;
1050
1051        /*
1052         * it->options[2] is DMA channel 0
1053         * it->options[3] is DMA channel 1
1054         *
1055         * Encode the DMA channels into 2 digit hexadecimal for switch.
1056         */
1057        dma_chan = &it->options[2];
1058
1059        switch ((dma_chan[0] & 0x7) | (dma_chan[1] << 4)) {
1060        case 0x5:       /*  dma0 == 5 */
1061                devpriv->dma_bits = DMA_CH5;
1062                break;
1063        case 0x6:       /*  dma0 == 6 */
1064                devpriv->dma_bits = DMA_CH6;
1065                break;
1066        case 0x7:       /*  dma0 == 7 */
1067                devpriv->dma_bits = DMA_CH7;
1068                break;
1069        case 0x65:      /*  dma0 == 5, dma1 == 6 */
1070                devpriv->dma_bits = DMA_CH5_CH6;
1071                break;
1072        case 0x76:      /*  dma0 == 6, dma1 == 7 */
1073                devpriv->dma_bits = DMA_CH6_CH7;
1074                break;
1075        case 0x57:      /*  dma0 == 7, dma1 == 5 */
1076                devpriv->dma_bits = DMA_CH7_CH5;
1077                break;
1078        default:
1079                return;
1080        }
1081
1082        /* DMA can use 1 or 2 buffers, each with a separate channel */
1083        devpriv->dma = comedi_isadma_alloc(dev, dma_chan[1] ? 2 : 1,
1084                                           dma_chan[0], dma_chan[1],
1085                                           DMA_BUF_SIZE, COMEDI_ISADMA_READ);
1086        if (!devpriv->dma)
1087                devpriv->dma_bits = 0;
1088}
1089
1090static void das1800_free_dma(struct comedi_device *dev)
1091{
1092        struct das1800_private *devpriv = dev->private;
1093
1094        if (devpriv)
1095                comedi_isadma_free(devpriv->dma);
1096}
1097
1098static int das1800_probe(struct comedi_device *dev)
1099{
1100        const struct das1800_board *board = dev->board_ptr;
1101        unsigned char id;
1102
1103        id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf;
1104
1105        /*
1106         * The dev->board_ptr will be set by comedi_device_attach() if the
1107         * board name provided by the user matches a board->name in this
1108         * driver. If so, this function sanity checks the id to verify that
1109         * the board is correct.
1110         */
1111        if (board) {
1112                if (board->id == id)
1113                        return 0;
1114                dev_err(dev->class_dev,
1115                        "probed id does not match board id (0x%x != 0x%x)\n",
1116                        id, board->id);
1117                return -ENODEV;
1118        }
1119
1120         /*
1121          * If the dev->board_ptr is not set, the user is trying to attach
1122          * an unspecified board to this driver. In this case the id is used
1123          * to 'probe' for the dev->board_ptr.
1124          */
1125        switch (id) {
1126        case DAS1800_ID_ST_DA:
1127                /* das-1701st-da, das-1702st-da, das-1801st-da, das-1802st-da */
1128                board = &das1800_boards[BOARD_DAS1801ST_DA];
1129                break;
1130        case DAS1800_ID_HR_DA:
1131                /* das-1702hr-da, das-1802hr-da */
1132                board = &das1800_boards[BOARD_DAS1802HR_DA];
1133                break;
1134        case DAS1800_ID_AO:
1135                /* das-1701ao, das-1702ao, das-1801ao, das-1802ao */
1136                board = &das1800_boards[BOARD_DAS1801AO];
1137                break;
1138        case DAS1800_ID_HR:
1139                /*  das-1702hr, das-1802hr */
1140                board = &das1800_boards[BOARD_DAS1802HR];
1141                break;
1142        case DAS1800_ID_ST:
1143                /* das-1701st, das-1702st, das-1801st, das-1802st */
1144                board = &das1800_boards[BOARD_DAS1801ST];
1145                break;
1146        case DAS1800_ID_HC:
1147                /* das-1801hc, das-1802hc */
1148                board = &das1800_boards[BOARD_DAS1801HC];
1149                break;
1150        default:
1151                dev_err(dev->class_dev, "invalid probe id 0x%x\n", id);
1152                return -ENODEV;
1153        }
1154        dev->board_ptr = board;
1155        dev->board_name = board->name;
1156        dev_warn(dev->class_dev,
1157                 "probed id 0x%0x: %s series (not recommended)\n",
1158                 id, board->name);
1159        return 0;
1160}
1161
1162static int das1800_attach(struct comedi_device *dev,
1163                          struct comedi_devconfig *it)
1164{
1165        const struct das1800_board *board;
1166        struct das1800_private *devpriv;
1167        struct comedi_subdevice *s;
1168        unsigned int irq = it->options[1];
1169        bool is_16bit;
1170        int ret;
1171        int i;
1172
1173        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1174        if (!devpriv)
1175                return -ENOMEM;
1176
1177        ret = comedi_request_region(dev, it->options[0], DAS1800_SIZE);
1178        if (ret)
1179                return ret;
1180
1181        ret = das1800_probe(dev);
1182        if (ret)
1183                return ret;
1184        board = dev->board_ptr;
1185
1186        is_16bit = board->id == DAS1800_ID_HR || board->id == DAS1800_ID_HR_DA;
1187
1188        /* waveform 'ao' boards have additional io ports */
1189        if (board->id == DAS1800_ID_AO) {
1190                unsigned long iobase2 = dev->iobase + IOBASE2;
1191
1192                ret = __comedi_request_region(dev, iobase2, DAS1800_SIZE);
1193                if (ret)
1194                        return ret;
1195                devpriv->iobase2 = iobase2;
1196        }
1197
1198        if (irq == 3 || irq == 5 || irq == 7 || irq == 10 || irq == 11 ||
1199            irq == 15) {
1200                ret = request_irq(irq, das1800_interrupt, 0,
1201                                  dev->board_name, dev);
1202                if (ret == 0) {
1203                        dev->irq = irq;
1204
1205                        switch (irq) {
1206                        case 3:
1207                                devpriv->irq_dma_bits |= 0x8;
1208                                break;
1209                        case 5:
1210                                devpriv->irq_dma_bits |= 0x10;
1211                                break;
1212                        case 7:
1213                                devpriv->irq_dma_bits |= 0x18;
1214                                break;
1215                        case 10:
1216                                devpriv->irq_dma_bits |= 0x28;
1217                                break;
1218                        case 11:
1219                                devpriv->irq_dma_bits |= 0x30;
1220                                break;
1221                        case 15:
1222                                devpriv->irq_dma_bits |= 0x38;
1223                                break;
1224                        }
1225                }
1226        }
1227
1228        /* an irq and one dma channel is required to use dma */
1229        if (dev->irq & it->options[2])
1230                das1800_init_dma(dev, it);
1231
1232        devpriv->fifo_buf = kmalloc_array(FIFO_SIZE,
1233                                          sizeof(*devpriv->fifo_buf),
1234                                          GFP_KERNEL);
1235        if (!devpriv->fifo_buf)
1236                return -ENOMEM;
1237
1238        dev->pacer = comedi_8254_init(dev->iobase + DAS1800_COUNTER,
1239                                      I8254_OSC_BASE_5MHZ, I8254_IO8, 0);
1240        if (!dev->pacer)
1241                return -ENOMEM;
1242
1243        ret = comedi_alloc_subdevices(dev, 4);
1244        if (ret)
1245                return ret;
1246
1247        /*
1248         * Analog Input subdevice
1249         *
1250         * The "hc" type boards have 64 analog input channels and a 64
1251         * entry QRAM fifo.
1252         *
1253         * All the other board types have 16 on-board channels. Each channel
1254         * can be expanded to 16 channels with the addition of an EXP-1800
1255         * expansion board for a total of 256 channels. The QRAM fifo on
1256         * these boards has 256 entries.
1257         *
1258         * From the datasheets it's not clear what the comedi channel to
1259         * actual physical channel mapping is when EXP-1800 boards are used.
1260         */
1261        s = &dev->subdevices[0];
1262        s->type         = COMEDI_SUBD_AI;
1263        s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
1264        if (board->id != DAS1800_ID_HC)
1265                s->subdev_flags |= SDF_COMMON;
1266        s->n_chan       = (board->id == DAS1800_ID_HC) ? 64 : 256;
1267        s->maxdata      = is_16bit ? 0xffff : 0x0fff;
1268        s->range_table  = board->is_01_series ? &das1801_ai_range
1269                                              : &das1802_ai_range;
1270        s->insn_read    = das1800_ai_insn_read;
1271        if (dev->irq) {
1272                dev->read_subdev = s;
1273                s->subdev_flags |= SDF_CMD_READ;
1274                s->len_chanlist = s->n_chan;
1275                s->do_cmd       = das1800_ai_cmd;
1276                s->do_cmdtest   = das1800_ai_cmdtest;
1277                s->poll         = das1800_ai_poll;
1278                s->cancel       = das1800_ai_cancel;
1279                s->munge        = das1800_ai_munge;
1280        }
1281
1282        /* Analog Output subdevice */
1283        s = &dev->subdevices[1];
1284        if (board->id == DAS1800_ID_ST_DA || board->id == DAS1800_ID_HR_DA) {
1285                s->type         = COMEDI_SUBD_AO;
1286                s->subdev_flags = SDF_WRITABLE;
1287                s->n_chan       = (board->id == DAS1800_ID_ST_DA) ? 4 : 2;
1288                s->maxdata      = is_16bit ? 0xffff : 0x0fff;
1289                s->range_table  = &range_bipolar10;
1290                s->insn_write   = das1800_ao_insn_write;
1291
1292                ret = comedi_alloc_subdev_readback(s);
1293                if (ret)
1294                        return ret;
1295
1296                /* initialize all channels to 0V */
1297                for (i = 0; i < s->n_chan; i++) {
1298                        /* spinlock is not necessary during the attach */
1299                        outb(DAC(i), dev->iobase + DAS1800_SELECT);
1300                        outw(0, dev->iobase + DAS1800_DAC);
1301                }
1302        } else if (board->id == DAS1800_ID_AO) {
1303                /*
1304                 * 'ao' boards have waveform analog outputs that are not
1305                 * currently supported.
1306                 */
1307                s->type         = COMEDI_SUBD_UNUSED;
1308        } else {
1309                s->type         = COMEDI_SUBD_UNUSED;
1310        }
1311
1312        /* Digital Input subdevice */
1313        s = &dev->subdevices[2];
1314        s->type         = COMEDI_SUBD_DI;
1315        s->subdev_flags = SDF_READABLE;
1316        s->n_chan       = 4;
1317        s->maxdata      = 1;
1318        s->range_table  = &range_digital;
1319        s->insn_bits    = das1800_di_insn_bits;
1320
1321        /* Digital Output subdevice */
1322        s = &dev->subdevices[3];
1323        s->type         = COMEDI_SUBD_DO;
1324        s->subdev_flags = SDF_WRITABLE;
1325        s->n_chan       = (board->id == DAS1800_ID_HC) ? 8 : 4;
1326        s->maxdata      = 1;
1327        s->range_table  = &range_digital;
1328        s->insn_bits    = das1800_do_insn_bits;
1329
1330        das1800_ai_cancel(dev, dev->read_subdev);
1331
1332        /*  initialize digital out channels */
1333        outb(0, dev->iobase + DAS1800_DIGITAL);
1334
1335        return 0;
1336};
1337
1338static void das1800_detach(struct comedi_device *dev)
1339{
1340        struct das1800_private *devpriv = dev->private;
1341
1342        das1800_free_dma(dev);
1343        if (devpriv) {
1344                kfree(devpriv->fifo_buf);
1345                if (devpriv->iobase2)
1346                        release_region(devpriv->iobase2, DAS1800_SIZE);
1347        }
1348        comedi_legacy_detach(dev);
1349}
1350
1351static struct comedi_driver das1800_driver = {
1352        .driver_name    = "das1800",
1353        .module         = THIS_MODULE,
1354        .attach         = das1800_attach,
1355        .detach         = das1800_detach,
1356        .num_names      = ARRAY_SIZE(das1800_boards),
1357        .board_name     = &das1800_boards[0].name,
1358        .offset         = sizeof(struct das1800_board),
1359};
1360module_comedi_driver(das1800_driver);
1361
1362MODULE_AUTHOR("Comedi https://www.comedi.org");
1363MODULE_DESCRIPTION("Comedi driver for DAS1800 compatible ISA boards");
1364MODULE_LICENSE("GPL");
1365