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