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 pacer_counter_dio;
 346        unsigned long ao_registers;
 347        /* divisors of master clock for analog input pacing */
 348        unsigned int divisor1;
 349        unsigned int divisor2;
 350        /* number of analog input samples remaining */
 351        unsigned int count;
 352        /* bits to write to registers */
 353        unsigned int adc_fifo_bits;
 354        unsigned int s5933_intcsr_bits;
 355        unsigned int ao_control_bits;
 356        /* fifo buffers */
 357        unsigned short ai_buffer[AI_BUFFER_SIZE];
 358        unsigned short ao_buffer[AO_BUFFER_SIZE];
 359        /* divisors of master clock for analog output pacing */
 360        unsigned int ao_divisor1;
 361        unsigned int ao_divisor2;
 362        /* number of analog output samples remaining */
 363        unsigned int ao_count;
 364        /* cached values for readback */
 365        unsigned short ao_value[2];
 366        unsigned int caldac_value[NUM_CHANNELS_8800];
 367        unsigned int trimpot_value[NUM_CHANNELS_8402];
 368        unsigned int dac08_value;
 369        unsigned int calibration_source;
 370};
 371
 372static inline unsigned int cal_enable_bits(struct comedi_device *dev)
 373{
 374        struct cb_pcidas_private *devpriv = dev->private;
 375
 376        return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
 377}
 378
 379static int cb_pcidas_ai_eoc(struct comedi_device *dev,
 380                            struct comedi_subdevice *s,
 381                            struct comedi_insn *insn,
 382                            unsigned long context)
 383{
 384        struct cb_pcidas_private *devpriv = dev->private;
 385        unsigned int status;
 386
 387        status = inw(devpriv->control_status + ADCMUX_CONT);
 388        if (status & EOC)
 389                return 0;
 390        return -EBUSY;
 391}
 392
 393static int cb_pcidas_ai_rinsn(struct comedi_device *dev,
 394                              struct comedi_subdevice *s,
 395                              struct comedi_insn *insn, unsigned int *data)
 396{
 397        struct cb_pcidas_private *devpriv = dev->private;
 398        unsigned int chan = CR_CHAN(insn->chanspec);
 399        unsigned int range = CR_RANGE(insn->chanspec);
 400        unsigned int aref = CR_AREF(insn->chanspec);
 401        unsigned int bits;
 402        int ret;
 403        int n;
 404
 405        /* enable calibration input if appropriate */
 406        if (insn->chanspec & CR_ALT_SOURCE) {
 407                outw(cal_enable_bits(dev),
 408                     devpriv->control_status + CALIBRATION_REG);
 409                chan = 0;
 410        } else {
 411                outw(0, devpriv->control_status + CALIBRATION_REG);
 412        }
 413
 414        /* set mux limits and gain */
 415        bits = BEGIN_SCAN(chan) | END_SCAN(chan) | GAIN_BITS(range);
 416        /* set unipolar/bipolar */
 417        if (range & IS_UNIPOLAR)
 418                bits |= UNIP;
 419        /* set single-ended/differential */
 420        if (aref != AREF_DIFF)
 421                bits |= SE;
 422        outw(bits, devpriv->control_status + ADCMUX_CONT);
 423
 424        /* clear fifo */
 425        outw(0, devpriv->adc_fifo + ADCFIFOCLR);
 426
 427        /* convert n samples */
 428        for (n = 0; n < insn->n; n++) {
 429                /* trigger conversion */
 430                outw(0, devpriv->adc_fifo + ADCDATA);
 431
 432                /* wait for conversion to end */
 433                ret = comedi_timeout(dev, s, insn, cb_pcidas_ai_eoc, 0);
 434                if (ret)
 435                        return ret;
 436
 437                /* read data */
 438                data[n] = inw(devpriv->adc_fifo + ADCDATA);
 439        }
 440
 441        /* return the number of samples read/written */
 442        return n;
 443}
 444
 445static int ai_config_insn(struct comedi_device *dev, struct comedi_subdevice *s,
 446                          struct comedi_insn *insn, unsigned int *data)
 447{
 448        struct cb_pcidas_private *devpriv = dev->private;
 449        int id = data[0];
 450        unsigned int source = data[1];
 451
 452        switch (id) {
 453        case INSN_CONFIG_ALT_SOURCE:
 454                if (source >= 8) {
 455                        dev_err(dev->class_dev,
 456                                "invalid calibration source: %i\n",
 457                                source);
 458                        return -EINVAL;
 459                }
 460                devpriv->calibration_source = source;
 461                break;
 462        default:
 463                return -EINVAL;
 464                break;
 465        }
 466        return insn->n;
 467}
 468
 469/* analog output insn for pcidas-1000 and 1200 series */
 470static int cb_pcidas_ao_nofifo_winsn(struct comedi_device *dev,
 471                                     struct comedi_subdevice *s,
 472                                     struct comedi_insn *insn,
 473                                     unsigned int *data)
 474{
 475        struct cb_pcidas_private *devpriv = dev->private;
 476        unsigned int chan = CR_CHAN(insn->chanspec);
 477        unsigned int range = CR_RANGE(insn->chanspec);
 478        unsigned long flags;
 479
 480        /* set channel and range */
 481        spin_lock_irqsave(&dev->spinlock, flags);
 482        devpriv->ao_control_bits &= (~DAC_MODE_UPDATE_BOTH &
 483                                     ~DAC_RANGE_MASK(chan));
 484        devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range));
 485        outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
 486        spin_unlock_irqrestore(&dev->spinlock, flags);
 487
 488        /* remember value for readback */
 489        devpriv->ao_value[chan] = data[0];
 490
 491        /* send data */
 492        outw(data[0], devpriv->ao_registers + DAC_DATA_REG(chan));
 493
 494        return insn->n;
 495}
 496
 497/* analog output insn for pcidas-1602 series */
 498static int cb_pcidas_ao_fifo_winsn(struct comedi_device *dev,
 499                                   struct comedi_subdevice *s,
 500                                   struct comedi_insn *insn, unsigned int *data)
 501{
 502        struct cb_pcidas_private *devpriv = dev->private;
 503        unsigned int chan = CR_CHAN(insn->chanspec);
 504        unsigned int range = CR_RANGE(insn->chanspec);
 505        unsigned long flags;
 506
 507        /* clear dac fifo */
 508        outw(0, devpriv->ao_registers + DACFIFOCLR);
 509
 510        /* set channel and range */
 511        spin_lock_irqsave(&dev->spinlock, flags);
 512        devpriv->ao_control_bits &= (~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) &
 513                                     ~DAC_RANGE_MASK(chan) & ~DAC_PACER_MASK);
 514        devpriv->ao_control_bits |= (DACEN | DAC_RANGE(chan, range) |
 515                                     DAC_CHAN_EN(chan) | DAC_START);
 516        outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
 517        spin_unlock_irqrestore(&dev->spinlock, flags);
 518
 519        /* remember value for readback */
 520        devpriv->ao_value[chan] = data[0];
 521
 522        /* send data */
 523        outw(data[0], devpriv->ao_registers + DACDATA);
 524
 525        return insn->n;
 526}
 527
 528static int cb_pcidas_ao_readback_insn(struct comedi_device *dev,
 529                                      struct comedi_subdevice *s,
 530                                      struct comedi_insn *insn,
 531                                      unsigned int *data)
 532{
 533        struct cb_pcidas_private *devpriv = dev->private;
 534
 535        data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
 536
 537        return 1;
 538}
 539
 540static int wait_for_nvram_ready(unsigned long s5933_base_addr)
 541{
 542        static const int timeout = 1000;
 543        unsigned int i;
 544
 545        for (i = 0; i < timeout; i++) {
 546                if ((inb(s5933_base_addr +
 547                         AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
 548                    == 0)
 549                        return 0;
 550                udelay(1);
 551        }
 552        return -1;
 553}
 554
 555static int nvram_read(struct comedi_device *dev, unsigned int address,
 556                        uint8_t *data)
 557{
 558        struct cb_pcidas_private *devpriv = dev->private;
 559        unsigned long iobase = devpriv->s5933_config;
 560
 561        if (wait_for_nvram_ready(iobase) < 0)
 562                return -ETIMEDOUT;
 563
 564        outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
 565             iobase + AMCC_OP_REG_MCSR_NVCMD);
 566        outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
 567        outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
 568             iobase + AMCC_OP_REG_MCSR_NVCMD);
 569        outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
 570        outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
 571
 572        if (wait_for_nvram_ready(iobase) < 0)
 573                return -ETIMEDOUT;
 574
 575        *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
 576
 577        return 0;
 578}
 579
 580static int eeprom_read_insn(struct comedi_device *dev,
 581                            struct comedi_subdevice *s,
 582                            struct comedi_insn *insn, unsigned int *data)
 583{
 584        uint8_t nvram_data;
 585        int retval;
 586
 587        retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
 588        if (retval < 0)
 589                return retval;
 590
 591        data[0] = nvram_data;
 592
 593        return 1;
 594}
 595
 596static void write_calibration_bitstream(struct comedi_device *dev,
 597                                        unsigned int register_bits,
 598                                        unsigned int bitstream,
 599                                        unsigned int bitstream_length)
 600{
 601        struct cb_pcidas_private *devpriv = dev->private;
 602        static const int write_delay = 1;
 603        unsigned int bit;
 604
 605        for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
 606                if (bitstream & bit)
 607                        register_bits |= SERIAL_DATA_IN_BIT;
 608                else
 609                        register_bits &= ~SERIAL_DATA_IN_BIT;
 610                udelay(write_delay);
 611                outw(register_bits, devpriv->control_status + CALIBRATION_REG);
 612        }
 613}
 614
 615static int caldac_8800_write(struct comedi_device *dev, unsigned int address,
 616                             uint8_t value)
 617{
 618        struct cb_pcidas_private *devpriv = dev->private;
 619        static const int num_caldac_channels = 8;
 620        static const int bitstream_length = 11;
 621        unsigned int bitstream = ((address & 0x7) << 8) | value;
 622        static const int caldac_8800_udelay = 1;
 623
 624        if (address >= num_caldac_channels) {
 625                comedi_error(dev, "illegal caldac channel");
 626                return -1;
 627        }
 628
 629        if (value == devpriv->caldac_value[address])
 630                return 1;
 631
 632        devpriv->caldac_value[address] = value;
 633
 634        write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
 635                                    bitstream_length);
 636
 637        udelay(caldac_8800_udelay);
 638        outw(cal_enable_bits(dev) | SELECT_8800_BIT,
 639             devpriv->control_status + CALIBRATION_REG);
 640        udelay(caldac_8800_udelay);
 641        outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
 642
 643        return 1;
 644}
 645
 646static int caldac_write_insn(struct comedi_device *dev,
 647                             struct comedi_subdevice *s,
 648                             struct comedi_insn *insn, unsigned int *data)
 649{
 650        const unsigned int channel = CR_CHAN(insn->chanspec);
 651
 652        return caldac_8800_write(dev, channel, data[0]);
 653}
 654
 655static int caldac_read_insn(struct comedi_device *dev,
 656                            struct comedi_subdevice *s,
 657                            struct comedi_insn *insn, unsigned int *data)
 658{
 659        struct cb_pcidas_private *devpriv = dev->private;
 660
 661        data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
 662
 663        return 1;
 664}
 665
 666/* 1602/16 pregain offset */
 667static void dac08_write(struct comedi_device *dev, unsigned int value)
 668{
 669        struct cb_pcidas_private *devpriv = dev->private;
 670        unsigned long cal_reg;
 671
 672        if (devpriv->dac08_value != value) {
 673                devpriv->dac08_value = value;
 674
 675                cal_reg = devpriv->control_status + CALIBRATION_REG;
 676
 677                value &= 0xff;
 678                value |= cal_enable_bits(dev);
 679
 680                /* latch the new value into the caldac */
 681                outw(value, cal_reg);
 682                udelay(1);
 683                outw(value | SELECT_DAC08_BIT, cal_reg);
 684                udelay(1);
 685                outw(value, cal_reg);
 686                udelay(1);
 687        }
 688}
 689
 690static int dac08_write_insn(struct comedi_device *dev,
 691                            struct comedi_subdevice *s,
 692                            struct comedi_insn *insn, unsigned int *data)
 693{
 694        int i;
 695
 696        for (i = 0; i < insn->n; i++)
 697                dac08_write(dev, data[i]);
 698
 699        return insn->n;
 700}
 701
 702static int dac08_read_insn(struct comedi_device *dev,
 703                           struct comedi_subdevice *s, struct comedi_insn *insn,
 704                           unsigned int *data)
 705{
 706        struct cb_pcidas_private *devpriv = dev->private;
 707
 708        data[0] = devpriv->dac08_value;
 709
 710        return 1;
 711}
 712
 713static int trimpot_7376_write(struct comedi_device *dev, uint8_t value)
 714{
 715        struct cb_pcidas_private *devpriv = dev->private;
 716        static const int bitstream_length = 7;
 717        unsigned int bitstream = value & 0x7f;
 718        unsigned int register_bits;
 719        static const int ad7376_udelay = 1;
 720
 721        register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
 722        udelay(ad7376_udelay);
 723        outw(register_bits, devpriv->control_status + CALIBRATION_REG);
 724
 725        write_calibration_bitstream(dev, register_bits, bitstream,
 726                                    bitstream_length);
 727
 728        udelay(ad7376_udelay);
 729        outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
 730
 731        return 0;
 732}
 733
 734/* For 1602/16 only
 735 * ch 0 : adc gain
 736 * ch 1 : adc postgain offset */
 737static int trimpot_8402_write(struct comedi_device *dev, unsigned int channel,
 738                              uint8_t value)
 739{
 740        struct cb_pcidas_private *devpriv = dev->private;
 741        static const int bitstream_length = 10;
 742        unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
 743        unsigned int register_bits;
 744        static const int ad8402_udelay = 1;
 745
 746        register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
 747        udelay(ad8402_udelay);
 748        outw(register_bits, devpriv->control_status + CALIBRATION_REG);
 749
 750        write_calibration_bitstream(dev, register_bits, bitstream,
 751                                    bitstream_length);
 752
 753        udelay(ad8402_udelay);
 754        outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
 755
 756        return 0;
 757}
 758
 759static int cb_pcidas_trimpot_write(struct comedi_device *dev,
 760                                   unsigned int channel, unsigned int value)
 761{
 762        const struct cb_pcidas_board *thisboard = comedi_board(dev);
 763        struct cb_pcidas_private *devpriv = dev->private;
 764
 765        if (devpriv->trimpot_value[channel] == value)
 766                return 1;
 767
 768        devpriv->trimpot_value[channel] = value;
 769        switch (thisboard->trimpot) {
 770        case AD7376:
 771                trimpot_7376_write(dev, value);
 772                break;
 773        case AD8402:
 774                trimpot_8402_write(dev, channel, value);
 775                break;
 776        default:
 777                comedi_error(dev, "driver bug?");
 778                return -1;
 779                break;
 780        }
 781
 782        return 1;
 783}
 784
 785static int trimpot_write_insn(struct comedi_device *dev,
 786                              struct comedi_subdevice *s,
 787                              struct comedi_insn *insn, unsigned int *data)
 788{
 789        unsigned int channel = CR_CHAN(insn->chanspec);
 790
 791        return cb_pcidas_trimpot_write(dev, channel, data[0]);
 792}
 793
 794static int trimpot_read_insn(struct comedi_device *dev,
 795                             struct comedi_subdevice *s,
 796                             struct comedi_insn *insn, unsigned int *data)
 797{
 798        struct cb_pcidas_private *devpriv = dev->private;
 799        unsigned int channel = CR_CHAN(insn->chanspec);
 800
 801        data[0] = devpriv->trimpot_value[channel];
 802
 803        return 1;
 804}
 805
 806static int cb_pcidas_ai_check_chanlist(struct comedi_device *dev,
 807                                       struct comedi_subdevice *s,
 808                                       struct comedi_cmd *cmd)
 809{
 810        unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
 811        unsigned int range0 = CR_RANGE(cmd->chanlist[0]);
 812        int i;
 813
 814        for (i = 1; i < cmd->chanlist_len; i++) {
 815                unsigned int chan = CR_CHAN(cmd->chanlist[i]);
 816                unsigned int range = CR_RANGE(cmd->chanlist[i]);
 817
 818                if (chan != (chan0 + i) % s->n_chan) {
 819                        dev_dbg(dev->class_dev,
 820                                "entries in chanlist must be consecutive channels, counting upwards\n");
 821                        return -EINVAL;
 822                }
 823
 824                if (range != range0) {
 825                        dev_dbg(dev->class_dev,
 826                                "entries in chanlist must all have the same gain\n");
 827                        return -EINVAL;
 828                }
 829        }
 830        return 0;
 831}
 832
 833static int cb_pcidas_ai_cmdtest(struct comedi_device *dev,
 834                                struct comedi_subdevice *s,
 835                                struct comedi_cmd *cmd)
 836{
 837        const struct cb_pcidas_board *thisboard = comedi_board(dev);
 838        struct cb_pcidas_private *devpriv = dev->private;
 839        int err = 0;
 840        unsigned int arg;
 841
 842        /* Step 1 : check if triggers are trivially valid */
 843
 844        err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_EXT);
 845        err |= cfc_check_trigger_src(&cmd->scan_begin_src,
 846                                        TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT);
 847        err |= cfc_check_trigger_src(&cmd->convert_src,
 848                                        TRIG_TIMER | TRIG_NOW | TRIG_EXT);
 849        err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 850        err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 851
 852        if (err)
 853                return 1;
 854
 855        /* Step 2a : make sure trigger sources are unique */
 856
 857        err |= cfc_check_trigger_is_unique(cmd->start_src);
 858        err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
 859        err |= cfc_check_trigger_is_unique(cmd->convert_src);
 860        err |= cfc_check_trigger_is_unique(cmd->stop_src);
 861
 862        /* Step 2b : and mutually compatible */
 863
 864        if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
 865                err |= -EINVAL;
 866        if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
 867                err |= -EINVAL;
 868        if (cmd->start_src == TRIG_EXT &&
 869            (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT))
 870                err |= -EINVAL;
 871
 872        if (err)
 873                return 2;
 874
 875        /* Step 3: check if arguments are trivially valid */
 876
 877        switch (cmd->start_src) {
 878        case TRIG_NOW:
 879                err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
 880                break;
 881        case TRIG_EXT:
 882                /* External trigger, only CR_EDGE and CR_INVERT flags allowed */
 883                if ((cmd->start_arg
 884                     & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) != 0) {
 885                        cmd->start_arg &= ~(CR_FLAGS_MASK &
 886                                                ~(CR_EDGE | CR_INVERT));
 887                        err |= -EINVAL;
 888                }
 889                if (!thisboard->is_1602 && (cmd->start_arg & CR_INVERT)) {
 890                        cmd->start_arg &= (CR_FLAGS_MASK & ~CR_INVERT);
 891                        err |= -EINVAL;
 892                }
 893                break;
 894        }
 895
 896        if (cmd->scan_begin_src == TRIG_TIMER)
 897                err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
 898                                thisboard->ai_speed * cmd->chanlist_len);
 899
 900        if (cmd->convert_src == TRIG_TIMER)
 901                err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
 902                                                 thisboard->ai_speed);
 903
 904        err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
 905
 906        if (cmd->stop_src == TRIG_NONE)
 907                err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 908
 909        if (err)
 910                return 3;
 911
 912        /* step 4: fix up any arguments */
 913
 914        if (cmd->scan_begin_src == TRIG_TIMER) {
 915                arg = cmd->scan_begin_arg;
 916                i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
 917                                          &devpriv->divisor1,
 918                                          &devpriv->divisor2,
 919                                          &arg, cmd->flags);
 920                err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
 921        }
 922        if (cmd->convert_src == TRIG_TIMER) {
 923                arg = cmd->convert_arg;
 924                i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
 925                                          &devpriv->divisor1,
 926                                          &devpriv->divisor2,
 927                                          &arg, cmd->flags);
 928                err |= cfc_check_trigger_arg_is(&cmd->convert_arg, arg);
 929        }
 930
 931        if (err)
 932                return 4;
 933
 934        /* Step 5: check channel list if it exists */
 935        if (cmd->chanlist && cmd->chanlist_len > 0)
 936                err |= cb_pcidas_ai_check_chanlist(dev, s, cmd);
 937
 938        if (err)
 939                return 5;
 940
 941        return 0;
 942}
 943
 944static void cb_pcidas_ai_load_counters(struct comedi_device *dev)
 945{
 946        struct cb_pcidas_private *devpriv = dev->private;
 947        unsigned long timer_base = devpriv->pacer_counter_dio + ADC8254;
 948
 949        i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
 950        i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
 951
 952        i8254_write(timer_base, 0, 1, devpriv->divisor1);
 953        i8254_write(timer_base, 0, 2, devpriv->divisor2);
 954}
 955
 956static int cb_pcidas_ai_cmd(struct comedi_device *dev,
 957                            struct comedi_subdevice *s)
 958{
 959        const struct cb_pcidas_board *thisboard = comedi_board(dev);
 960        struct cb_pcidas_private *devpriv = dev->private;
 961        struct comedi_async *async = s->async;
 962        struct comedi_cmd *cmd = &async->cmd;
 963        unsigned int bits;
 964        unsigned long flags;
 965
 966        /*  make sure CAL_EN_BIT is disabled */
 967        outw(0, devpriv->control_status + CALIBRATION_REG);
 968        /*  initialize before settings pacer source and count values */
 969        outw(0, devpriv->control_status + TRIG_CONTSTAT);
 970        /*  clear fifo */
 971        outw(0, devpriv->adc_fifo + ADCFIFOCLR);
 972
 973        /*  set mux limits, gain and pacer source */
 974        bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
 975            END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
 976            GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
 977        /*  set unipolar/bipolar */
 978        if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
 979                bits |= UNIP;
 980        /*  set singleended/differential */
 981        if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
 982                bits |= SE;
 983        /*  set pacer source */
 984        if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
 985                bits |= PACER_EXT_RISE;
 986        else
 987                bits |= PACER_INT;
 988        outw(bits, devpriv->control_status + ADCMUX_CONT);
 989
 990        /*  load counters */
 991        if (cmd->scan_begin_src == TRIG_TIMER || cmd->convert_src == TRIG_TIMER)
 992                cb_pcidas_ai_load_counters(dev);
 993
 994        /*  set number of conversions */
 995        if (cmd->stop_src == TRIG_COUNT)
 996                devpriv->count = cmd->chanlist_len * cmd->stop_arg;
 997        /*  enable interrupts */
 998        spin_lock_irqsave(&dev->spinlock, flags);
 999        devpriv->adc_fifo_bits |= INTE;
1000        devpriv->adc_fifo_bits &= ~INT_MASK;
1001        if (cmd->flags & TRIG_WAKE_EOS) {
1002                if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1) {
1003                        /* interrupt end of burst */
1004                        devpriv->adc_fifo_bits |= INT_EOS;
1005                } else {
1006                        /* interrupt fifo not empty */
1007                        devpriv->adc_fifo_bits |= INT_FNE;
1008                }
1009        } else {
1010                /* interrupt fifo half full */
1011                devpriv->adc_fifo_bits |= INT_FHF;
1012        }
1013
1014        /*  enable (and clear) interrupts */
1015        outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
1016             devpriv->control_status + INT_ADCFIFO);
1017        spin_unlock_irqrestore(&dev->spinlock, flags);
1018
1019        /*  set start trigger and burst mode */
1020        bits = 0;
1021        if (cmd->start_src == TRIG_NOW) {
1022                bits |= SW_TRIGGER;
1023        } else {        /* TRIG_EXT */
1024                bits |= EXT_TRIGGER | TGEN | XTRCL;
1025                if (thisboard->is_1602) {
1026                        if (cmd->start_arg & CR_INVERT)
1027                                bits |= TGPOL;
1028                        if (cmd->start_arg & CR_EDGE)
1029                                bits |= TGSEL;
1030                }
1031        }
1032        if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
1033                bits |= BURSTE;
1034        outw(bits, devpriv->control_status + TRIG_CONTSTAT);
1035
1036        return 0;
1037}
1038
1039static int cb_pcidas_ao_check_chanlist(struct comedi_device *dev,
1040                                       struct comedi_subdevice *s,
1041                                       struct comedi_cmd *cmd)
1042{
1043        unsigned int chan0 = CR_CHAN(cmd->chanlist[0]);
1044
1045        if (cmd->chanlist_len > 1) {
1046                unsigned int chan1 = CR_CHAN(cmd->chanlist[1]);
1047
1048                if (chan0 != 0 || chan1 != 1) {
1049                        dev_dbg(dev->class_dev,
1050                                "channels must be ordered channel 0, channel 1 in chanlist\n");
1051                        return -EINVAL;
1052                }
1053        }
1054
1055        return 0;
1056}
1057
1058static int cb_pcidas_ao_cmdtest(struct comedi_device *dev,
1059                                struct comedi_subdevice *s,
1060                                struct comedi_cmd *cmd)
1061{
1062        const struct cb_pcidas_board *thisboard = comedi_board(dev);
1063        struct cb_pcidas_private *devpriv = dev->private;
1064        int err = 0;
1065        unsigned int arg;
1066
1067        /* Step 1 : check if triggers are trivially valid */
1068
1069        err |= cfc_check_trigger_src(&cmd->start_src, TRIG_INT);
1070        err |= cfc_check_trigger_src(&cmd->scan_begin_src,
1071                                        TRIG_TIMER | TRIG_EXT);
1072        err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
1073        err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1074        err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
1075
1076        if (err)
1077                return 1;
1078
1079        /* Step 2a : make sure trigger sources are unique */
1080
1081        err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1082        err |= cfc_check_trigger_is_unique(cmd->stop_src);
1083
1084        /* Step 2b : and mutually compatible */
1085
1086        if (err)
1087                return 2;
1088
1089        /* Step 3: check if arguments are trivially valid */
1090
1091        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1092
1093        if (cmd->scan_begin_src == TRIG_TIMER)
1094                err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1095                                                 thisboard->ao_scan_speed);
1096
1097        err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
1098
1099        if (cmd->stop_src == TRIG_NONE)
1100                err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1101
1102        if (err)
1103                return 3;
1104
1105        /* step 4: fix up any arguments */
1106
1107        if (cmd->scan_begin_src == TRIG_TIMER) {
1108                arg = cmd->scan_begin_arg;
1109                i8253_cascade_ns_to_timer(I8254_OSC_BASE_10MHZ,
1110                                          &devpriv->ao_divisor1,
1111                                          &devpriv->ao_divisor2,
1112                                          &arg, cmd->flags);
1113                err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
1114        }
1115
1116        if (err)
1117                return 4;
1118
1119        /* Step 5: check channel list if it exists */
1120        if (cmd->chanlist && cmd->chanlist_len > 0)
1121                err |= cb_pcidas_ao_check_chanlist(dev, s, cmd);
1122
1123        if (err)
1124                return 5;
1125
1126        return 0;
1127}
1128
1129/* cancel analog input command */
1130static int cb_pcidas_cancel(struct comedi_device *dev,
1131                            struct comedi_subdevice *s)
1132{
1133        struct cb_pcidas_private *devpriv = dev->private;
1134        unsigned long flags;
1135
1136        spin_lock_irqsave(&dev->spinlock, flags);
1137        /*  disable interrupts */
1138        devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
1139        outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1140        spin_unlock_irqrestore(&dev->spinlock, flags);
1141
1142        /*  disable start trigger source and burst mode */
1143        outw(0, devpriv->control_status + TRIG_CONTSTAT);
1144        /*  software pacer source */
1145        outw(0, devpriv->control_status + ADCMUX_CONT);
1146
1147        return 0;
1148}
1149
1150static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
1151                                struct comedi_subdevice *s,
1152                                unsigned int trig_num)
1153{
1154        const struct cb_pcidas_board *thisboard = comedi_board(dev);
1155        struct cb_pcidas_private *devpriv = dev->private;
1156        unsigned int num_bytes, num_points = thisboard->fifo_size;
1157        struct comedi_async *async = s->async;
1158        struct comedi_cmd *cmd = &s->async->cmd;
1159        unsigned long flags;
1160
1161        if (trig_num != cmd->start_arg)
1162                return -EINVAL;
1163
1164        /*  load up fifo */
1165        if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
1166                num_points = devpriv->ao_count;
1167
1168        num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1169                                               num_points * sizeof(short));
1170        num_points = num_bytes / sizeof(short);
1171
1172        if (cmd->stop_src == TRIG_COUNT)
1173                devpriv->ao_count -= num_points;
1174        /*  write data to board's fifo */
1175        outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
1176
1177        /*  enable dac half-full and empty interrupts */
1178        spin_lock_irqsave(&dev->spinlock, flags);
1179        devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
1180
1181        /*  enable and clear interrupts */
1182        outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
1183             devpriv->control_status + INT_ADCFIFO);
1184
1185        /*  start dac */
1186        devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
1187        outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1188
1189        spin_unlock_irqrestore(&dev->spinlock, flags);
1190
1191        async->inttrig = NULL;
1192
1193        return 0;
1194}
1195
1196static void cb_pcidas_ao_load_counters(struct comedi_device *dev)
1197{
1198        struct cb_pcidas_private *devpriv = dev->private;
1199        unsigned long timer_base = devpriv->pacer_counter_dio + DAC8254;
1200
1201        i8254_set_mode(timer_base, 0, 1, I8254_MODE2 | I8254_BINARY);
1202        i8254_set_mode(timer_base, 0, 2, I8254_MODE2 | I8254_BINARY);
1203
1204        i8254_write(timer_base, 0, 1, devpriv->ao_divisor1);
1205        i8254_write(timer_base, 0, 2, devpriv->ao_divisor2);
1206}
1207
1208static int cb_pcidas_ao_cmd(struct comedi_device *dev,
1209                            struct comedi_subdevice *s)
1210{
1211        struct cb_pcidas_private *devpriv = dev->private;
1212        struct comedi_async *async = s->async;
1213        struct comedi_cmd *cmd = &async->cmd;
1214        unsigned int i;
1215        unsigned long flags;
1216
1217        /*  set channel limits, gain */
1218        spin_lock_irqsave(&dev->spinlock, flags);
1219        for (i = 0; i < cmd->chanlist_len; i++) {
1220                /*  enable channel */
1221                devpriv->ao_control_bits |=
1222                    DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
1223                /*  set range */
1224                devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
1225                                                      CR_RANGE(cmd->
1226                                                               chanlist[i]));
1227        }
1228
1229        /*  disable analog out before settings pacer source and count values */
1230        outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1231        spin_unlock_irqrestore(&dev->spinlock, flags);
1232
1233        /*  clear fifo */
1234        outw(0, devpriv->ao_registers + DACFIFOCLR);
1235
1236        /*  load counters */
1237        if (cmd->scan_begin_src == TRIG_TIMER)
1238                cb_pcidas_ao_load_counters(dev);
1239
1240        /*  set number of conversions */
1241        if (cmd->stop_src == TRIG_COUNT)
1242                devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
1243        /*  set pacer source */
1244        spin_lock_irqsave(&dev->spinlock, flags);
1245        switch (cmd->scan_begin_src) {
1246        case TRIG_TIMER:
1247                devpriv->ao_control_bits |= DAC_PACER_INT;
1248                break;
1249        case TRIG_EXT:
1250                devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
1251                break;
1252        default:
1253                spin_unlock_irqrestore(&dev->spinlock, flags);
1254                comedi_error(dev, "error setting dac pacer source");
1255                return -1;
1256                break;
1257        }
1258        spin_unlock_irqrestore(&dev->spinlock, flags);
1259
1260        async->inttrig = cb_pcidas_ao_inttrig;
1261
1262        return 0;
1263}
1264
1265/* cancel analog output command */
1266static int cb_pcidas_ao_cancel(struct comedi_device *dev,
1267                               struct comedi_subdevice *s)
1268{
1269        struct cb_pcidas_private *devpriv = dev->private;
1270        unsigned long flags;
1271
1272        spin_lock_irqsave(&dev->spinlock, flags);
1273        /*  disable interrupts */
1274        devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
1275        outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
1276
1277        /*  disable output */
1278        devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
1279        outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
1280        spin_unlock_irqrestore(&dev->spinlock, flags);
1281
1282        return 0;
1283}
1284
1285static void handle_ao_interrupt(struct comedi_device *dev, unsigned int status)
1286{
1287        const struct cb_pcidas_board *thisboard = comedi_board(dev);
1288        struct cb_pcidas_private *devpriv = dev->private;
1289        struct comedi_subdevice *s = dev->write_subdev;
1290        struct comedi_async *async = s->async;
1291        struct comedi_cmd *cmd = &async->cmd;
1292        unsigned int half_fifo = thisboard->fifo_size / 2;
1293        unsigned int num_points;
1294        unsigned long flags;
1295
1296        if (status & DAEMI) {
1297                /*  clear dac empty interrupt latch */
1298                spin_lock_irqsave(&dev->spinlock, flags);
1299                outw(devpriv->adc_fifo_bits | DAEMI,
1300                     devpriv->control_status + INT_ADCFIFO);
1301                spin_unlock_irqrestore(&dev->spinlock, flags);
1302                if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
1303                        if (cmd->stop_src == TRIG_NONE ||
1304                            (cmd->stop_src == TRIG_COUNT
1305                             && devpriv->ao_count)) {
1306                                comedi_error(dev, "dac fifo underflow");
1307                                async->events |= COMEDI_CB_ERROR;
1308                        }
1309                        async->events |= COMEDI_CB_EOA;
1310                }
1311        } else if (status & DAHFI) {
1312                unsigned int num_bytes;
1313
1314                /*  figure out how many points we are writing to fifo */
1315                num_points = half_fifo;
1316                if (cmd->stop_src == TRIG_COUNT &&
1317                    devpriv->ao_count < num_points)
1318                        num_points = devpriv->ao_count;
1319                num_bytes =
1320                    cfc_read_array_from_buffer(s, devpriv->ao_buffer,
1321                                               num_points * sizeof(short));
1322                num_points = num_bytes / sizeof(short);
1323
1324                if (cmd->stop_src == TRIG_COUNT)
1325                        devpriv->ao_count -= num_points;
1326                /*  write data to board's fifo */
1327                outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
1328                      num_points);
1329                /*  clear half-full interrupt latch */
1330                spin_lock_irqsave(&dev->spinlock, flags);
1331                outw(devpriv->adc_fifo_bits | DAHFI,
1332                     devpriv->control_status + INT_ADCFIFO);
1333                spin_unlock_irqrestore(&dev->spinlock, flags);
1334        }
1335
1336        cfc_handle_events(dev, s);
1337}
1338
1339static irqreturn_t cb_pcidas_interrupt(int irq, void *d)
1340{
1341        struct comedi_device *dev = (struct comedi_device *)d;
1342        const struct cb_pcidas_board *thisboard = comedi_board(dev);
1343        struct cb_pcidas_private *devpriv = dev->private;
1344        struct comedi_subdevice *s = dev->read_subdev;
1345        struct comedi_async *async;
1346        struct comedi_cmd *cmd;
1347        int status, s5933_status;
1348        int half_fifo = thisboard->fifo_size / 2;
1349        unsigned int num_samples, i;
1350        static const int timeout = 10000;
1351        unsigned long flags;
1352
1353        if (!dev->attached)
1354                return IRQ_NONE;
1355
1356        async = s->async;
1357        cmd = &async->cmd;
1358
1359        s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1360
1361        if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
1362                return IRQ_NONE;
1363
1364        /*  make sure mailbox 4 is empty */
1365        inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1366        /*  clear interrupt on amcc s5933 */
1367        outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1368             devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1369
1370        status = inw(devpriv->control_status + INT_ADCFIFO);
1371
1372        /*  check for analog output interrupt */
1373        if (status & (DAHFI | DAEMI))
1374                handle_ao_interrupt(dev, status);
1375        /*  check for analog input interrupts */
1376        /*  if fifo half-full */
1377        if (status & ADHFI) {
1378                /*  read data */
1379                num_samples = half_fifo;
1380                if (cmd->stop_src == TRIG_COUNT &&
1381                    num_samples > devpriv->count) {
1382                        num_samples = devpriv->count;
1383                }
1384                insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
1385                     num_samples);
1386                cfc_write_array_to_buffer(s, devpriv->ai_buffer,
1387                                          num_samples * sizeof(short));
1388                devpriv->count -= num_samples;
1389                if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
1390                        async->events |= COMEDI_CB_EOA;
1391                /*  clear half-full interrupt latch */
1392                spin_lock_irqsave(&dev->spinlock, flags);
1393                outw(devpriv->adc_fifo_bits | INT,
1394                     devpriv->control_status + INT_ADCFIFO);
1395                spin_unlock_irqrestore(&dev->spinlock, flags);
1396                /*  else if fifo not empty */
1397        } else if (status & (ADNEI | EOBI)) {
1398                for (i = 0; i < timeout; i++) {
1399                        /*  break if fifo is empty */
1400                        if ((ADNE & inw(devpriv->control_status +
1401                                        INT_ADCFIFO)) == 0)
1402                                break;
1403                        cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
1404                        if (cmd->stop_src == TRIG_COUNT &&
1405                            --devpriv->count == 0) {
1406                                /* end of acquisition */
1407                                async->events |= COMEDI_CB_EOA;
1408                                break;
1409                        }
1410                }
1411                /*  clear not-empty interrupt latch */
1412                spin_lock_irqsave(&dev->spinlock, flags);
1413                outw(devpriv->adc_fifo_bits | INT,
1414                     devpriv->control_status + INT_ADCFIFO);
1415                spin_unlock_irqrestore(&dev->spinlock, flags);
1416        } else if (status & EOAI) {
1417                comedi_error(dev,
1418                             "bug! encountered end of acquisition interrupt?");
1419                /*  clear EOA interrupt latch */
1420                spin_lock_irqsave(&dev->spinlock, flags);
1421                outw(devpriv->adc_fifo_bits | EOAI,
1422                     devpriv->control_status + INT_ADCFIFO);
1423                spin_unlock_irqrestore(&dev->spinlock, flags);
1424        }
1425        /* check for fifo overflow */
1426        if (status & LADFUL) {
1427                comedi_error(dev, "fifo overflow");
1428                /*  clear overflow interrupt latch */
1429                spin_lock_irqsave(&dev->spinlock, flags);
1430                outw(devpriv->adc_fifo_bits | LADFUL,
1431                     devpriv->control_status + INT_ADCFIFO);
1432                spin_unlock_irqrestore(&dev->spinlock, flags);
1433                async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1434        }
1435
1436        cfc_handle_events(dev, s);
1437
1438        return IRQ_HANDLED;
1439}
1440
1441static int cb_pcidas_auto_attach(struct comedi_device *dev,
1442                                 unsigned long context)
1443{
1444        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1445        const struct cb_pcidas_board *thisboard = NULL;
1446        struct cb_pcidas_private *devpriv;
1447        struct comedi_subdevice *s;
1448        int i;
1449        int ret;
1450
1451        if (context < ARRAY_SIZE(cb_pcidas_boards))
1452                thisboard = &cb_pcidas_boards[context];
1453        if (!thisboard)
1454                return -ENODEV;
1455        dev->board_ptr  = thisboard;
1456        dev->board_name = thisboard->name;
1457
1458        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
1459        if (!devpriv)
1460                return -ENOMEM;
1461
1462        ret = comedi_pci_enable(dev);
1463        if (ret)
1464                return ret;
1465
1466        devpriv->s5933_config = pci_resource_start(pcidev, 0);
1467        devpriv->control_status = pci_resource_start(pcidev, 1);
1468        devpriv->adc_fifo = pci_resource_start(pcidev, 2);
1469        devpriv->pacer_counter_dio = pci_resource_start(pcidev, 3);
1470        if (thisboard->ao_nchan)
1471                devpriv->ao_registers = pci_resource_start(pcidev, 4);
1472
1473        /*  disable and clear interrupts on amcc s5933 */
1474        outl(INTCSR_INBOX_INTR_STATUS,
1475             devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1476
1477        if (request_irq(pcidev->irq, cb_pcidas_interrupt,
1478                        IRQF_SHARED, dev->driver->driver_name, dev)) {
1479                dev_dbg(dev->class_dev, "unable to allocate irq %d\n",
1480                        pcidev->irq);
1481                return -EINVAL;
1482        }
1483        dev->irq = pcidev->irq;
1484
1485        ret = comedi_alloc_subdevices(dev, 7);
1486        if (ret)
1487                return ret;
1488
1489        s = &dev->subdevices[0];
1490        /* analog input subdevice */
1491        dev->read_subdev = s;
1492        s->type = COMEDI_SUBD_AI;
1493        s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
1494        /* WARNING: Number of inputs in differential mode is ignored */
1495        s->n_chan = thisboard->ai_nchan;
1496        s->len_chanlist = thisboard->ai_nchan;
1497        s->maxdata = (1 << thisboard->ai_bits) - 1;
1498        s->range_table = thisboard->ranges;
1499        s->insn_read = cb_pcidas_ai_rinsn;
1500        s->insn_config = ai_config_insn;
1501        s->do_cmd = cb_pcidas_ai_cmd;
1502        s->do_cmdtest = cb_pcidas_ai_cmdtest;
1503        s->cancel = cb_pcidas_cancel;
1504
1505        /* analog output subdevice */
1506        s = &dev->subdevices[1];
1507        if (thisboard->ao_nchan) {
1508                s->type = COMEDI_SUBD_AO;
1509                s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
1510                s->n_chan = thisboard->ao_nchan;
1511                /*
1512                 * analog out resolution is the same as
1513                 * analog input resolution, so use ai_bits
1514                 */
1515                s->maxdata = (1 << thisboard->ai_bits) - 1;
1516                s->range_table = &cb_pcidas_ao_ranges;
1517                s->insn_read = cb_pcidas_ao_readback_insn;
1518                if (thisboard->has_ao_fifo) {
1519                        dev->write_subdev = s;
1520                        s->subdev_flags |= SDF_CMD_WRITE;
1521                        s->insn_write = cb_pcidas_ao_fifo_winsn;
1522                        s->do_cmdtest = cb_pcidas_ao_cmdtest;
1523                        s->do_cmd = cb_pcidas_ao_cmd;
1524                        s->cancel = cb_pcidas_ao_cancel;
1525                } else {
1526                        s->insn_write = cb_pcidas_ao_nofifo_winsn;
1527                }
1528        } else {
1529                s->type = COMEDI_SUBD_UNUSED;
1530        }
1531
1532        /* 8255 */
1533        s = &dev->subdevices[2];
1534        ret = subdev_8255_init(dev, s, NULL,
1535                               devpriv->pacer_counter_dio + DIO_8255);
1536        if (ret)
1537                return ret;
1538
1539        /*  serial EEPROM, */
1540        s = &dev->subdevices[3];
1541        s->type = COMEDI_SUBD_MEMORY;
1542        s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
1543        s->n_chan = 256;
1544        s->maxdata = 0xff;
1545        s->insn_read = eeprom_read_insn;
1546
1547        /*  8800 caldac */
1548        s = &dev->subdevices[4];
1549        s->type = COMEDI_SUBD_CALIB;
1550        s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1551        s->n_chan = NUM_CHANNELS_8800;
1552        s->maxdata = 0xff;
1553        s->insn_read = caldac_read_insn;
1554        s->insn_write = caldac_write_insn;
1555        for (i = 0; i < s->n_chan; i++)
1556                caldac_8800_write(dev, i, s->maxdata / 2);
1557
1558        /*  trim potentiometer */
1559        s = &dev->subdevices[5];
1560        s->type = COMEDI_SUBD_CALIB;
1561        s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1562        if (thisboard->trimpot == AD7376) {
1563                s->n_chan = NUM_CHANNELS_7376;
1564                s->maxdata = 0x7f;
1565        } else {
1566                s->n_chan = NUM_CHANNELS_8402;
1567                s->maxdata = 0xff;
1568        }
1569        s->insn_read = trimpot_read_insn;
1570        s->insn_write = trimpot_write_insn;
1571        for (i = 0; i < s->n_chan; i++)
1572                cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
1573
1574        /*  dac08 caldac */
1575        s = &dev->subdevices[6];
1576        if (thisboard->has_dac08) {
1577                s->type = COMEDI_SUBD_CALIB;
1578                s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
1579                s->n_chan = NUM_CHANNELS_DAC08;
1580                s->insn_read = dac08_read_insn;
1581                s->insn_write = dac08_write_insn;
1582                s->maxdata = 0xff;
1583                dac08_write(dev, s->maxdata / 2);
1584        } else
1585                s->type = COMEDI_SUBD_UNUSED;
1586
1587        /*  make sure mailbox 4 is empty */
1588        inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
1589        /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
1590        devpriv->s5933_intcsr_bits =
1591            INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
1592            INTCSR_INBOX_FULL_INT;
1593        /*  clear and enable interrupt on amcc s5933 */
1594        outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
1595             devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1596
1597        return 0;
1598}
1599
1600static void cb_pcidas_detach(struct comedi_device *dev)
1601{
1602        struct cb_pcidas_private *devpriv = dev->private;
1603
1604        if (devpriv) {
1605                if (devpriv->s5933_config) {
1606                        outl(INTCSR_INBOX_INTR_STATUS,
1607                             devpriv->s5933_config + AMCC_OP_REG_INTCSR);
1608                }
1609        }
1610        if (dev->irq)
1611                free_irq(dev->irq, dev);
1612        comedi_pci_disable(dev);
1613}
1614
1615static struct comedi_driver cb_pcidas_driver = {
1616        .driver_name    = "cb_pcidas",
1617        .module         = THIS_MODULE,
1618        .auto_attach    = cb_pcidas_auto_attach,
1619        .detach         = cb_pcidas_detach,
1620};
1621
1622static int cb_pcidas_pci_probe(struct pci_dev *dev,
1623                               const struct pci_device_id *id)
1624{
1625        return comedi_pci_auto_config(dev, &cb_pcidas_driver,
1626                                      id->driver_data);
1627}
1628
1629static const struct pci_device_id cb_pcidas_pci_table[] = {
1630        { PCI_VDEVICE(CB, 0x0001), BOARD_PCIDAS1602_16 },
1631        { PCI_VDEVICE(CB, 0x000f), BOARD_PCIDAS1200 },
1632        { PCI_VDEVICE(CB, 0x0010), BOARD_PCIDAS1602_12 },
1633        { PCI_VDEVICE(CB, 0x0019), BOARD_PCIDAS1200_JR },
1634        { PCI_VDEVICE(CB, 0x001c), BOARD_PCIDAS1602_16_JR },
1635        { PCI_VDEVICE(CB, 0x004c), BOARD_PCIDAS1000 },
1636        { PCI_VDEVICE(CB, 0x001a), BOARD_PCIDAS1001 },
1637        { PCI_VDEVICE(CB, 0x001b), BOARD_PCIDAS1002 },
1638        { 0 }
1639};
1640MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
1641
1642static struct pci_driver cb_pcidas_pci_driver = {
1643        .name           = "cb_pcidas",
1644        .id_table       = cb_pcidas_pci_table,
1645        .probe          = cb_pcidas_pci_probe,
1646        .remove         = comedi_pci_auto_unconfig,
1647};
1648module_comedi_pci_driver(cb_pcidas_driver, cb_pcidas_pci_driver);
1649
1650MODULE_AUTHOR("Comedi http://www.comedi.org");
1651MODULE_DESCRIPTION("Comedi low-level driver");
1652MODULE_LICENSE("GPL");
1653