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