linux/drivers/staging/comedi/drivers/adl_pci9118.c
<<
>>
Prefs
   1/*
   2 *  comedi/drivers/adl_pci9118.c
   3 *
   4 *  hardware driver for ADLink cards:
   5 *   card:   PCI-9118DG, PCI-9118HG, PCI-9118HR
   6 *   driver: pci9118dg,  pci9118hg,  pci9118hr
   7 *
   8 * Author: Michal Dobes <dobes@tesnet.cz>
   9 *
  10*/
  11/*
  12Driver: adl_pci9118
  13Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
  14Author: Michal Dobes <dobes@tesnet.cz>
  15Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
  16  PCI-9118HR (pci9118hr)
  17Status: works
  18
  19This driver supports AI, AO, DI and DO subdevices.
  20AI subdevice supports cmd and insn interface,
  21other subdevices support only insn interface.
  22For AI:
  23- If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
  24- If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
  25- If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
  26- It is not necessary to have cmd.scan_end_arg=cmd.chanlist_len but
  27  cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
  28- If return value of cmdtest is 5 then you've bad channel list
  29  (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
  30  ranges).
  31
  32There are some hardware limitations:
  33a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
  34   ended inputs.
  35b) DMA transfers must have the length aligned to two samples (32 bit),
  36   so there is some problems if cmd->chanlist_len is odd. This driver tries
  37   bypass this with adding one sample to the end of the every scan and discard
  38   it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
  39   and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
  40   with interrupt after every sample.
  41c) If isn't used DMA then you can use only mode where
  42   cmd->scan_begin_src=TRIG_FOLLOW.
  43
  44Configuration options:
  45  [0] - PCI bus of device (optional)
  46  [1] - PCI slot of device (optional)
  47        If bus/slot is not specified, then first available PCI
  48        card will be used.
  49  [2] - 0= standard 8 DIFF/16 SE channels configuration
  50        n = external multiplexer connected, 1 <= n <= 256
  51  [3] - 0=autoselect DMA or EOC interrupts operation
  52        1 = disable DMA mode
  53        3 = disable DMA and INT, only insn interface will work
  54  [4] - sample&hold signal - card can generate signal for external S&H board
  55        0 = use SSHO(pin 45) signal is generated in onboard hardware S&H logic
  56        0 != use ADCHN7(pin 23) signal is generated from driver, number say how
  57                long delay is requested in ns and sign polarity of the hold
  58                (in this case external multiplexor can serve only 128 channels)
  59  [5] - 0=stop measure on all hardware errors
  60        2 | = ignore ADOR - A/D Overrun status
  61        8|=ignore Bover - A/D Burst Mode Overrun status
  62        256|=ignore nFull - A/D FIFO Full status
  63
  64*/
  65
  66/*
  67 * FIXME
  68 *
  69 * All the supported boards have the same PCI vendor and device IDs, so
  70 * auto-attachment of PCI devices will always find the first board type.
  71 *
  72 * Perhaps the boards have different subdevice IDs that we could use to
  73 * distinguish them?
  74 *
  75 * Need some device attributes so the board type can be corrected after
  76 * attachment if necessary, and possibly to set other options supported by
  77 * manual attachment.
  78 */
  79
  80#include <linux/pci.h>
  81#include <linux/delay.h>
  82#include <linux/gfp.h>
  83#include <linux/interrupt.h>
  84#include <linux/io.h>
  85
  86#include "../comedidev.h"
  87
  88#include "amcc_s5933.h"
  89#include "8253.h"
  90#include "comedi_fc.h"
  91
  92/* paranoid checks are broken */
  93#undef PCI9118_PARANOIDCHECK    /*
  94                                 * if defined, then is used code which control
  95                                 * correct channel number on every 12 bit sample
  96                                 */
  97
  98#define IORANGE_9118    64      /* I hope */
  99#define PCI9118_CHANLEN 255     /*
 100                                 * len of chanlist, some source say 256,
 101                                 * but reality looks like 255 :-(
 102                                 */
 103
 104#define PCI9118_CNT0    0x00    /* R/W: 8254 counter 0 */
 105#define PCI9118_CNT1    0x04    /* R/W: 8254 counter 0 */
 106#define PCI9118_CNT2    0x08    /* R/W: 8254 counter 0 */
 107#define PCI9118_CNTCTRL 0x0c    /* W:   8254 counter control */
 108#define PCI9118_AD_DATA 0x10    /* R:   A/D data */
 109#define PCI9118_DA1     0x10    /* W:   D/A registers */
 110#define PCI9118_DA2     0x14
 111#define PCI9118_ADSTAT  0x18    /* R:   A/D status register */
 112#define PCI9118_ADCNTRL 0x18    /* W:   A/D control register */
 113#define PCI9118_DI      0x1c    /* R:   digi input register */
 114#define PCI9118_DO      0x1c    /* W:   digi output register */
 115#define PCI9118_SOFTTRG 0x20    /* W:   soft trigger for A/D */
 116#define PCI9118_GAIN    0x24    /* W:   A/D gain/channel register */
 117#define PCI9118_BURST   0x28    /* W:   A/D burst number register */
 118#define PCI9118_SCANMOD 0x2c    /* W:   A/D auto scan mode */
 119#define PCI9118_ADFUNC  0x30    /* W:   A/D function register */
 120#define PCI9118_DELFIFO 0x34    /* W:   A/D data FIFO reset */
 121#define PCI9118_INTSRC  0x38    /* R:   interrupt reason register */
 122#define PCI9118_INTCTRL 0x38    /* W:   interrupt control register */
 123
 124/* bits from A/D control register (PCI9118_ADCNTRL) */
 125#define AdControl_UniP  0x80    /* 1=bipolar, 0=unipolar */
 126#define AdControl_Diff  0x40    /* 1=differential, 0= single end inputs */
 127#define AdControl_SoftG 0x20    /* 1=8254 counter works, 0=counter stops */
 128#define AdControl_ExtG  0x10    /*
 129                                 * 1=8254 countrol controlled by TGIN(pin 46),
 130                                 * 0=controlled by SoftG
 131                                 */
 132#define AdControl_ExtM  0x08    /*
 133                                 * 1=external hardware trigger (pin 44),
 134                                 * 0=internal trigger
 135                                 */
 136#define AdControl_TmrTr 0x04    /*
 137                                 * 1=8254 is iternal trigger source,
 138                                 * 0=software trigger is source
 139                                 * (register PCI9118_SOFTTRG)
 140                                 */
 141#define AdControl_Int   0x02    /* 1=enable INT, 0=disable */
 142#define AdControl_Dma   0x01    /* 1=enable DMA, 0=disable */
 143
 144/* bits from A/D function register (PCI9118_ADFUNC) */
 145#define AdFunction_PDTrg        0x80    /*
 146                                         * 1=positive,
 147                                         * 0=negative digital trigger
 148                                         * (only positive is correct)
 149                                         */
 150#define AdFunction_PETrg        0x40    /*
 151                                         * 1=positive,
 152                                         * 0=negative external trigger
 153                                         * (only positive is correct)
 154                                         */
 155#define AdFunction_BSSH         0x20    /* 1=with sample&hold, 0=without */
 156#define AdFunction_BM           0x10    /* 1=burst mode, 0=normal mode */
 157#define AdFunction_BS           0x08    /*
 158                                         * 1=burst mode start,
 159                                         * 0=burst mode stop
 160                                         */
 161#define AdFunction_PM           0x04    /*
 162                                         * 1=post trigger mode,
 163                                         * 0=not post trigger
 164                                         */
 165#define AdFunction_AM           0x02    /*
 166                                         * 1=about trigger mode,
 167                                         * 0=not about trigger
 168                                         */
 169#define AdFunction_Start        0x01    /* 1=trigger start, 0=trigger stop */
 170
 171/* bits from A/D status register (PCI9118_ADSTAT) */
 172#define AdStatus_nFull  0x100   /* 0=FIFO full (fatal), 1=not full */
 173#define AdStatus_nHfull 0x080   /* 0=FIFO half full, 1=FIFO not half full */
 174#define AdStatus_nEpty  0x040   /* 0=FIFO empty, 1=FIFO not empty */
 175#define AdStatus_Acmp   0x020   /*  */
 176#define AdStatus_DTH    0x010   /* 1=external digital trigger */
 177#define AdStatus_Bover  0x008   /* 1=burst mode overrun (fatal) */
 178#define AdStatus_ADOS   0x004   /* 1=A/D over speed (warning) */
 179#define AdStatus_ADOR   0x002   /* 1=A/D overrun (fatal) */
 180#define AdStatus_ADrdy  0x001   /* 1=A/D already ready, 0=not ready */
 181
 182/* bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL) */
 183/* 1=interrupt occur, enable source,  0=interrupt not occur, disable source */
 184#define Int_Timer       0x08    /* timer interrupt */
 185#define Int_About       0x04    /* about trigger complete */
 186#define Int_Hfull       0x02    /* A/D FIFO hlaf full */
 187#define Int_DTrg        0x01    /* external digital trigger */
 188
 189#define START_AI_EXT    0x01    /* start measure on external trigger */
 190#define STOP_AI_EXT     0x02    /* stop measure on external trigger */
 191#define START_AI_INT    0x04    /* start measure on internal trigger */
 192#define STOP_AI_INT     0x08    /* stop measure on internal trigger */
 193
 194#define EXTTRG_AI       0       /* ext trg is used by AI */
 195
 196static const struct comedi_lrange range_pci9118dg_hr = { 8, {
 197                                                             BIP_RANGE(5),
 198                                                             BIP_RANGE(2.5),
 199                                                             BIP_RANGE(1.25),
 200                                                             BIP_RANGE(0.625),
 201                                                             UNI_RANGE(10),
 202                                                             UNI_RANGE(5),
 203                                                             UNI_RANGE(2.5),
 204                                                             UNI_RANGE(1.25)
 205                                                             }
 206};
 207
 208static const struct comedi_lrange range_pci9118hg = { 8, {
 209                                                          BIP_RANGE(5),
 210                                                          BIP_RANGE(0.5),
 211                                                          BIP_RANGE(0.05),
 212                                                          BIP_RANGE(0.005),
 213                                                          UNI_RANGE(10),
 214                                                          UNI_RANGE(1),
 215                                                          UNI_RANGE(0.1),
 216                                                          UNI_RANGE(0.01)
 217                                                          }
 218};
 219
 220#define PCI9118_BIPOLAR_RANGES  4       /*
 221                                         * used for test on mixture
 222                                         * of BIP/UNI ranges
 223                                         */
 224
 225struct boardtype {
 226        const char *name;               /* board name */
 227        int device_id;                  /* PCI device ID of card */
 228        int iorange_amcc;               /* iorange for own S5933 region */
 229        int iorange_9118;               /* pass thru card region size */
 230        int n_aichan;                   /* num of A/D chans */
 231        int n_aichand;                  /* num of A/D chans in diff mode */
 232        int mux_aichan;                 /*
 233                                         * num of A/D chans with
 234                                         * external multiplexor
 235                                         */
 236        int n_aichanlist;               /* len of chanlist */
 237        int n_aochan;                   /* num of D/A chans */
 238        int ai_maxdata;                 /* resolution of A/D */
 239        int ao_maxdata;                 /* resolution of D/A */
 240        const struct comedi_lrange *rangelist_ai;       /* rangelist for A/D */
 241        const struct comedi_lrange *rangelist_ao;       /* rangelist for D/A */
 242        unsigned int ai_ns_min;         /* max sample speed of card v ns */
 243        unsigned int ai_pacer_min;      /*
 244                                         * minimal pacer value
 245                                         * (c1*c2 or c1 in burst)
 246                                         */
 247        int half_fifo_size;             /* size of FIFO/2 */
 248
 249};
 250
 251static const struct boardtype boardtypes[] = {
 252        {
 253                .name           = "pci9118dg",
 254                .device_id      = 0x80d9,
 255                .iorange_amcc   = AMCC_OP_REG_SIZE,
 256                .iorange_9118   = IORANGE_9118,
 257                .n_aichan       = 16,
 258                .n_aichand      = 8,
 259                .mux_aichan     = 256,
 260                .n_aichanlist   = PCI9118_CHANLEN,
 261                .n_aochan       = 2,
 262                .ai_maxdata     = 0x0fff,
 263                .ao_maxdata     = 0x0fff,
 264                .rangelist_ai   = &range_pci9118dg_hr,
 265                .rangelist_ao   = &range_bipolar10,
 266                .ai_ns_min      = 3000,
 267                .ai_pacer_min   = 12,
 268                .half_fifo_size = 512,
 269        }, {
 270                .name           = "pci9118hg",
 271                .device_id      = 0x80d9,
 272                .iorange_amcc   = AMCC_OP_REG_SIZE,
 273                .iorange_9118   = IORANGE_9118,
 274                .n_aichan       = 16,
 275                .n_aichand      = 8,
 276                .mux_aichan     = 256,
 277                .n_aichanlist   = PCI9118_CHANLEN,
 278                .n_aochan       = 2,
 279                .ai_maxdata     = 0x0fff,
 280                .ao_maxdata     = 0x0fff,
 281                .rangelist_ai   = &range_pci9118hg,
 282                .rangelist_ao   = &range_bipolar10,
 283                .ai_ns_min      = 3000,
 284                .ai_pacer_min   = 12,
 285                .half_fifo_size = 512,
 286        }, {
 287                .name           = "pci9118hr",
 288                .device_id      = 0x80d9,
 289                .iorange_amcc   = AMCC_OP_REG_SIZE,
 290                .iorange_9118   = IORANGE_9118,
 291                .n_aichan       = 16,
 292                .n_aichand      = 8,
 293                .mux_aichan     = 256,
 294                .n_aichanlist   = PCI9118_CHANLEN,
 295                .n_aochan       = 2,
 296                .ai_maxdata     = 0xffff,
 297                .ao_maxdata     = 0x0fff,
 298                .rangelist_ai   = &range_pci9118dg_hr,
 299                .rangelist_ao   = &range_bipolar10,
 300                .ai_ns_min      = 10000,
 301                .ai_pacer_min   = 40,
 302                .half_fifo_size = 512,
 303        },
 304};
 305
 306struct pci9118_private {
 307        unsigned long iobase_a; /* base+size for AMCC chip */
 308        unsigned int master;    /* master capable */
 309        unsigned int usemux;    /* we want to use external multiplexor! */
 310#ifdef PCI9118_PARANOIDCHECK
 311        unsigned short chanlist[PCI9118_CHANLEN + 1];   /*
 312                                                         * list of
 313                                                         * scanned channel
 314                                                         */
 315        unsigned char chanlistlen;      /* number of scanlist */
 316#endif
 317        unsigned char AdControlReg;     /* A/D control register */
 318        unsigned char IntControlReg;    /* Interrupt control register */
 319        unsigned char AdFunctionReg;    /* A/D function register */
 320        char valid;                     /* driver is ok */
 321        char ai_neverending;            /* we do unlimited AI */
 322        unsigned int i8254_osc_base;    /* frequence of onboard oscilator */
 323        unsigned int ai_do;             /* what do AI? 0=nothing, 1 to 4 mode */
 324        unsigned int ai_act_scan;       /* how many scans we finished */
 325        unsigned int ai_buf_ptr;        /* data buffer ptr in samples */
 326        unsigned int ai_n_chan;         /* how many channels is measured */
 327        unsigned int ai_n_scanlen;      /* len of actual scanlist */
 328        unsigned int ai_n_realscanlen;  /*
 329                                         * what we must transfer for one
 330                                         * outgoing scan include front/back adds
 331                                         */
 332        unsigned int ai_act_dmapos;     /* position in actual real stream */
 333        unsigned int ai_add_front;      /*
 334                                         * how many channels we must add
 335                                         * before scan to satisfy S&H?
 336                                         */
 337        unsigned int ai_add_back;       /*
 338                                         * how many channels we must add
 339                                         * before scan to satisfy DMA?
 340                                         */
 341        unsigned int *ai_chanlist;      /* actual chanlist */
 342        unsigned int ai_timer1;
 343        unsigned int ai_timer2;
 344        unsigned int ai_flags;
 345        char ai12_startstop;            /*
 346                                         * measure can start/stop
 347                                         * on external trigger
 348                                         */
 349        unsigned int ai_divisor1, ai_divisor2;  /*
 350                                                 * divisors for start of measure
 351                                                 * on external start
 352                                                 */
 353        unsigned int ai_data_len;
 354        short *ai_data;
 355        short ao_data[2];                       /* data output buffer */
 356        unsigned int ai_scans;                  /* number of scans to do */
 357        char dma_doublebuf;                     /* we can use double buffering */
 358        unsigned int dma_actbuf;                /* which buffer is used now */
 359        short *dmabuf_virt[2];                  /*
 360                                                 * pointers to begin of
 361                                                 * DMA buffer
 362                                                 */
 363        unsigned long dmabuf_hw[2];             /* hw address of DMA buff */
 364        unsigned int dmabuf_size[2];            /*
 365                                                 * size of dma buffer in bytes
 366                                                 */
 367        unsigned int dmabuf_use_size[2];        /*
 368                                                 * which size we may now use
 369                                                 * for transfer
 370                                                 */
 371        unsigned int dmabuf_used_size[2];       /* which size was truly used */
 372        unsigned int dmabuf_panic_size[2];
 373        unsigned int dmabuf_samples[2];         /* size in samples */
 374        int dmabuf_pages[2];                    /* number of pages in buffer */
 375        unsigned char cnt0_users;               /*
 376                                                 * bit field of 8254 CNT0 users
 377                                                 * (0-unused, 1-AO, 2-DI, 3-DO)
 378                                                 */
 379        unsigned char exttrg_users;             /*
 380                                                 * bit field of external trigger
 381                                                 * users(0-AI, 1-AO, 2-DI, 3-DO)
 382                                                 */
 383        unsigned int cnt0_divisor;              /* actual CNT0 divisor */
 384        void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *,
 385                unsigned short,
 386                unsigned int,
 387                unsigned short);        /*
 388                                         * ptr to actual interrupt
 389                                         * AI function
 390                                         */
 391        unsigned char ai16bits;         /* =1 16 bit card */
 392        unsigned char usedma;           /* =1 use DMA transfer and not INT */
 393        unsigned char useeoshandle;     /*
 394                                         * =1 change WAKE_EOS DMA transfer
 395                                         * to fit on every second
 396                                         */
 397        unsigned char usessh;           /* =1 turn on S&H support */
 398        int softsshdelay;               /*
 399                                         * >0 use software S&H,
 400                                         * numer is requested delay in ns
 401                                         */
 402        unsigned char softsshsample;    /*
 403                                         * polarity of S&H signal
 404                                         * in sample state
 405                                         */
 406        unsigned char softsshhold;      /*
 407                                         * polarity of S&H signal
 408                                         * in hold state
 409                                         */
 410        unsigned int ai_maskerr;        /* which warning was printed */
 411        unsigned int ai_maskharderr;    /* on which error bits stops */
 412        unsigned int ai_inttrig_start;  /* TRIG_INT for start */
 413};
 414
 415static int check_channel_list(struct comedi_device *dev,
 416                              struct comedi_subdevice *s, int n_chan,
 417                              unsigned int *chanlist, int frontadd, int backadd)
 418{
 419        const struct boardtype *this_board = comedi_board(dev);
 420        struct pci9118_private *devpriv = dev->private;
 421        unsigned int i, differencial = 0, bipolar = 0;
 422
 423        /* correct channel and range number check itself comedi/range.c */
 424        if (n_chan < 1) {
 425                comedi_error(dev, "range/channel list is empty!");
 426                return 0;
 427        }
 428        if ((frontadd + n_chan + backadd) > s->len_chanlist) {
 429                comedi_error(dev,
 430                            "range/channel list is too long for actual configuration!\n");
 431                return 0;
 432        }
 433
 434        if (CR_AREF(chanlist[0]) == AREF_DIFF)
 435                differencial = 1;       /* all input must be diff */
 436        if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
 437                bipolar = 1;    /* all input must be bipolar */
 438        if (n_chan > 1)
 439                for (i = 1; i < n_chan; i++) {  /* check S.E/diff */
 440                        if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
 441                            (differencial)) {
 442                                comedi_error(dev,
 443                                             "Differencial and single ended "
 444                                                "inputs can't be mixtured!");
 445                                return 0;
 446                        }
 447                        if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
 448                            (bipolar)) {
 449                                comedi_error(dev,
 450                                             "Bipolar and unipolar ranges "
 451                                                        "can't be mixtured!");
 452                                return 0;
 453                        }
 454                        if (!devpriv->usemux && differencial &&
 455                            (CR_CHAN(chanlist[i]) >= this_board->n_aichand)) {
 456                                comedi_error(dev,
 457                                             "If AREF_DIFF is used then is "
 458                                        "available only first 8 channels!");
 459                                return 0;
 460                        }
 461                }
 462
 463        return 1;
 464}
 465
 466static int setup_channel_list(struct comedi_device *dev,
 467                              struct comedi_subdevice *s, int n_chan,
 468                              unsigned int *chanlist, int rot, int frontadd,
 469                              int backadd, int usedma, char useeos)
 470{
 471        struct pci9118_private *devpriv = dev->private;
 472        unsigned int i, differencial = 0, bipolar = 0;
 473        unsigned int scanquad, gain, ssh = 0x00;
 474
 475        if (usedma == 1) {
 476                rot = 8;
 477                usedma = 0;
 478        }
 479
 480        if (CR_AREF(chanlist[0]) == AREF_DIFF)
 481                differencial = 1;       /* all input must be diff */
 482        if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
 483                bipolar = 1;    /* all input must be bipolar */
 484
 485        /* All is ok, so we can setup channel/range list */
 486
 487        if (!bipolar) {
 488                devpriv->AdControlReg |= AdControl_UniP;
 489                                                        /* set unibipolar */
 490        } else {
 491                devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff);
 492                                                        /* enable bipolar */
 493        }
 494
 495        if (differencial) {
 496                devpriv->AdControlReg |= AdControl_Diff;
 497                                                        /* enable diff inputs */
 498        } else {
 499                devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff);
 500                                                /* set single ended inputs */
 501        }
 502
 503        outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
 504                                                                /* setup mode */
 505
 506        outl(2, dev->iobase + PCI9118_SCANMOD);
 507                                        /* gods know why this sequence! */
 508        outl(0, dev->iobase + PCI9118_SCANMOD);
 509        outl(1, dev->iobase + PCI9118_SCANMOD);
 510
 511#ifdef PCI9118_PARANOIDCHECK
 512        devpriv->chanlistlen = n_chan;
 513        for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
 514                devpriv->chanlist[i] = 0x55aa;
 515#endif
 516
 517        if (frontadd) {         /* insert channels for S&H */
 518                ssh = devpriv->softsshsample;
 519                for (i = 0; i < frontadd; i++) {
 520                                                /* store range list to card */
 521                        scanquad = CR_CHAN(chanlist[0]);
 522                                                /* get channel number; */
 523                        gain = CR_RANGE(chanlist[0]);
 524                                                /* get gain number */
 525                        scanquad |= ((gain & 0x03) << 8);
 526                        outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
 527                        ssh = devpriv->softsshhold;
 528                }
 529        }
 530
 531        for (i = 0; i < n_chan; i++) {  /* store range list to card */
 532                scanquad = CR_CHAN(chanlist[i]);        /* get channel number */
 533#ifdef PCI9118_PARANOIDCHECK
 534                devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
 535#endif
 536                gain = CR_RANGE(chanlist[i]);           /* get gain number */
 537                scanquad |= ((gain & 0x03) << 8);
 538                outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
 539        }
 540
 541        if (backadd) {          /* insert channels for fit onto 32bit DMA */
 542                for (i = 0; i < backadd; i++) { /* store range list to card */
 543                        scanquad = CR_CHAN(chanlist[0]);
 544                                                        /* get channel number */
 545                        gain = CR_RANGE(chanlist[0]);   /* get gain number */
 546                        scanquad |= ((gain & 0x03) << 8);
 547                        outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
 548                }
 549        }
 550#ifdef PCI9118_PARANOIDCHECK
 551        devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma];
 552                                                /* for 32bit operations */
 553        if (useeos) {
 554                for (i = 1; i < n_chan; i++) {  /* store range list to card */
 555                        devpriv->chanlist[(n_chan + i) ^ usedma] =
 556                            (CR_CHAN(chanlist[i]) & 0xf) << rot;
 557                }
 558                devpriv->chanlist[(2 * n_chan) ^ usedma] =
 559                                                devpriv->chanlist[0 ^ usedma];
 560                                                /* for 32bit operations */
 561                useeos = 2;
 562        } else {
 563                useeos = 1;
 564        }
 565#endif
 566        outl(0, dev->iobase + PCI9118_SCANMOD); /* close scan queue */
 567        /* udelay(100); important delay, or first sample will be crippled */
 568
 569        return 1;               /* we can serve this with scan logic */
 570}
 571
 572static int pci9118_insn_read_ai(struct comedi_device *dev,
 573                                struct comedi_subdevice *s,
 574                                struct comedi_insn *insn, unsigned int *data)
 575{
 576        struct pci9118_private *devpriv = dev->private;
 577        int n, timeout;
 578
 579        devpriv->AdControlReg = AdControl_Int & 0xff;
 580        devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
 581        outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
 582                                                /*
 583                                                 * positive triggers, no S&H,
 584                                                 * no burst, burst stop,
 585                                                 * no post trigger,
 586                                                 * no about trigger,
 587                                                 * trigger stop
 588                                                 */
 589
 590        if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
 591                return -EINVAL;
 592
 593        outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
 594
 595        for (n = 0; n < insn->n; n++) {
 596                outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */
 597                udelay(2);
 598                timeout = 100;
 599                while (timeout--) {
 600                        if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
 601                                goto conv_finish;
 602                        udelay(1);
 603                }
 604
 605                comedi_error(dev, "A/D insn timeout");
 606                data[n] = 0;
 607                outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
 608                return -ETIME;
 609
 610conv_finish:
 611                if (devpriv->ai16bits) {
 612                        data[n] =
 613                            (inl(dev->iobase +
 614                                 PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
 615                } else {
 616                        data[n] =
 617                            (inw(dev->iobase + PCI9118_AD_DATA) >> 4) & 0xfff;
 618                }
 619        }
 620
 621        outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
 622        return n;
 623
 624}
 625
 626static int pci9118_insn_write_ao(struct comedi_device *dev,
 627                                 struct comedi_subdevice *s,
 628                                 struct comedi_insn *insn, unsigned int *data)
 629{
 630        struct pci9118_private *devpriv = dev->private;
 631        int n, chanreg, ch;
 632
 633        ch = CR_CHAN(insn->chanspec);
 634        if (ch)
 635                chanreg = PCI9118_DA2;
 636        else
 637                chanreg = PCI9118_DA1;
 638
 639
 640        for (n = 0; n < insn->n; n++) {
 641                outl(data[n], dev->iobase + chanreg);
 642                devpriv->ao_data[ch] = data[n];
 643        }
 644
 645        return n;
 646}
 647
 648static int pci9118_insn_read_ao(struct comedi_device *dev,
 649                                struct comedi_subdevice *s,
 650                                struct comedi_insn *insn, unsigned int *data)
 651{
 652        struct pci9118_private *devpriv = dev->private;
 653        int n, chan;
 654
 655        chan = CR_CHAN(insn->chanspec);
 656        for (n = 0; n < insn->n; n++)
 657                data[n] = devpriv->ao_data[chan];
 658
 659        return n;
 660}
 661
 662static int pci9118_insn_bits_di(struct comedi_device *dev,
 663                                struct comedi_subdevice *s,
 664                                struct comedi_insn *insn, unsigned int *data)
 665{
 666        data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
 667
 668        return insn->n;
 669}
 670
 671static int pci9118_insn_bits_do(struct comedi_device *dev,
 672                                struct comedi_subdevice *s,
 673                                struct comedi_insn *insn, unsigned int *data)
 674{
 675        if (data[0]) {
 676                s->state &= ~data[0];
 677                s->state |= (data[0] & data[1]);
 678                outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
 679        }
 680        data[1] = s->state;
 681
 682        return insn->n;
 683}
 684
 685static void interrupt_pci9118_ai_mode4_switch(struct comedi_device *dev)
 686{
 687        struct pci9118_private *devpriv = dev->private;
 688
 689        devpriv->AdFunctionReg =
 690            AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
 691        outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
 692        outl(0x30, dev->iobase + PCI9118_CNTCTRL);
 693        outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
 694             dev->iobase + PCI9118_CNT0);
 695        outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
 696             dev->iobase + PCI9118_CNT0);
 697        devpriv->AdFunctionReg |= AdFunction_Start;
 698        outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
 699}
 700
 701static unsigned int defragment_dma_buffer(struct comedi_device *dev,
 702                                          struct comedi_subdevice *s,
 703                                          short *dma_buffer,
 704                                          unsigned int num_samples)
 705{
 706        struct pci9118_private *devpriv = dev->private;
 707        unsigned int i = 0, j = 0;
 708        unsigned int start_pos = devpriv->ai_add_front,
 709            stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
 710        unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
 711            devpriv->ai_add_back;
 712
 713        for (i = 0; i < num_samples; i++) {
 714                if (devpriv->ai_act_dmapos >= start_pos &&
 715                    devpriv->ai_act_dmapos < stop_pos) {
 716                        dma_buffer[j++] = dma_buffer[i];
 717                }
 718                devpriv->ai_act_dmapos++;
 719                devpriv->ai_act_dmapos %= raw_scanlen;
 720        }
 721
 722        return j;
 723}
 724
 725static int move_block_from_dma(struct comedi_device *dev,
 726                                        struct comedi_subdevice *s,
 727                                        short *dma_buffer,
 728                                        unsigned int num_samples)
 729{
 730        struct pci9118_private *devpriv = dev->private;
 731        unsigned int num_bytes;
 732
 733        num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
 734        devpriv->ai_act_scan +=
 735            (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
 736        s->async->cur_chan += num_samples;
 737        s->async->cur_chan %= devpriv->ai_n_scanlen;
 738        num_bytes =
 739            cfc_write_array_to_buffer(s, dma_buffer,
 740                                      num_samples * sizeof(short));
 741        if (num_bytes < num_samples * sizeof(short))
 742                return -1;
 743        return 0;
 744}
 745
 746static int pci9118_exttrg_add(struct comedi_device *dev, unsigned char source)
 747{
 748        struct pci9118_private *devpriv = dev->private;
 749
 750        if (source > 3)
 751                return -1;                              /* incorrect source */
 752        devpriv->exttrg_users |= (1 << source);
 753        devpriv->IntControlReg |= Int_DTrg;
 754        outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
 755        outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
 756                                        devpriv->iobase_a + AMCC_OP_REG_INTCSR);
 757                                                        /* allow INT in AMCC */
 758        return 0;
 759}
 760
 761static int pci9118_exttrg_del(struct comedi_device *dev, unsigned char source)
 762{
 763        struct pci9118_private *devpriv = dev->private;
 764
 765        if (source > 3)
 766                return -1;                      /* incorrect source */
 767        devpriv->exttrg_users &= ~(1 << source);
 768        if (!devpriv->exttrg_users) {   /* shutdown ext trg intterrupts */
 769                devpriv->IntControlReg &= ~Int_DTrg;
 770                if (!devpriv->IntControlReg)    /* all IRQ disabled */
 771                        outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) &
 772                                        (~0x00001f00),
 773                                        devpriv->iobase_a + AMCC_OP_REG_INTCSR);
 774                                                /* disable int in AMCC */
 775                outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
 776        }
 777        return 0;
 778}
 779
 780static void pci9118_calc_divisors(char mode, struct comedi_device *dev,
 781                                  struct comedi_subdevice *s,
 782                                  unsigned int *tim1, unsigned int *tim2,
 783                                  unsigned int flags, int chans,
 784                                  unsigned int *div1, unsigned int *div2,
 785                                  char usessh, unsigned int chnsshfront)
 786{
 787        const struct boardtype *this_board = comedi_board(dev);
 788        struct pci9118_private *devpriv = dev->private;
 789
 790        switch (mode) {
 791        case 1:
 792        case 4:
 793                if (*tim2 < this_board->ai_ns_min)
 794                        *tim2 = this_board->ai_ns_min;
 795                i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
 796                                          tim2, flags & TRIG_ROUND_NEAREST);
 797                break;
 798        case 2:
 799                if (*tim2 < this_board->ai_ns_min)
 800                        *tim2 = this_board->ai_ns_min;
 801                *div1 = *tim2 / devpriv->i8254_osc_base;
 802                                                /* convert timer (burst) */
 803                if (*div1 < this_board->ai_pacer_min)
 804                        *div1 = this_board->ai_pacer_min;
 805                *div2 = *tim1 / devpriv->i8254_osc_base;        /* scan timer */
 806                *div2 = *div2 / *div1;          /* major timer is c1*c2 */
 807                if (*div2 < chans)
 808                        *div2 = chans;
 809
 810                *tim2 = *div1 * devpriv->i8254_osc_base;
 811                                                        /* real convert timer */
 812
 813                if (usessh && (chnsshfront == 0))       /* use BSSH signal */
 814                        if (*div2 < (chans + 2))
 815                                *div2 = chans + 2;
 816
 817                *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
 818                break;
 819        }
 820}
 821
 822static void start_pacer(struct comedi_device *dev, int mode,
 823                        unsigned int divisor1, unsigned int divisor2)
 824{
 825        outl(0x74, dev->iobase + PCI9118_CNTCTRL);
 826        outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
 827/* outl(0x30, dev->iobase + PCI9118_CNTCTRL); */
 828        udelay(1);
 829
 830        if ((mode == 1) || (mode == 2) || (mode == 4)) {
 831                outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
 832                outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
 833                outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
 834                outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
 835        }
 836}
 837
 838static int pci9118_ai_cancel(struct comedi_device *dev,
 839                             struct comedi_subdevice *s)
 840{
 841        struct pci9118_private *devpriv = dev->private;
 842
 843        if (devpriv->usedma)
 844                outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) &
 845                        (~EN_A2P_TRANSFERS),
 846                        devpriv->iobase_a + AMCC_OP_REG_MCSR);  /* stop DMA */
 847        pci9118_exttrg_del(dev, EXTTRG_AI);
 848        start_pacer(dev, 0, 0, 0);      /* stop 8254 counters */
 849        devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
 850        outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
 851                                        /*
 852                                         * positive triggers, no S&H, no burst,
 853                                         * burst stop, no post trigger,
 854                                         * no about trigger, trigger stop
 855                                         */
 856        devpriv->AdControlReg = 0x00;
 857        outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
 858                                        /*
 859                                         * bipolar, S.E., use 8254, stop 8354,
 860                                         * internal trigger, soft trigger,
 861                                         * disable INT and DMA
 862                                         */
 863        outl(0, dev->iobase + PCI9118_BURST);
 864        outl(1, dev->iobase + PCI9118_SCANMOD);
 865        outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
 866        outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
 867
 868        devpriv->ai_do = 0;
 869        devpriv->usedma = 0;
 870
 871        devpriv->ai_act_scan = 0;
 872        devpriv->ai_act_dmapos = 0;
 873        s->async->cur_chan = 0;
 874        s->async->inttrig = NULL;
 875        devpriv->ai_buf_ptr = 0;
 876        devpriv->ai_neverending = 0;
 877        devpriv->dma_actbuf = 0;
 878
 879        if (!devpriv->IntControlReg)
 880                outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
 881                                        devpriv->iobase_a + AMCC_OP_REG_INTCSR);
 882                                                        /* allow INT in AMCC */
 883
 884        return 0;
 885}
 886
 887static char pci9118_decode_error_status(struct comedi_device *dev,
 888                                        struct comedi_subdevice *s,
 889                                        unsigned char m)
 890{
 891        struct pci9118_private *devpriv = dev->private;
 892
 893        if (m & 0x100) {
 894                comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
 895                devpriv->ai_maskerr &= ~0x100L;
 896        }
 897        if (m & 0x008) {
 898                comedi_error(dev,
 899                             "A/D Burst Mode Overrun Status (Fatal Error!)");
 900                devpriv->ai_maskerr &= ~0x008L;
 901        }
 902        if (m & 0x004) {
 903                comedi_error(dev, "A/D Over Speed Status (Warning!)");
 904                devpriv->ai_maskerr &= ~0x004L;
 905        }
 906        if (m & 0x002) {
 907                comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
 908                devpriv->ai_maskerr &= ~0x002L;
 909        }
 910        if (m & devpriv->ai_maskharderr) {
 911                s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
 912                pci9118_ai_cancel(dev, s);
 913                comedi_event(dev, s);
 914                return 1;
 915        }
 916
 917        return 0;
 918}
 919
 920static void pci9118_ai_munge(struct comedi_device *dev,
 921                             struct comedi_subdevice *s, void *data,
 922                             unsigned int num_bytes,
 923                             unsigned int start_chan_index)
 924{
 925        struct pci9118_private *devpriv = dev->private;
 926        unsigned int i, num_samples = num_bytes / sizeof(short);
 927        short *array = data;
 928
 929        for (i = 0; i < num_samples; i++) {
 930                if (devpriv->usedma)
 931                        array[i] = be16_to_cpu(array[i]);
 932                if (devpriv->ai16bits)
 933                        array[i] ^= 0x8000;
 934                else
 935                        array[i] = (array[i] >> 4) & 0x0fff;
 936
 937        }
 938}
 939
 940static void interrupt_pci9118_ai_onesample(struct comedi_device *dev,
 941                                           struct comedi_subdevice *s,
 942                                           unsigned short int_adstat,
 943                                           unsigned int int_amcc,
 944                                           unsigned short int_daq)
 945{
 946        struct pci9118_private *devpriv = dev->private;
 947        register short sampl;
 948
 949        s->async->events = 0;
 950
 951        if (int_adstat & devpriv->ai_maskerr)
 952                if (pci9118_decode_error_status(dev, s, int_adstat))
 953                        return;
 954
 955        sampl = inw(dev->iobase + PCI9118_AD_DATA);
 956
 957#ifdef PCI9118_PARANOIDCHECK
 958        if (devpriv->ai16bits == 0) {
 959                if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) {
 960                                                        /* data dropout! */
 961                        dev_info(dev->class_dev,
 962                                 "A/D  SAMPL - data dropout: received channel %d, expected %d!\n",
 963                                 sampl & 0x000f,
 964                                 devpriv->chanlist[s->async->cur_chan]);
 965                        s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
 966                        pci9118_ai_cancel(dev, s);
 967                        comedi_event(dev, s);
 968                        return;
 969                }
 970        }
 971#endif
 972        cfc_write_to_buffer(s, sampl);
 973        s->async->cur_chan++;
 974        if (s->async->cur_chan >= devpriv->ai_n_scanlen) {
 975                                                        /* one scan done */
 976                s->async->cur_chan %= devpriv->ai_n_scanlen;
 977                devpriv->ai_act_scan++;
 978                if (!(devpriv->ai_neverending))
 979                        if (devpriv->ai_act_scan >= devpriv->ai_scans) {
 980                                                        /* all data sampled */
 981                                pci9118_ai_cancel(dev, s);
 982                                s->async->events |= COMEDI_CB_EOA;
 983                        }
 984        }
 985
 986        if (s->async->events)
 987                comedi_event(dev, s);
 988}
 989
 990static void interrupt_pci9118_ai_dma(struct comedi_device *dev,
 991                                     struct comedi_subdevice *s,
 992                                     unsigned short int_adstat,
 993                                     unsigned int int_amcc,
 994                                     unsigned short int_daq)
 995{
 996        struct pci9118_private *devpriv = dev->private;
 997        unsigned int next_dma_buf, samplesinbuf, sampls, m;
 998
 999        if (int_amcc & MASTER_ABORT_INT) {
1000                comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
1001                s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1002                pci9118_ai_cancel(dev, s);
1003                comedi_event(dev, s);
1004                return;
1005        }
1006
1007        if (int_amcc & TARGET_ABORT_INT) {
1008                comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
1009                s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
1010                pci9118_ai_cancel(dev, s);
1011                comedi_event(dev, s);
1012                return;
1013        }
1014        if (int_adstat & devpriv->ai_maskerr)
1015                                        /* if (int_adstat & 0x106) */
1016                if (pci9118_decode_error_status(dev, s, int_adstat))
1017                        return;
1018
1019        samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1;
1020                                        /* number of received real samples */
1021
1022        if (devpriv->dma_doublebuf) {   /*
1023                                         * switch DMA buffers if is used
1024                                         * double buffering
1025                                         */
1026                next_dma_buf = 1 - devpriv->dma_actbuf;
1027                outl(devpriv->dmabuf_hw[next_dma_buf],
1028                     devpriv->iobase_a + AMCC_OP_REG_MWAR);
1029                outl(devpriv->dmabuf_use_size[next_dma_buf],
1030                     devpriv->iobase_a + AMCC_OP_REG_MWTC);
1031                devpriv->dmabuf_used_size[next_dma_buf] =
1032                    devpriv->dmabuf_use_size[next_dma_buf];
1033                if (devpriv->ai_do == 4)
1034                        interrupt_pci9118_ai_mode4_switch(dev);
1035        }
1036
1037        if (samplesinbuf) {
1038                m = devpriv->ai_data_len >> 1;  /*
1039                                                 * how many samples is to
1040                                                 * end of buffer
1041                                                 */
1042                sampls = m;
1043                move_block_from_dma(dev, s,
1044                                    devpriv->dmabuf_virt[devpriv->dma_actbuf],
1045                                    samplesinbuf);
1046                m = m - sampls;         /* m= how many samples was transferred */
1047        }
1048
1049        if (!devpriv->ai_neverending)
1050                if (devpriv->ai_act_scan >= devpriv->ai_scans) {
1051                                                        /* all data sampled */
1052                        pci9118_ai_cancel(dev, s);
1053                        s->async->events |= COMEDI_CB_EOA;
1054                }
1055
1056        if (devpriv->dma_doublebuf) {   /* switch dma buffers */
1057                devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
1058        } else {        /* restart DMA if is not used double buffering */
1059                outl(devpriv->dmabuf_hw[0],
1060                     devpriv->iobase_a + AMCC_OP_REG_MWAR);
1061                outl(devpriv->dmabuf_use_size[0],
1062                     devpriv->iobase_a + AMCC_OP_REG_MWTC);
1063                if (devpriv->ai_do == 4)
1064                        interrupt_pci9118_ai_mode4_switch(dev);
1065        }
1066
1067        comedi_event(dev, s);
1068}
1069
1070static irqreturn_t interrupt_pci9118(int irq, void *d)
1071{
1072        struct comedi_device *dev = d;
1073        struct pci9118_private *devpriv = dev->private;
1074        unsigned int int_daq = 0, int_amcc, int_adstat;
1075
1076        if (!dev->attached)
1077                return IRQ_NONE;        /* not fully initialized */
1078
1079        int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf;
1080                                        /* get IRQ reasons from card */
1081        int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1082                                        /* get INT register from AMCC chip */
1083
1084        if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
1085                return IRQ_NONE;        /* interrupt from other source */
1086
1087        outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1088                                        /* shutdown IRQ reasons in AMCC */
1089
1090        int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff;
1091                                        /* get STATUS register */
1092
1093        if (devpriv->ai_do) {
1094                if (devpriv->ai12_startstop)
1095                        if ((int_adstat & AdStatus_DTH) &&
1096                                                        (int_daq & Int_DTrg)) {
1097                                                /* start stop of measure */
1098                                if (devpriv->ai12_startstop & START_AI_EXT) {
1099                                        devpriv->ai12_startstop &=
1100                                            ~START_AI_EXT;
1101                                        if (!(devpriv->ai12_startstop &
1102                                                        STOP_AI_EXT))
1103                                                        pci9118_exttrg_del
1104                                                        (dev, EXTTRG_AI);
1105                                                /* deactivate EXT trigger */
1106                                        start_pacer(dev, devpriv->ai_do,
1107                                                devpriv->ai_divisor1,
1108                                                devpriv->ai_divisor2);
1109                                                /* start pacer */
1110                                        outl(devpriv->AdControlReg,
1111                                                dev->iobase + PCI9118_ADCNTRL);
1112                                } else {
1113                                        if (devpriv->ai12_startstop &
1114                                                STOP_AI_EXT) {
1115                                                devpriv->ai12_startstop &=
1116                                                        ~STOP_AI_EXT;
1117                                                pci9118_exttrg_del
1118                                                        (dev, EXTTRG_AI);
1119                                                /* deactivate EXT trigger */
1120                                                devpriv->ai_neverending = 0;
1121                                                /*
1122                                                 * well, on next interrupt from
1123                                                 * DMA/EOC measure will stop
1124                                                 */
1125                                        }
1126                                }
1127                        }
1128
1129                (devpriv->int_ai_func) (dev, &dev->subdevices[0], int_adstat,
1130                                        int_amcc, int_daq);
1131
1132        }
1133        return IRQ_HANDLED;
1134}
1135
1136static int pci9118_ai_inttrig(struct comedi_device *dev,
1137                              struct comedi_subdevice *s, unsigned int trignum)
1138{
1139        struct pci9118_private *devpriv = dev->private;
1140
1141        if (trignum != devpriv->ai_inttrig_start)
1142                return -EINVAL;
1143
1144        devpriv->ai12_startstop &= ~START_AI_INT;
1145        s->async->inttrig = NULL;
1146
1147        outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1148        outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1149        if (devpriv->ai_do != 3) {
1150                start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1151                            devpriv->ai_divisor2);
1152                devpriv->AdControlReg |= AdControl_SoftG;
1153        }
1154        outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1155
1156        return 1;
1157}
1158
1159static int pci9118_ai_cmdtest(struct comedi_device *dev,
1160                              struct comedi_subdevice *s,
1161                              struct comedi_cmd *cmd)
1162{
1163        const struct boardtype *this_board = comedi_board(dev);
1164        struct pci9118_private *devpriv = dev->private;
1165        int err = 0;
1166        unsigned int flags;
1167        int tmp;
1168        unsigned int divisor1 = 0, divisor2 = 0;
1169
1170        /* Step 1 : check if triggers are trivially valid */
1171
1172        err |= cfc_check_trigger_src(&cmd->start_src,
1173                                        TRIG_NOW | TRIG_EXT | TRIG_INT);
1174
1175        flags = TRIG_FOLLOW;
1176        if (devpriv->master)
1177                flags |= TRIG_TIMER | TRIG_EXT;
1178        err |= cfc_check_trigger_src(&cmd->scan_begin_src, flags);
1179
1180        flags = TRIG_TIMER | TRIG_EXT;
1181        if (devpriv->master)
1182                flags |= TRIG_NOW;
1183        err |= cfc_check_trigger_src(&cmd->convert_src, flags);
1184
1185        err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
1186        err |= cfc_check_trigger_src(&cmd->stop_src,
1187                                        TRIG_COUNT | TRIG_NONE | TRIG_EXT);
1188
1189        if (err)
1190                return 1;
1191
1192        /* Step 2a : make sure trigger sources are unique */
1193
1194        err |= cfc_check_trigger_is_unique(cmd->start_src);
1195        err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
1196        err |= cfc_check_trigger_is_unique(cmd->convert_src);
1197        err |= cfc_check_trigger_is_unique(cmd->stop_src);
1198
1199        /* Step 2b : and mutually compatible */
1200
1201        if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1202                err |= -EINVAL;
1203
1204        if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT)
1205                err |= -EINVAL;
1206
1207        if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
1208            (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW))))
1209                err |= -EINVAL;
1210
1211        if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
1212            (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT))))
1213                err |= -EINVAL;
1214
1215        if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT)
1216                err |= -EINVAL;
1217
1218        if (err)
1219                return 2;
1220
1221        /* Step 3: check if arguments are trivially valid */
1222
1223        if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
1224                err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
1225
1226        if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
1227                err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
1228
1229        if ((cmd->scan_begin_src == TRIG_TIMER) &&
1230            (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
1231                cmd->scan_begin_src = TRIG_FOLLOW;
1232                cmd->convert_arg = cmd->scan_begin_arg;
1233                cmd->scan_begin_arg = 0;
1234        }
1235
1236        if (cmd->scan_begin_src == TRIG_TIMER)
1237                err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
1238                                                 this_board->ai_ns_min);
1239
1240        if (cmd->scan_begin_src == TRIG_EXT)
1241                if (cmd->scan_begin_arg) {
1242                        cmd->scan_begin_arg = 0;
1243                        err |= -EINVAL;
1244                        err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg,
1245                                                         65535);
1246                }
1247
1248        if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
1249                err |= cfc_check_trigger_arg_min(&cmd->convert_arg,
1250                                                 this_board->ai_ns_min);
1251
1252        if (cmd->convert_src == TRIG_EXT)
1253                err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
1254
1255        if (cmd->stop_src == TRIG_COUNT)
1256                err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
1257        else    /* TRIG_NONE */
1258                err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
1259
1260        err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
1261        err |= cfc_check_trigger_arg_max(&cmd->chanlist_len,
1262                                         this_board->n_aichanlist);
1263
1264        err |= cfc_check_trigger_arg_min(&cmd->scan_end_arg,
1265                                         cmd->chanlist_len);
1266
1267        if ((cmd->scan_end_arg % cmd->chanlist_len)) {
1268                cmd->scan_end_arg =
1269                    cmd->chanlist_len * (cmd->scan_end_arg / cmd->chanlist_len);
1270                err |= -EINVAL;
1271        }
1272
1273        if (err)
1274                return 3;
1275
1276        /* step 4: fix up any arguments */
1277
1278        if (cmd->scan_begin_src == TRIG_TIMER) {
1279                tmp = cmd->scan_begin_arg;
1280                i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1281                                          &divisor2, &cmd->scan_begin_arg,
1282                                          cmd->flags & TRIG_ROUND_MASK);
1283                if (cmd->scan_begin_arg < this_board->ai_ns_min)
1284                        cmd->scan_begin_arg = this_board->ai_ns_min;
1285                if (tmp != cmd->scan_begin_arg)
1286                        err++;
1287        }
1288
1289        if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
1290                tmp = cmd->convert_arg;
1291                i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
1292                                          &divisor2, &cmd->convert_arg,
1293                                          cmd->flags & TRIG_ROUND_MASK);
1294                if (cmd->convert_arg < this_board->ai_ns_min)
1295                        cmd->convert_arg = this_board->ai_ns_min;
1296                if (tmp != cmd->convert_arg)
1297                        err++;
1298                if (cmd->scan_begin_src == TRIG_TIMER
1299                    && cmd->convert_src == TRIG_NOW) {
1300                        if (cmd->convert_arg == 0) {
1301                                if (cmd->scan_begin_arg <
1302                                    this_board->ai_ns_min *
1303                                    (cmd->scan_end_arg + 2)) {
1304                                        cmd->scan_begin_arg =
1305                                            this_board->ai_ns_min *
1306                                            (cmd->scan_end_arg + 2);
1307                                        err++;
1308                                }
1309                        } else {
1310                                if (cmd->scan_begin_arg <
1311                                    cmd->convert_arg * cmd->chanlist_len) {
1312                                        cmd->scan_begin_arg =
1313                                            cmd->convert_arg *
1314                                            cmd->chanlist_len;
1315                                        err++;
1316                                }
1317                        }
1318                }
1319        }
1320
1321        if (err)
1322                return 4;
1323
1324        if (cmd->chanlist)
1325                if (!check_channel_list(dev, s, cmd->chanlist_len,
1326                                        cmd->chanlist, 0, 0))
1327                        return 5;       /* incorrect channels list */
1328
1329        return 0;
1330}
1331
1332static int Compute_and_setup_dma(struct comedi_device *dev)
1333{
1334        struct pci9118_private *devpriv = dev->private;
1335        unsigned int dmalen0, dmalen1, i;
1336
1337        dmalen0 = devpriv->dmabuf_size[0];
1338        dmalen1 = devpriv->dmabuf_size[1];
1339        /* isn't output buff smaller that our DMA buff? */
1340        if (dmalen0 > (devpriv->ai_data_len)) {
1341                dmalen0 = devpriv->ai_data_len & ~3L;   /*
1342                                                         * align to 32bit down
1343                                                         */
1344        }
1345        if (dmalen1 > (devpriv->ai_data_len)) {
1346                dmalen1 = devpriv->ai_data_len & ~3L;   /*
1347                                                         * align to 32bit down
1348                                                         */
1349        }
1350
1351        /* we want wake up every scan? */
1352        if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1353                if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
1354                        /* uff, too short DMA buffer, disable EOS support! */
1355                        devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1356                        dev_info(dev->class_dev,
1357                                 "WAR: DMA0 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
1358                                  dmalen0, devpriv->ai_n_realscanlen << 1);
1359                } else {
1360                        /* short first DMA buffer to one scan */
1361                        dmalen0 = devpriv->ai_n_realscanlen << 1;
1362                        if (devpriv->useeoshandle)
1363                                dmalen0 += 2;
1364                        if (dmalen0 < 4) {
1365                                dev_info(dev->class_dev,
1366                                         "ERR: DMA0 buf len bug? (%d<4)\n",
1367                                         dmalen0);
1368                                dmalen0 = 4;
1369                        }
1370                }
1371        }
1372        if (devpriv->ai_flags & TRIG_WAKE_EOS) {
1373                if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
1374                        /* uff, too short DMA buffer, disable EOS support! */
1375                        devpriv->ai_flags &= (~TRIG_WAKE_EOS);
1376                        dev_info(dev->class_dev,
1377                                 "WAR: DMA1 buf too short, can't support TRIG_WAKE_EOS (%d<%d)\n",
1378                                 dmalen1, devpriv->ai_n_realscanlen << 1);
1379                } else {
1380                        /* short second DMA buffer to one scan */
1381                        dmalen1 = devpriv->ai_n_realscanlen << 1;
1382                        if (devpriv->useeoshandle)
1383                                dmalen1 -= 2;
1384                        if (dmalen1 < 4) {
1385                                dev_info(dev->class_dev,
1386                                         "ERR: DMA1 buf len bug? (%d<4)\n",
1387                                         dmalen1);
1388                                dmalen1 = 4;
1389                        }
1390                }
1391        }
1392
1393        /* transfer without TRIG_WAKE_EOS */
1394        if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
1395                /* if it's possible then align DMA buffers to length of scan */
1396                i = dmalen0;
1397                dmalen0 =
1398                    (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
1399                    (devpriv->ai_n_realscanlen << 1);
1400                dmalen0 &= ~3L;
1401                if (!dmalen0)
1402                        dmalen0 = i;    /* uff. very long scan? */
1403                i = dmalen1;
1404                dmalen1 =
1405                    (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
1406                    (devpriv->ai_n_realscanlen << 1);
1407                dmalen1 &= ~3L;
1408                if (!dmalen1)
1409                        dmalen1 = i;    /* uff. very long scan? */
1410                /*
1411                 * if measure isn't neverending then test, if it fits whole
1412                 * into one or two DMA buffers
1413                 */
1414                if (!devpriv->ai_neverending) {
1415                        /* fits whole measure into one DMA buffer? */
1416                        if (dmalen0 >
1417                            ((devpriv->ai_n_realscanlen << 1) *
1418                             devpriv->ai_scans)) {
1419                                dmalen0 =
1420                                    (devpriv->ai_n_realscanlen << 1) *
1421                                    devpriv->ai_scans;
1422                                dmalen0 &= ~3L;
1423                        } else {        /*
1424                                         * fits whole measure into
1425                                         * two DMA buffer?
1426                                         */
1427                                if (dmalen1 >
1428                                    ((devpriv->ai_n_realscanlen << 1) *
1429                                     devpriv->ai_scans - dmalen0))
1430                                        dmalen1 =
1431                                            (devpriv->ai_n_realscanlen << 1) *
1432                                            devpriv->ai_scans - dmalen0;
1433                                dmalen1 &= ~3L;
1434                        }
1435                }
1436        }
1437
1438        /* these DMA buffer size will be used */
1439        devpriv->dma_actbuf = 0;
1440        devpriv->dmabuf_use_size[0] = dmalen0;
1441        devpriv->dmabuf_use_size[1] = dmalen1;
1442
1443#if 0
1444        if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
1445                devpriv->dmabuf_panic_size[0] =
1446                    (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1447                     1) * devpriv->ai_n_scanlen * sizeof(short);
1448                devpriv->dmabuf_panic_size[1] =
1449                    (this_board->half_fifo_size / devpriv->ai_n_scanlen +
1450                     1) * devpriv->ai_n_scanlen * sizeof(short);
1451        } else {
1452                devpriv->dmabuf_panic_size[0] =
1453                    (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
1454                devpriv->dmabuf_panic_size[1] =
1455                    (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
1456        }
1457#endif
1458
1459        outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS),
1460                        devpriv->iobase_a + AMCC_OP_REG_MCSR);  /* stop DMA */
1461        outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
1462        outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
1463        /* init DMA transfer */
1464        outl(0x00000000 | AINT_WRITE_COMPL,
1465             devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1466/* outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR); */
1467
1468        outl(inl(devpriv->iobase_a +
1469                 AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
1470             EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
1471        outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS,
1472                        devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1473                                                /* allow bus mastering */
1474
1475        return 0;
1476}
1477
1478static int pci9118_ai_docmd_sampl(struct comedi_device *dev,
1479                                  struct comedi_subdevice *s)
1480{
1481        struct pci9118_private *devpriv = dev->private;
1482
1483        switch (devpriv->ai_do) {
1484        case 1:
1485                devpriv->AdControlReg |= AdControl_TmrTr;
1486                break;
1487        case 2:
1488                comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
1489                return -EIO;
1490        case 3:
1491                devpriv->AdControlReg |= AdControl_ExtM;
1492                break;
1493        case 4:
1494                comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
1495                return -EIO;
1496        default:
1497                comedi_error(dev,
1498                             "pci9118_ai_docmd_sampl() mode number bug!\n");
1499                return -EIO;
1500        }
1501
1502        devpriv->int_ai_func = interrupt_pci9118_ai_onesample;
1503                                                /* transfer function */
1504
1505        if (devpriv->ai12_startstop)
1506                pci9118_exttrg_add(dev, EXTTRG_AI);
1507                                                /* activate EXT trigger */
1508
1509        if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
1510                devpriv->IntControlReg |= Int_Timer;
1511
1512        devpriv->AdControlReg |= AdControl_Int;
1513
1514        outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00,
1515                        devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1516                                                        /* allow INT in AMCC */
1517
1518        if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1519                outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1520                outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1521                if (devpriv->ai_do != 3) {
1522                        start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1523                                    devpriv->ai_divisor2);
1524                        devpriv->AdControlReg |= AdControl_SoftG;
1525                }
1526                outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1527        }
1528
1529        return 0;
1530}
1531
1532static int pci9118_ai_docmd_dma(struct comedi_device *dev,
1533                                struct comedi_subdevice *s)
1534{
1535        struct pci9118_private *devpriv = dev->private;
1536
1537        Compute_and_setup_dma(dev);
1538
1539        switch (devpriv->ai_do) {
1540        case 1:
1541                devpriv->AdControlReg |=
1542                    ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1543                break;
1544        case 2:
1545                devpriv->AdControlReg |=
1546                    ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1547                devpriv->AdFunctionReg =
1548                    AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
1549                    AdFunction_BS;
1550                if (devpriv->usessh && (!devpriv->softsshdelay))
1551                        devpriv->AdFunctionReg |= AdFunction_BSSH;
1552                outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
1553                break;
1554        case 3:
1555                devpriv->AdControlReg |=
1556                    ((AdControl_ExtM | AdControl_Dma) & 0xff);
1557                devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1558                break;
1559        case 4:
1560                devpriv->AdControlReg |=
1561                    ((AdControl_TmrTr | AdControl_Dma) & 0xff);
1562                devpriv->AdFunctionReg =
1563                    AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
1564                outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1565                outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1566                outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
1567                     dev->iobase + PCI9118_CNT0);
1568                outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
1569                     dev->iobase + PCI9118_CNT0);
1570                devpriv->AdFunctionReg |= AdFunction_Start;
1571                break;
1572        default:
1573                comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
1574                return -EIO;
1575        }
1576
1577        if (devpriv->ai12_startstop) {
1578                pci9118_exttrg_add(dev, EXTTRG_AI);
1579                                                /* activate EXT trigger */
1580        }
1581
1582        devpriv->int_ai_func = interrupt_pci9118_ai_dma;
1583                                                /* transfer function */
1584
1585        outl(0x02000000 | AINT_WRITE_COMPL,
1586             devpriv->iobase_a + AMCC_OP_REG_INTCSR);
1587
1588        if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
1589                outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1590                outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1591                if (devpriv->ai_do != 3) {
1592                        start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
1593                                    devpriv->ai_divisor2);
1594                        devpriv->AdControlReg |= AdControl_SoftG;
1595                }
1596                outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1597        }
1598
1599        return 0;
1600}
1601
1602static int pci9118_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
1603{
1604        const struct boardtype *this_board = comedi_board(dev);
1605        struct pci9118_private *devpriv = dev->private;
1606        struct comedi_cmd *cmd = &s->async->cmd;
1607        unsigned int addchans = 0;
1608        int ret = 0;
1609
1610        devpriv->ai12_startstop = 0;
1611        devpriv->ai_flags = cmd->flags;
1612        devpriv->ai_n_chan = cmd->chanlist_len;
1613        devpriv->ai_n_scanlen = cmd->scan_end_arg;
1614        devpriv->ai_chanlist = cmd->chanlist;
1615        devpriv->ai_data = s->async->prealloc_buf;
1616        devpriv->ai_data_len = s->async->prealloc_bufsz;
1617        devpriv->ai_timer1 = 0;
1618        devpriv->ai_timer2 = 0;
1619        devpriv->ai_add_front = 0;
1620        devpriv->ai_add_back = 0;
1621        devpriv->ai_maskerr = 0x10e;
1622
1623        /* prepare for start/stop conditions */
1624        if (cmd->start_src == TRIG_EXT)
1625                devpriv->ai12_startstop |= START_AI_EXT;
1626        if (cmd->stop_src == TRIG_EXT) {
1627                devpriv->ai_neverending = 1;
1628                devpriv->ai12_startstop |= STOP_AI_EXT;
1629        }
1630        if (cmd->start_src == TRIG_INT) {
1631                devpriv->ai12_startstop |= START_AI_INT;
1632                devpriv->ai_inttrig_start = cmd->start_arg;
1633                s->async->inttrig = pci9118_ai_inttrig;
1634        }
1635#if 0
1636        if (cmd->stop_src == TRIG_INT) {
1637                devpriv->ai_neverending = 1;
1638                devpriv->ai12_startstop |= STOP_AI_INT;
1639        }
1640#endif
1641        if (cmd->stop_src == TRIG_NONE)
1642                devpriv->ai_neverending = 1;
1643        if (cmd->stop_src == TRIG_COUNT) {
1644                devpriv->ai_scans = cmd->stop_arg;
1645                devpriv->ai_neverending = 0;
1646        } else {
1647                devpriv->ai_scans = 0;
1648        }
1649
1650        /* use sample&hold signal? */
1651        if (cmd->convert_src == TRIG_NOW)
1652                devpriv->usessh = 1;
1653        /* yes */
1654        else
1655                devpriv->usessh = 0;
1656                                /*  no */
1657
1658        /*
1659         * use additional sample at end of every scan
1660         * to satisty DMA 32 bit transfer?
1661         */
1662        devpriv->ai_add_front = 0;
1663        devpriv->ai_add_back = 0;
1664        devpriv->useeoshandle = 0;
1665        if (devpriv->master) {
1666                devpriv->usedma = 1;
1667                if ((cmd->flags & TRIG_WAKE_EOS) &&
1668                    (devpriv->ai_n_scanlen == 1)) {
1669                        if (cmd->convert_src == TRIG_NOW)
1670                                devpriv->ai_add_back = 1;
1671                        if (cmd->convert_src == TRIG_TIMER) {
1672                                devpriv->usedma = 0;
1673                                        /*
1674                                         * use INT transfer if scanlist
1675                                         * have only one channel
1676                                         */
1677                        }
1678                }
1679                if ((cmd->flags & TRIG_WAKE_EOS) &&
1680                    (devpriv->ai_n_scanlen & 1) &&
1681                    (devpriv->ai_n_scanlen > 1)) {
1682                        if (cmd->scan_begin_src == TRIG_FOLLOW) {
1683                                /*
1684                                 * vpriv->useeoshandle=1; // change DMA transfer
1685                                 * block to fit EOS on every second call
1686                                 */
1687                                devpriv->usedma = 0;
1688                                /*
1689                                 * XXX maybe can be corrected to use 16 bit DMA
1690                                 */
1691                        } else {        /*
1692                                         * well, we must insert one sample
1693                                         * to end of EOS to meet 32 bit transfer
1694                                         */
1695                                devpriv->ai_add_back = 1;
1696                        }
1697                }
1698        } else {        /* interrupt transfer don't need any correction */
1699                devpriv->usedma = 0;
1700        }
1701
1702        /*
1703         * we need software S&H signal?
1704         * It adds two samples before every scan as minimum
1705         */
1706        if (devpriv->usessh && devpriv->softsshdelay) {
1707                devpriv->ai_add_front = 2;
1708                if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) {
1709                                                        /* move it to front */
1710                        devpriv->ai_add_front++;
1711                        devpriv->ai_add_back = 0;
1712                }
1713                if (cmd->convert_arg < this_board->ai_ns_min)
1714                        cmd->convert_arg = this_board->ai_ns_min;
1715                addchans = devpriv->softsshdelay / cmd->convert_arg;
1716                if (devpriv->softsshdelay % cmd->convert_arg)
1717                        addchans++;
1718                if (addchans > (devpriv->ai_add_front - 1)) {
1719                                                        /* uff, still short */
1720                        devpriv->ai_add_front = addchans + 1;
1721                        if (devpriv->usedma == 1)
1722                                if ((devpriv->ai_add_front +
1723                                     devpriv->ai_n_chan +
1724                                     devpriv->ai_add_back) & 1)
1725                                        devpriv->ai_add_front++;
1726                                                        /* round up to 32 bit */
1727                }
1728        }
1729        /* well, we now know what must be all added */
1730        devpriv->ai_n_realscanlen =     /*
1731                                         * what we must take from card in real
1732                                         * to have ai_n_scanlen on output?
1733                                         */
1734            (devpriv->ai_add_front + devpriv->ai_n_chan +
1735             devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
1736                                      devpriv->ai_n_chan);
1737
1738        /* check and setup channel list */
1739        if (!check_channel_list(dev, s, devpriv->ai_n_chan,
1740                                devpriv->ai_chanlist, devpriv->ai_add_front,
1741                                devpriv->ai_add_back))
1742                return -EINVAL;
1743        if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
1744                                devpriv->ai_chanlist, 0, devpriv->ai_add_front,
1745                                devpriv->ai_add_back, devpriv->usedma,
1746                                devpriv->useeoshandle))
1747                return -EINVAL;
1748
1749        /* compute timers settings */
1750        /*
1751         * simplest way, fr=4Mhz/(tim1*tim2),
1752         * channel manipulation without timers effect
1753         */
1754        if (((cmd->scan_begin_src == TRIG_FOLLOW) ||
1755                (cmd->scan_begin_src == TRIG_EXT) ||
1756                (cmd->scan_begin_src == TRIG_INT)) &&
1757                (cmd->convert_src == TRIG_TIMER)) {
1758                                        /* both timer is used for one time */
1759                if (cmd->scan_begin_src == TRIG_EXT)
1760                        devpriv->ai_do = 4;
1761                else
1762                        devpriv->ai_do = 1;
1763                pci9118_calc_divisors(devpriv->ai_do, dev, s,
1764                                      &cmd->scan_begin_arg, &cmd->convert_arg,
1765                                      devpriv->ai_flags,
1766                                      devpriv->ai_n_realscanlen,
1767                                      &devpriv->ai_divisor1,
1768                                      &devpriv->ai_divisor2, devpriv->usessh,
1769                                      devpriv->ai_add_front);
1770                devpriv->ai_timer2 = cmd->convert_arg;
1771        }
1772
1773        if ((cmd->scan_begin_src == TRIG_TIMER) &&
1774                ((cmd->convert_src == TRIG_TIMER) ||
1775                (cmd->convert_src == TRIG_NOW))) {
1776                                                /* double timed action */
1777                if (!devpriv->usedma) {
1778                        comedi_error(dev,
1779                                     "cmd->scan_begin_src=TRIG_TIMER works "
1780                                                "only with bus mastering!");
1781                        return -EIO;
1782                }
1783
1784                devpriv->ai_do = 2;
1785                pci9118_calc_divisors(devpriv->ai_do, dev, s,
1786                                      &cmd->scan_begin_arg, &cmd->convert_arg,
1787                                      devpriv->ai_flags,
1788                                      devpriv->ai_n_realscanlen,
1789                                      &devpriv->ai_divisor1,
1790                                      &devpriv->ai_divisor2, devpriv->usessh,
1791                                      devpriv->ai_add_front);
1792                devpriv->ai_timer1 = cmd->scan_begin_arg;
1793                devpriv->ai_timer2 = cmd->convert_arg;
1794        }
1795
1796        if ((cmd->scan_begin_src == TRIG_FOLLOW)
1797            && (cmd->convert_src == TRIG_EXT)) {
1798                devpriv->ai_do = 3;
1799        }
1800
1801        start_pacer(dev, -1, 0, 0);     /* stop pacer */
1802
1803        devpriv->AdControlReg = 0;      /*
1804                                         * bipolar, S.E., use 8254, stop 8354,
1805                                         * internal trigger, soft trigger,
1806                                         * disable DMA
1807                                         */
1808        outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1809        devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1810                                        /*
1811                                         * positive triggers, no S&H, no burst,
1812                                         * burst stop, no post trigger,
1813                                         * no about trigger, trigger stop
1814                                         */
1815        outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1816        udelay(1);
1817        outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1818        inl(dev->iobase + PCI9118_ADSTAT);      /*
1819                                                 * flush A/D and INT
1820                                                 * status register
1821                                                 */
1822        inl(dev->iobase + PCI9118_INTSRC);
1823
1824        devpriv->ai_act_scan = 0;
1825        devpriv->ai_act_dmapos = 0;
1826        s->async->cur_chan = 0;
1827        devpriv->ai_buf_ptr = 0;
1828
1829        if (devpriv->usedma)
1830                ret = pci9118_ai_docmd_dma(dev, s);
1831        else
1832                ret = pci9118_ai_docmd_sampl(dev, s);
1833
1834        return ret;
1835}
1836
1837static int pci9118_reset(struct comedi_device *dev)
1838{
1839        struct pci9118_private *devpriv = dev->private;
1840
1841        devpriv->IntControlReg = 0;
1842        devpriv->exttrg_users = 0;
1843        inl(dev->iobase + PCI9118_INTCTRL);
1844        outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
1845                                                /* disable interrupts source */
1846        outl(0x30, dev->iobase + PCI9118_CNTCTRL);
1847/* outl(0xb4, dev->iobase + PCI9118_CNTCTRL); */
1848        start_pacer(dev, 0, 0, 0);              /* stop 8254 counters */
1849        devpriv->AdControlReg = 0;
1850        outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1851                                                /*
1852                                                 * bipolar, S.E., use 8254,
1853                                                 * stop 8354, internal trigger,
1854                                                 * soft trigger,
1855                                                 * disable INT and DMA
1856                                                 */
1857        outl(0, dev->iobase + PCI9118_BURST);
1858        outl(1, dev->iobase + PCI9118_SCANMOD);
1859        outl(2, dev->iobase + PCI9118_SCANMOD); /* reset scan queue */
1860        devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
1861        outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
1862                                                /*
1863                                                 * positive triggers, no S&H,
1864                                                 * no burst, burst stop,
1865                                                 * no post trigger,
1866                                                 * no about trigger,
1867                                                 * trigger stop
1868                                                 */
1869
1870        devpriv->ao_data[0] = 2047;
1871        devpriv->ao_data[1] = 2047;
1872        outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1);
1873                                                /* reset A/D outs to 0V */
1874        outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
1875        outl(0, dev->iobase + PCI9118_DO);      /* reset digi outs to L */
1876        udelay(10);
1877        inl(dev->iobase + PCI9118_AD_DATA);
1878        outl(0, dev->iobase + PCI9118_DELFIFO); /* flush FIFO */
1879        outl(0, dev->iobase + PCI9118_INTSRC);  /* remove INT requests */
1880        inl(dev->iobase + PCI9118_ADSTAT);      /* flush A/D status register */
1881        inl(dev->iobase + PCI9118_INTSRC);      /* flush INT requests */
1882        devpriv->AdControlReg = 0;
1883        outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
1884                                                /*
1885                                                 * bipolar, S.E., use 8254,
1886                                                 * stop 8354, internal trigger,
1887                                                 * soft trigger,
1888                                                 * disable INT and DMA
1889                                                 */
1890
1891        devpriv->cnt0_users = 0;
1892        devpriv->exttrg_users = 0;
1893
1894        return 0;
1895}
1896
1897/*
1898 * FIXME - this is pretty ineffective because all the supported board types
1899 * have the same device ID!
1900 */
1901static const struct boardtype *pci9118_find_boardinfo(struct pci_dev *pcidev)
1902{
1903        unsigned int i;
1904
1905        for (i = 0; i < ARRAY_SIZE(boardtypes); i++)
1906                if (pcidev->device == boardtypes[i].device_id)
1907                        return &boardtypes[i];
1908        return NULL;
1909}
1910
1911static struct pci_dev *pci9118_find_pci(struct comedi_device *dev,
1912                                        struct comedi_devconfig *it)
1913{
1914        const struct boardtype *this_board = comedi_board(dev);
1915        struct pci_dev *pcidev = NULL;
1916        int bus = it->options[0];
1917        int slot = it->options[1];
1918
1919        for_each_pci_dev(pcidev) {
1920                if (pcidev->vendor != PCI_VENDOR_ID_AMCC)
1921                        continue;
1922                if (pcidev->device != this_board->device_id)
1923                        continue;
1924                if (bus || slot) {
1925                        /* requested particular bus/slot */
1926                        if (pcidev->bus->number != bus ||
1927                            PCI_SLOT(pcidev->devfn) != slot)
1928                                continue;
1929                }
1930                return pcidev;
1931        }
1932        dev_err(dev->class_dev,
1933                "no supported board found! (req. bus/slot : %d/%d)\n",
1934                bus, slot);
1935        return NULL;
1936}
1937
1938static void pci9118_report_attach(struct comedi_device *dev, unsigned int irq)
1939{
1940        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1941        struct pci9118_private *devpriv = dev->private;
1942        char irqbuf[30];
1943        char muxbuf[30];
1944
1945        if (irq)
1946                snprintf(irqbuf, sizeof(irqbuf), "irq %u%s", irq,
1947                         (dev->irq ? "" : " UNAVAILABLE"));
1948        else
1949                snprintf(irqbuf, sizeof(irqbuf), "irq DISABLED");
1950        if (devpriv->usemux)
1951                snprintf(muxbuf, sizeof(muxbuf), "ext mux %u chans",
1952                         devpriv->usemux);
1953        else
1954                snprintf(muxbuf, sizeof(muxbuf), "no ext mux");
1955        dev_info(dev->class_dev, "%s (pci %s, %s, %sbus master, %s) attached\n",
1956                 dev->board_name, pci_name(pcidev), irqbuf,
1957                 (devpriv->master ? "" : "no "), muxbuf);
1958}
1959
1960static int pci9118_common_attach(struct comedi_device *dev, int disable_irq,
1961                                 int master, int ext_mux, int softsshdelay,
1962                                 int hw_err_mask)
1963{
1964        const struct boardtype *this_board = comedi_board(dev);
1965        struct pci9118_private *devpriv = dev->private;
1966        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
1967        struct comedi_subdevice *s;
1968        int ret, pages, i;
1969        unsigned int irq;
1970        u16 u16w;
1971
1972        dev->board_name = this_board->name;
1973        ret = comedi_pci_enable(pcidev, dev->board_name);
1974        if (ret) {
1975                dev_err(dev->class_dev,
1976                        "cannot enable PCI device %s\n", pci_name(pcidev));
1977                return ret;
1978        }
1979        if (master)
1980                pci_set_master(pcidev);
1981
1982        devpriv->iobase_a = pci_resource_start(pcidev, 0);
1983        dev->iobase = pci_resource_start(pcidev, 2);
1984
1985        pci9118_reset(dev);
1986
1987        if (master) {           /* alloc DMA buffers */
1988                devpriv->dma_doublebuf = 0;
1989                for (i = 0; i < 2; i++) {
1990                        for (pages = 4; pages >= 0; pages--) {
1991                                devpriv->dmabuf_virt[i] =
1992                                    (short *)__get_free_pages(GFP_KERNEL,
1993                                                              pages);
1994                                if (devpriv->dmabuf_virt[i])
1995                                        break;
1996                        }
1997                        if (devpriv->dmabuf_virt[i]) {
1998                                devpriv->dmabuf_pages[i] = pages;
1999                                devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
2000                                devpriv->dmabuf_samples[i] =
2001                                    devpriv->dmabuf_size[i] >> 1;
2002                                devpriv->dmabuf_hw[i] =
2003                                    virt_to_bus((void *)
2004                                                devpriv->dmabuf_virt[i]);
2005                        }
2006                }
2007                if (!devpriv->dmabuf_virt[0]) {
2008                        dev_warn(dev->class_dev,
2009                                 "Can't allocate DMA buffer, DMA disabled!\n");
2010                        master = 0;
2011                }
2012                if (devpriv->dmabuf_virt[1])
2013                        devpriv->dma_doublebuf = 1;
2014        }
2015        devpriv->master = master;
2016
2017        if (ext_mux > 0) {
2018                if (ext_mux > 256)
2019                        ext_mux = 256;  /* max 256 channels! */
2020                if (softsshdelay > 0)
2021                        if (ext_mux > 128)
2022                                ext_mux = 128;
2023                devpriv->usemux = ext_mux;
2024        } else {
2025                devpriv->usemux = 0;
2026        }
2027
2028        if (softsshdelay < 0) {
2029                /* select sample&hold signal polarity */
2030                devpriv->softsshdelay = -softsshdelay;
2031                devpriv->softsshsample = 0x80;
2032                devpriv->softsshhold = 0x00;
2033        } else {
2034                devpriv->softsshdelay = softsshdelay;
2035                devpriv->softsshsample = 0x00;
2036                devpriv->softsshhold = 0x80;
2037        }
2038
2039        pci_read_config_word(pcidev, PCI_COMMAND, &u16w);
2040        pci_write_config_word(pcidev, PCI_COMMAND, u16w | 64);
2041                                /* Enable parity check for parity error */
2042
2043        ret = comedi_alloc_subdevices(dev, 4);
2044        if (ret)
2045                return ret;
2046
2047        s = &dev->subdevices[0];
2048        dev->read_subdev = s;
2049        s->type = COMEDI_SUBD_AI;
2050        s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
2051        if (devpriv->usemux)
2052                s->n_chan = devpriv->usemux;
2053        else
2054                s->n_chan = this_board->n_aichan;
2055
2056        s->maxdata = this_board->ai_maxdata;
2057        s->len_chanlist = this_board->n_aichanlist;
2058        s->range_table = this_board->rangelist_ai;
2059        s->cancel = pci9118_ai_cancel;
2060        s->insn_read = pci9118_insn_read_ai;
2061        s->munge = pci9118_ai_munge;
2062
2063        s = &dev->subdevices[1];
2064        s->type = COMEDI_SUBD_AO;
2065        s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2066        s->n_chan = this_board->n_aochan;
2067        s->maxdata = this_board->ao_maxdata;
2068        s->len_chanlist = this_board->n_aochan;
2069        s->range_table = this_board->rangelist_ao;
2070        s->insn_write = pci9118_insn_write_ao;
2071        s->insn_read = pci9118_insn_read_ao;
2072
2073        s = &dev->subdevices[2];
2074        s->type = COMEDI_SUBD_DI;
2075        s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
2076        s->n_chan = 4;
2077        s->maxdata = 1;
2078        s->len_chanlist = 4;
2079        s->range_table = &range_digital;
2080        s->io_bits = 0;         /* all bits input */
2081        s->insn_bits = pci9118_insn_bits_di;
2082
2083        s = &dev->subdevices[3];
2084        s->type = COMEDI_SUBD_DO;
2085        s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
2086        s->n_chan = 4;
2087        s->maxdata = 1;
2088        s->len_chanlist = 4;
2089        s->range_table = &range_digital;
2090        s->io_bits = 0xf;       /* all bits output */
2091        s->insn_bits = pci9118_insn_bits_do;
2092
2093        devpriv->valid = 1;
2094        devpriv->i8254_osc_base = 250;  /* 250ns=4MHz */
2095        devpriv->ai_maskharderr = 0x10a;
2096                                        /* default measure crash condition */
2097        if (hw_err_mask)                /* disable some requested */
2098                devpriv->ai_maskharderr &= ~hw_err_mask;
2099
2100        switch (this_board->ai_maxdata) {
2101        case 0xffff:
2102                devpriv->ai16bits = 1;
2103                break;
2104        default:
2105                devpriv->ai16bits = 0;
2106                break;
2107        }
2108
2109        if (disable_irq)
2110                irq = 0;
2111        else
2112                irq = pcidev->irq;
2113        if (irq > 0) {
2114                if (request_irq(irq, interrupt_pci9118, IRQF_SHARED,
2115                                dev->board_name, dev)) {
2116                        dev_warn(dev->class_dev,
2117                                 "unable to allocate IRQ %u, DISABLING IT\n",
2118                                 irq);
2119                } else {
2120                        dev->irq = irq;
2121                        /* Enable AI commands */
2122                        s = &dev->subdevices[0];
2123                        s->subdev_flags |= SDF_CMD_READ;
2124                        s->do_cmdtest = pci9118_ai_cmdtest;
2125                        s->do_cmd = pci9118_ai_cmd;
2126                }
2127        }
2128
2129        pci9118_report_attach(dev, irq);
2130        return 0;
2131}
2132
2133static int pci9118_attach(struct comedi_device *dev,
2134                          struct comedi_devconfig *it)
2135{
2136        struct pci9118_private *devpriv;
2137        struct pci_dev *pcidev;
2138        int ext_mux, disable_irq, master, softsshdelay, hw_err_mask;
2139
2140        ext_mux = it->options[2];
2141        master = ((it->options[3] & 1) == 0);
2142        disable_irq = ((it->options[3] & 2) != 0);
2143        softsshdelay = it->options[4];
2144        hw_err_mask = it->options[5];
2145
2146        devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
2147        if (!devpriv)
2148                return -ENOMEM;
2149        dev->private = devpriv;
2150
2151        pcidev = pci9118_find_pci(dev, it);
2152        if (!pcidev)
2153                return -EIO;
2154        comedi_set_hw_dev(dev, &pcidev->dev);
2155
2156        return pci9118_common_attach(dev, disable_irq, master, ext_mux,
2157                                     softsshdelay, hw_err_mask);
2158}
2159
2160static int pci9118_auto_attach(struct comedi_device *dev,
2161                                         unsigned long context_unused)
2162{
2163        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2164        struct pci9118_private *devpriv;
2165
2166        devpriv = kzalloc(sizeof(*devpriv), GFP_KERNEL);
2167        if (!devpriv)
2168                return -ENOMEM;
2169        dev->private = devpriv;
2170
2171        dev->board_ptr = pci9118_find_boardinfo(pcidev);
2172        if (dev->board_ptr == NULL) {
2173                dev_err(dev->class_dev,
2174                        "adl_pci9118: cannot determine board type for pci %s\n",
2175                        pci_name(pcidev));
2176                return -EINVAL;
2177        }
2178        /*
2179         * Need to 'get' the PCI device to match the 'put' in pci9118_detach().
2180         * (The 'put' also matches the implicit 'get' by pci9118_find_pci().)
2181         */
2182        pci_dev_get(pcidev);
2183        /* Don't disable irq, use bus master, no external mux,
2184         * no sample-hold delay, no error mask. */
2185        return pci9118_common_attach(dev, 0, 1, 0, 0, 0);
2186}
2187
2188static void pci9118_detach(struct comedi_device *dev)
2189{
2190        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
2191        struct pci9118_private *devpriv = dev->private;
2192
2193        if (devpriv) {
2194                if (devpriv->valid)
2195                        pci9118_reset(dev);
2196                if (dev->irq)
2197                        free_irq(dev->irq, dev);
2198                if (devpriv->dmabuf_virt[0])
2199                        free_pages((unsigned long)devpriv->dmabuf_virt[0],
2200                                   devpriv->dmabuf_pages[0]);
2201                if (devpriv->dmabuf_virt[1])
2202                        free_pages((unsigned long)devpriv->dmabuf_virt[1],
2203                                   devpriv->dmabuf_pages[1]);
2204        }
2205        if (pcidev) {
2206                if (dev->iobase)
2207                        comedi_pci_disable(pcidev);
2208
2209                pci_dev_put(pcidev);
2210        }
2211}
2212
2213static struct comedi_driver adl_pci9118_driver = {
2214        .driver_name    = "adl_pci9118",
2215        .module         = THIS_MODULE,
2216        .attach         = pci9118_attach,
2217        .auto_attach    = pci9118_auto_attach,
2218        .detach         = pci9118_detach,
2219        .num_names      = ARRAY_SIZE(boardtypes),
2220        .board_name     = &boardtypes[0].name,
2221        .offset         = sizeof(struct boardtype),
2222};
2223
2224static int adl_pci9118_pci_probe(struct pci_dev *dev,
2225                                           const struct pci_device_id *ent)
2226{
2227        return comedi_pci_auto_config(dev, &adl_pci9118_driver);
2228}
2229
2230static DEFINE_PCI_DEVICE_TABLE(adl_pci9118_pci_table) = {
2231        { PCI_DEVICE(PCI_VENDOR_ID_AMCC, 0x80d9) },
2232        { 0 }
2233};
2234MODULE_DEVICE_TABLE(pci, adl_pci9118_pci_table);
2235
2236static struct pci_driver adl_pci9118_pci_driver = {
2237        .name           = "adl_pci9118",
2238        .id_table       = adl_pci9118_pci_table,
2239        .probe          = adl_pci9118_pci_probe,
2240        .remove         = comedi_pci_auto_unconfig,
2241};
2242module_comedi_pci_driver(adl_pci9118_driver, adl_pci9118_pci_driver);
2243
2244MODULE_AUTHOR("Comedi http://www.comedi.org");
2245MODULE_DESCRIPTION("Comedi low-level driver");
2246MODULE_LICENSE("GPL");
2247