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