linux/drivers/staging/comedi/drivers/ni_pcidio.c
<<
>>
Prefs
   1/*
   2    comedi/drivers/ni_pcidio.c
   3    driver for National Instruments PCI-DIO-96/PCI-6508
   4                National Instruments PCI-DIO-32HS
   5                National Instruments PCI-6503
   6
   7    COMEDI - Linux Control and Measurement Device Interface
   8    Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
   9
  10    This program is free software; you can redistribute it and/or modify
  11    it under the terms of the GNU General Public License as published by
  12    the Free Software Foundation; either version 2 of the License, or
  13    (at your option) any later version.
  14
  15    This program is distributed in the hope that it will be useful,
  16    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18    GNU General Public License for more details.
  19
  20    You should have received a copy of the GNU General Public License
  21    along with this program; if not, write to the Free Software
  22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23
  24*/
  25/*
  26Driver: ni_pcidio
  27Description: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503
  28Author: ds
  29Status: works
  30Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533,
  31  PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,
  32  PXI-6503, PCI-6533, PCI-6534
  33Updated: Sun, 21 Apr 2002 21:03:38 -0700
  34
  35The DIO-96 appears as four 8255 subdevices.  See the 8255
  36driver notes for details.
  37
  38The DIO32HS board appears as one subdevice, with 32 channels.
  39Each channel is individually I/O configurable.  The channel order
  40is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0.  The driver only
  41supports simple digital I/O; no handshaking is supported.
  42
  43DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
  44
  45This driver could be easily modified to support AT-MIO32HS and
  46AT-MIO96.
  47
  48The PCI-6534 requires a firmware upload after power-up to work, the
  49firmware data and instructions for loading it with comedi_config
  50it are contained in the
  51comedi_nonfree_firmware tarball available from http://www.comedi.org
  52*/
  53
  54/*
  55   This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96,
  56   which have very different architectures.  But, since the '96 is
  57   so simple, it is included here.
  58
  59   Manuals (available from ftp://ftp.natinst.com/support/manuals)
  60
  61        320938c.pdf     PCI-DIO-96/PXI-6508/PCI-6503 User Manual
  62        321464b.pdf     AT/PCI-DIO-32HS User Manual
  63        341329A.pdf     PCI-6533 Register-Level Programmer Manual
  64        341330A.pdf     DAQ-DIO Technical Reference Manual
  65
  66 */
  67
  68#define USE_DMA
  69/* #define DEBUG 1 */
  70/* #define DEBUG_FLAGS */
  71
  72#include <linux/interrupt.h>
  73#include <linux/sched.h>
  74#include "../comedidev.h"
  75
  76#include "mite.h"
  77#include "8255.h"
  78
  79#undef DPRINTK
  80#ifdef DEBUG
  81#define DPRINTK(format, args...)        printk(format, ## args)
  82#else
  83#define DPRINTK(format, args...)
  84#endif
  85
  86#define PCI_DIO_SIZE 4096
  87#define PCI_MITE_SIZE 4096
  88
  89/* defines for the PCI-DIO-96 */
  90
  91#define NIDIO_8255_BASE(x)      ((x)*4)
  92#define NIDIO_A 0
  93#define NIDIO_B 4
  94#define NIDIO_C 8
  95#define NIDIO_D 12
  96
  97/* defines for the PCI-DIO-32HS */
  98
  99#define Window_Address                  4       /* W */
 100#define Interrupt_And_Window_Status     4       /* R */
 101#define IntStatus1                              (1<<0)
 102#define IntStatus2                              (1<<1)
 103#define WindowAddressStatus_mask                0x7c
 104
 105#define Master_DMA_And_Interrupt_Control 5      /* W */
 106#define InterruptLine(x)                        ((x)&3)
 107#define OpenInt                         (1<<2)
 108#define Group_Status                    5       /* R */
 109#define DataLeft                                (1<<0)
 110#define Req                                     (1<<2)
 111#define StopTrig                                (1<<3)
 112
 113#define Group_1_Flags                   6       /* R */
 114#define Group_2_Flags                   7       /* R */
 115#define TransferReady                           (1<<0)
 116#define CountExpired                            (1<<1)
 117#define Waited                          (1<<5)
 118#define PrimaryTC                               (1<<6)
 119#define SecondaryTC                             (1<<7)
 120  /* #define SerialRose */
 121  /* #define ReqRose */
 122  /* #define Paused */
 123
 124#define Group_1_First_Clear             6       /* W */
 125#define Group_2_First_Clear             7       /* W */
 126#define ClearWaited                             (1<<3)
 127#define ClearPrimaryTC                  (1<<4)
 128#define ClearSecondaryTC                        (1<<5)
 129#define DMAReset                                (1<<6)
 130#define FIFOReset                               (1<<7)
 131#define ClearAll                                0xf8
 132
 133#define Group_1_FIFO                    8       /* W */
 134#define Group_2_FIFO                    12      /* W */
 135
 136#define Transfer_Count                  20
 137#define Chip_ID_D                       24
 138#define Chip_ID_I                       25
 139#define Chip_ID_O                       26
 140#define Chip_Version                    27
 141#define Port_IO(x)                      (28+(x))
 142#define Port_Pin_Directions(x)          (32+(x))
 143#define Port_Pin_Mask(x)                (36+(x))
 144#define Port_Pin_Polarities(x)          (40+(x))
 145
 146#define Master_Clock_Routing            45
 147#define RTSIClocking(x)                 (((x)&3)<<4)
 148
 149#define Group_1_Second_Clear            46      /* W */
 150#define Group_2_Second_Clear            47      /* W */
 151#define ClearExpired                            (1<<0)
 152
 153#define Port_Pattern(x)                 (48+(x))
 154
 155#define Data_Path                       64
 156#define FIFOEnableA             (1<<0)
 157#define FIFOEnableB             (1<<1)
 158#define FIFOEnableC             (1<<2)
 159#define FIFOEnableD             (1<<3)
 160#define Funneling(x)            (((x)&3)<<4)
 161#define GroupDirection  (1<<7)
 162
 163#define Protocol_Register_1             65
 164#define OpMode                          Protocol_Register_1
 165#define RunMode(x)              ((x)&7)
 166#define Numbered                (1<<3)
 167
 168#define Protocol_Register_2             66
 169#define ClockReg                        Protocol_Register_2
 170#define ClockLine(x)            (((x)&3)<<5)
 171#define InvertStopTrig  (1<<7)
 172#define DataLatching(x)       (((x)&3)<<5)
 173
 174#define Protocol_Register_3             67
 175#define Sequence                        Protocol_Register_3
 176
 177#define Protocol_Register_14            68      /* 16 bit */
 178#define ClockSpeed                      Protocol_Register_14
 179
 180#define Protocol_Register_4             70
 181#define ReqReg                          Protocol_Register_4
 182#define ReqConditioning(x)      (((x)&7)<<3)
 183
 184#define Protocol_Register_5             71
 185#define BlockMode                       Protocol_Register_5
 186
 187#define FIFO_Control                    72
 188#define ReadyLevel(x)           ((x)&7)
 189
 190#define Protocol_Register_6             73
 191#define LinePolarities                  Protocol_Register_6
 192#define InvertAck               (1<<0)
 193#define InvertReq               (1<<1)
 194#define InvertClock             (1<<2)
 195#define InvertSerial            (1<<3)
 196#define OpenAck         (1<<4)
 197#define OpenClock               (1<<5)
 198
 199#define Protocol_Register_7             74
 200#define AckSer                          Protocol_Register_7
 201#define AckLine(x)              (((x)&3)<<2)
 202#define ExchangePins            (1<<7)
 203
 204#define Interrupt_Control               75
 205  /* bits same as flags */
 206
 207#define DMA_Line_Control_Group1         76
 208#define DMA_Line_Control_Group2         108
 209/* channel zero is none */
 210static inline unsigned primary_DMAChannel_bits(unsigned channel)
 211{
 212        return channel & 0x3;
 213}
 214
 215static inline unsigned secondary_DMAChannel_bits(unsigned channel)
 216{
 217        return (channel << 2) & 0xc;
 218}
 219
 220#define Transfer_Size_Control           77
 221#define TransferWidth(x)        ((x)&3)
 222#define TransferLength(x)       (((x)&3)<<3)
 223#define RequireRLevel           (1<<5)
 224
 225#define Protocol_Register_15            79
 226#define DAQOptions                      Protocol_Register_15
 227#define StartSource(x)                  ((x)&0x3)
 228#define InvertStart                             (1<<2)
 229#define StopSource(x)                           (((x)&0x3)<<3)
 230#define ReqStart                                (1<<6)
 231#define PreStart                                (1<<7)
 232
 233#define Pattern_Detection               81
 234#define DetectionMethod                 (1<<0)
 235#define InvertMatch                             (1<<1)
 236#define IE_Pattern_Detection                    (1<<2)
 237
 238#define Protocol_Register_9             82
 239#define ReqDelay                        Protocol_Register_9
 240
 241#define Protocol_Register_10            83
 242#define ReqNotDelay                     Protocol_Register_10
 243
 244#define Protocol_Register_11            84
 245#define AckDelay                        Protocol_Register_11
 246
 247#define Protocol_Register_12            85
 248#define AckNotDelay                     Protocol_Register_12
 249
 250#define Protocol_Register_13            86
 251#define Data1Delay                      Protocol_Register_13
 252
 253#define Protocol_Register_8             88      /* 32 bit */
 254#define StartDelay                      Protocol_Register_8
 255
 256enum pci_6534_firmware_registers {      /* 16 bit */
 257        Firmware_Control_Register = 0x100,
 258        Firmware_Status_Register = 0x104,
 259        Firmware_Data_Register = 0x108,
 260        Firmware_Mask_Register = 0x10c,
 261        Firmware_Debug_Register = 0x110,
 262};
 263/* main fpga registers (32 bit)*/
 264enum pci_6534_fpga_registers {
 265        FPGA_Control1_Register = 0x200,
 266        FPGA_Control2_Register = 0x204,
 267        FPGA_Irq_Mask_Register = 0x208,
 268        FPGA_Status_Register = 0x20c,
 269        FPGA_Signature_Register = 0x210,
 270        FPGA_SCALS_Counter_Register = 0x280,    /*write-clear */
 271        FPGA_SCAMS_Counter_Register = 0x284,    /*write-clear */
 272        FPGA_SCBLS_Counter_Register = 0x288,    /*write-clear */
 273        FPGA_SCBMS_Counter_Register = 0x28c,    /*write-clear */
 274        FPGA_Temp_Control_Register = 0x2a0,
 275        FPGA_DAR_Register = 0x2a8,
 276        FPGA_ELC_Read_Register = 0x2b8,
 277        FPGA_ELC_Write_Register = 0x2bc,
 278};
 279enum FPGA_Control_Bits {
 280        FPGA_Enable_Bit = 0x8000,
 281};
 282
 283#define TIMER_BASE 50           /* nanoseconds */
 284
 285#ifdef USE_DMA
 286#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
 287#else
 288#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
 289#endif
 290
 291static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it);
 292static int nidio_detach(struct comedi_device *dev);
 293static int ni_pcidio_cancel(struct comedi_device *dev,
 294                            struct comedi_subdevice *s);
 295
 296static struct comedi_driver driver_pcidio = {
 297        .driver_name = "ni_pcidio",
 298        .module = THIS_MODULE,
 299        .attach = nidio_attach,
 300        .detach = nidio_detach,
 301};
 302
 303struct nidio_board {
 304
 305        int dev_id;
 306        const char *name;
 307        int n_8255;
 308        unsigned int is_diodaq:1;
 309        unsigned int uses_firmware:1;
 310};
 311
 312static const struct nidio_board nidio_boards[] = {
 313        {
 314         .dev_id = 0x1150,
 315         .name = "pci-dio-32hs",
 316         .n_8255 = 0,
 317         .is_diodaq = 1,
 318         },
 319        {
 320         .dev_id = 0x1320,
 321         .name = "pxi-6533",
 322         .n_8255 = 0,
 323         .is_diodaq = 1,
 324         },
 325        {
 326         .dev_id = 0x12b0,
 327         .name = "pci-6534",
 328         .n_8255 = 0,
 329         .is_diodaq = 1,
 330         .uses_firmware = 1,
 331         },
 332        {
 333         .dev_id = 0x0160,
 334         .name = "pci-dio-96",
 335         .n_8255 = 4,
 336         .is_diodaq = 0,
 337         },
 338        {
 339         .dev_id = 0x1630,
 340         .name = "pci-dio-96b",
 341         .n_8255 = 4,
 342         .is_diodaq = 0,
 343         },
 344        {
 345         .dev_id = 0x13c0,
 346         .name = "pxi-6508",
 347         .n_8255 = 4,
 348         .is_diodaq = 0,
 349         },
 350        {
 351         .dev_id = 0x0400,
 352         .name = "pci-6503",
 353         .n_8255 = 1,
 354         .is_diodaq = 0,
 355         },
 356        {
 357         .dev_id = 0x1250,
 358         .name = "pci-6503b",
 359         .n_8255 = 1,
 360         .is_diodaq = 0,
 361         },
 362        {
 363         .dev_id = 0x17d0,
 364         .name = "pci-6503x",
 365         .n_8255 = 1,
 366         .is_diodaq = 0,
 367         },
 368        {
 369         .dev_id = 0x1800,
 370         .name = "pxi-6503",
 371         .n_8255 = 1,
 372         .is_diodaq = 0,
 373         },
 374};
 375
 376#define n_nidio_boards ARRAY_SIZE(nidio_boards)
 377#define this_board ((const struct nidio_board *)dev->board_ptr)
 378
 379static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
 380        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1150)},
 381        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1320)},
 382        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x12b0)},
 383        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0160)},
 384        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1630)},
 385        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x13c0)},
 386        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x0400)},
 387        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1250)},
 388        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x17d0)},
 389        {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x1800)},
 390        {0}
 391};
 392
 393MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
 394
 395struct nidio96_private {
 396        struct mite_struct *mite;
 397        int boardtype;
 398        int dio;
 399        unsigned short OpModeBits;
 400        struct mite_channel *di_mite_chan;
 401        struct mite_dma_descriptor_ring *di_mite_ring;
 402        spinlock_t mite_channel_lock;
 403};
 404#define devpriv ((struct nidio96_private *)dev->private)
 405
 406static int ni_pcidio_cmdtest(struct comedi_device *dev,
 407                             struct comedi_subdevice *s,
 408                             struct comedi_cmd *cmd);
 409static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
 410static int ni_pcidio_inttrig(struct comedi_device *dev,
 411                             struct comedi_subdevice *s, unsigned int trignum);
 412static int nidio_find_device(struct comedi_device *dev, int bus, int slot);
 413static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
 414static int setup_mite_dma(struct comedi_device *dev,
 415                          struct comedi_subdevice *s);
 416
 417#ifdef DEBUG_FLAGS
 418static void ni_pcidio_print_flags(unsigned int flags);
 419static void ni_pcidio_print_status(unsigned int status);
 420#else
 421#define ni_pcidio_print_flags(x)
 422#define ni_pcidio_print_status(x)
 423#endif
 424
 425static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
 426{
 427        unsigned long flags;
 428
 429        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
 430        BUG_ON(devpriv->di_mite_chan);
 431        devpriv->di_mite_chan =
 432            mite_request_channel_in_range(devpriv->mite,
 433                                          devpriv->di_mite_ring, 1, 2);
 434        if (devpriv->di_mite_chan == NULL) {
 435                spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 436                comedi_error(dev, "failed to reserve mite dma channel.");
 437                return -EBUSY;
 438        }
 439        writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
 440               secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
 441               devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
 442        mmiowb();
 443        spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 444        return 0;
 445}
 446
 447static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
 448{
 449        unsigned long flags;
 450
 451        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
 452        if (devpriv->di_mite_chan) {
 453                mite_dma_disarm(devpriv->di_mite_chan);
 454                mite_dma_reset(devpriv->di_mite_chan);
 455                mite_release_channel(devpriv->di_mite_chan);
 456                devpriv->di_mite_chan = NULL;
 457                writeb(primary_DMAChannel_bits(0) |
 458                       secondary_DMAChannel_bits(0),
 459                       devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
 460                mmiowb();
 461        }
 462        spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 463}
 464
 465static int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase)
 466{
 467        if (dir) {
 468                writeb(data, (void *)(iobase + port));
 469                return 0;
 470        } else {
 471                return readb((void *)(iobase + port));
 472        }
 473}
 474
 475void ni_pcidio_event(struct comedi_device *dev, struct comedi_subdevice *s)
 476{
 477        if (s->
 478            async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
 479                             COMEDI_CB_OVERFLOW)) {
 480                ni_pcidio_cancel(dev, s);
 481        }
 482        comedi_event(dev, s);
 483}
 484
 485static irqreturn_t nidio_interrupt(int irq, void *d)
 486{
 487        struct comedi_device *dev = d;
 488        struct comedi_subdevice *s = dev->subdevices;
 489        struct comedi_async *async = s->async;
 490        struct mite_struct *mite = devpriv->mite;
 491
 492        /* int i, j; */
 493        long int AuxData = 0;
 494        short data1 = 0;
 495        short data2 = 0;
 496        int flags;
 497        int status;
 498        int work = 0;
 499        unsigned int m_status = 0;
 500        unsigned long irq_flags;
 501
 502        /* interrupcions parasites */
 503        if (dev->attached == 0) {
 504                /* assume it's from another card */
 505                return IRQ_NONE;
 506        }
 507
 508        status = readb(devpriv->mite->daq_io_addr +
 509                       Interrupt_And_Window_Status);
 510        flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
 511
 512        DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
 513                status, flags);
 514        ni_pcidio_print_flags(flags);
 515        ni_pcidio_print_status(status);
 516
 517        /* printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf); */
 518        /* printk("buf[4096]=%08x\n",
 519               *(unsigned int *)(async->prealloc_buf+4096)); */
 520
 521        spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
 522        if (devpriv->di_mite_chan)
 523                m_status = mite_get_status(devpriv->di_mite_chan);
 524#ifdef MITE_DEBUG
 525        mite_print_chsr(m_status);
 526#endif
 527        /* printk("mite_bytes_transferred: %d\n",
 528               mite_bytes_transferred(mite,DI_DMA_CHAN)); */
 529
 530        /* mite_dump_regs(mite); */
 531        if (m_status & CHSR_INT) {
 532                if (m_status & CHSR_LINKC) {
 533                        writel(CHOR_CLRLC,
 534                               mite->mite_io_addr +
 535                               MITE_CHOR(devpriv->di_mite_chan->channel));
 536                        mite_sync_input_dma(devpriv->di_mite_chan, s->async);
 537                        /* XXX need to byteswap */
 538                }
 539                if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
 540                                 CHSR_DRQ1 | CHSR_MRDY)) {
 541                        DPRINTK("unknown mite interrupt, disabling IRQ\n");
 542                        async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 543                        disable_irq(dev->irq);
 544                }
 545        }
 546        spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
 547
 548        while (status & DataLeft) {
 549                work++;
 550                if (work > 20) {
 551                        DPRINTK("too much work in interrupt\n");
 552                        writeb(0x00,
 553                               devpriv->mite->daq_io_addr +
 554                               Master_DMA_And_Interrupt_Control);
 555                        break;
 556                }
 557
 558                flags &= IntEn;
 559
 560                if (flags & TransferReady) {
 561                        /* DPRINTK("TransferReady\n"); */
 562                        while (flags & TransferReady) {
 563                                work++;
 564                                if (work > 100) {
 565                                        DPRINTK("too much work in interrupt\n");
 566                                        writeb(0x00,
 567                                               devpriv->mite->daq_io_addr +
 568                                               Master_DMA_And_Interrupt_Control
 569                                              );
 570                                        goto out;
 571                                }
 572                                AuxData =
 573                                    readl(devpriv->mite->daq_io_addr +
 574                                          Group_1_FIFO);
 575                                data1 = AuxData & 0xffff;
 576                                data2 = (AuxData & 0xffff0000) >> 16;
 577                                comedi_buf_put(async, data1);
 578                                comedi_buf_put(async, data2);
 579                                /* DPRINTK("read:%d, %d\n",data1,data2); */
 580                                flags = readb(devpriv->mite->daq_io_addr +
 581                                              Group_1_Flags);
 582                        }
 583                        /* DPRINTK("buf_int_count: %d\n",
 584                                async->buf_int_count); */
 585                        /* DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",
 586                                IntEn,flags,status); */
 587                        /* ni_pcidio_print_flags(flags); */
 588                        /* ni_pcidio_print_status(status); */
 589                        async->events |= COMEDI_CB_BLOCK;
 590                }
 591
 592                if (flags & CountExpired) {
 593                        DPRINTK("CountExpired\n");
 594                        writeb(ClearExpired,
 595                               devpriv->mite->daq_io_addr +
 596                               Group_1_Second_Clear);
 597                        async->events |= COMEDI_CB_EOA;
 598
 599                        writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
 600                        break;
 601                } else if (flags & Waited) {
 602                        DPRINTK("Waited\n");
 603                        writeb(ClearWaited,
 604                               devpriv->mite->daq_io_addr +
 605                               Group_1_First_Clear);
 606                        async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 607                        break;
 608                } else if (flags & PrimaryTC) {
 609                        DPRINTK("PrimaryTC\n");
 610                        writeb(ClearPrimaryTC,
 611                               devpriv->mite->daq_io_addr +
 612                               Group_1_First_Clear);
 613                        async->events |= COMEDI_CB_EOA;
 614                } else if (flags & SecondaryTC) {
 615                        DPRINTK("SecondaryTC\n");
 616                        writeb(ClearSecondaryTC,
 617                               devpriv->mite->daq_io_addr +
 618                               Group_1_First_Clear);
 619                        async->events |= COMEDI_CB_EOA;
 620                }
 621#if 0
 622                else {
 623                        printk("ni_pcidio: unknown interrupt\n");
 624                        async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
 625                        writeb(0x00,
 626                               devpriv->mite->daq_io_addr +
 627                               Master_DMA_And_Interrupt_Control);
 628                }
 629#endif
 630                flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
 631                status = readb(devpriv->mite->daq_io_addr +
 632                               Interrupt_And_Window_Status);
 633                /* DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,"
 634                        "status=0x%02x\n", IntEn, flags, status); */
 635                /* ni_pcidio_print_flags(flags); */
 636                /* ni_pcidio_print_status(status); */
 637        }
 638
 639out:
 640        ni_pcidio_event(dev, s);
 641#if 0
 642        if (!tag) {
 643                writeb(0x03,
 644                       devpriv->mite->daq_io_addr +
 645                       Master_DMA_And_Interrupt_Control);
 646        }
 647#endif
 648        return IRQ_HANDLED;
 649}
 650
 651#ifdef DEBUG_FLAGS
 652static const char *const flags_strings[] = {
 653        "TransferReady", "CountExpired", "2", "3",
 654        "4", "Waited", "PrimaryTC", "SecondaryTC",
 655};
 656
 657static void ni_pcidio_print_flags(unsigned int flags)
 658{
 659        int i;
 660
 661        printk(KERN_INFO "group_1_flags:");
 662        for (i = 7; i >= 0; i--) {
 663                if (flags & (1 << i))
 664                        printk(" %s", flags_strings[i]);
 665        }
 666        printk("\n");
 667}
 668
 669static char *status_strings[] = {
 670        "DataLeft1", "Reserved1", "Req1", "StopTrig1",
 671        "DataLeft2", "Reserved2", "Req2", "StopTrig2",
 672};
 673
 674static void ni_pcidio_print_status(unsigned int flags)
 675{
 676        int i;
 677
 678        printk(KERN_INFO "group_status:");
 679        for (i = 7; i >= 0; i--) {
 680                if (flags & (1 << i))
 681                        printk(" %s", status_strings[i]);
 682        }
 683        printk("\n");
 684}
 685#endif
 686
 687#ifdef unused
 688static void debug_int(struct comedi_device *dev)
 689{
 690        int a, b;
 691        static int n_int = 0;
 692        struct timeval tv;
 693
 694        do_gettimeofday(&tv);
 695        a = readb(devpriv->mite->daq_io_addr + Group_Status);
 696        b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
 697
 698        if (n_int < 10) {
 699                DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
 700                        (int)tv.tv_usec);
 701        }
 702
 703        while (b & 1) {
 704                writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
 705                b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
 706        }
 707
 708        b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
 709
 710        if (n_int < 10) {
 711                DPRINTK("new status 0x%02x\n", b);
 712                n_int++;
 713        }
 714}
 715#endif
 716
 717static int ni_pcidio_insn_config(struct comedi_device *dev,
 718                                 struct comedi_subdevice *s,
 719                                 struct comedi_insn *insn, unsigned int *data)
 720{
 721        if (insn->n != 1)
 722                return -EINVAL;
 723        switch (data[0]) {
 724        case INSN_CONFIG_DIO_OUTPUT:
 725                s->io_bits |= 1 << CR_CHAN(insn->chanspec);
 726                break;
 727        case INSN_CONFIG_DIO_INPUT:
 728                s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
 729                break;
 730        case INSN_CONFIG_DIO_QUERY:
 731                data[1] =
 732                    (s->
 733                     io_bits & (1 << CR_CHAN(insn->chanspec))) ? COMEDI_OUTPUT :
 734                    COMEDI_INPUT;
 735                return insn->n;
 736                break;
 737        default:
 738                return -EINVAL;
 739        }
 740        writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
 741
 742        return 1;
 743}
 744
 745static int ni_pcidio_insn_bits(struct comedi_device *dev,
 746                               struct comedi_subdevice *s,
 747                               struct comedi_insn *insn, unsigned int *data)
 748{
 749        if (insn->n != 2)
 750                return -EINVAL;
 751        if (data[0]) {
 752                s->state &= ~data[0];
 753                s->state |= (data[0] & data[1]);
 754                writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
 755        }
 756        data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
 757
 758        return 2;
 759}
 760
 761static int ni_pcidio_cmdtest(struct comedi_device *dev,
 762                             struct comedi_subdevice *s, struct comedi_cmd *cmd)
 763{
 764        int err = 0;
 765        int tmp;
 766
 767        /* step 1: make sure trigger sources are trivially valid */
 768
 769        tmp = cmd->start_src;
 770        cmd->start_src &= TRIG_NOW | TRIG_INT;
 771        if (!cmd->start_src || tmp != cmd->start_src)
 772                err++;
 773
 774        tmp = cmd->scan_begin_src;
 775        cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
 776        if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
 777                err++;
 778
 779        tmp = cmd->convert_src;
 780        cmd->convert_src &= TRIG_NOW;
 781        if (!cmd->convert_src || tmp != cmd->convert_src)
 782                err++;
 783
 784        tmp = cmd->scan_end_src;
 785        cmd->scan_end_src &= TRIG_COUNT;
 786        if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
 787                err++;
 788
 789        tmp = cmd->stop_src;
 790        cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
 791        if (!cmd->stop_src || tmp != cmd->stop_src)
 792                err++;
 793
 794        if (err)
 795                return 1;
 796
 797        /* step 2: make sure trigger sources are unique and mutually
 798        compatible */
 799
 800        /* note that mutual compatibility is not an issue here */
 801        if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
 802                err++;
 803        if (cmd->scan_begin_src != TRIG_TIMER &&
 804            cmd->scan_begin_src != TRIG_EXT)
 805                err++;
 806
 807        if (err)
 808                return 2;
 809
 810        /* step 3: make sure arguments are trivially compatible */
 811
 812        if (cmd->start_arg != 0) {
 813                /* same for both TRIG_INT and TRIG_NOW */
 814                cmd->start_arg = 0;
 815                err++;
 816        }
 817#define MAX_SPEED       (TIMER_BASE)    /* in nanoseconds */
 818
 819        if (cmd->scan_begin_src == TRIG_TIMER) {
 820                if (cmd->scan_begin_arg < MAX_SPEED) {
 821                        cmd->scan_begin_arg = MAX_SPEED;
 822                        err++;
 823                }
 824                /* no minumum speed */
 825        } else {
 826                /* TRIG_EXT */
 827                /* should be level/edge, hi/lo specification here */
 828                if (cmd->scan_begin_arg != 0) {
 829                        cmd->scan_begin_arg = 0;
 830                        err++;
 831                }
 832        }
 833        if (cmd->convert_arg != 0) {
 834                cmd->convert_arg = 0;
 835                err++;
 836        }
 837
 838        if (cmd->scan_end_arg != cmd->chanlist_len) {
 839                cmd->scan_end_arg = cmd->chanlist_len;
 840                err++;
 841        }
 842        if (cmd->stop_src == TRIG_COUNT) {
 843                /* no limit */
 844        } else {
 845                /* TRIG_NONE */
 846                if (cmd->stop_arg != 0) {
 847                        cmd->stop_arg = 0;
 848                        err++;
 849                }
 850        }
 851
 852        if (err)
 853                return 3;
 854
 855        /* step 4: fix up any arguments */
 856
 857        if (cmd->scan_begin_src == TRIG_TIMER) {
 858                tmp = cmd->scan_begin_arg;
 859                ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
 860                                      cmd->flags & TRIG_ROUND_MASK);
 861                if (tmp != cmd->scan_begin_arg)
 862                        err++;
 863        }
 864
 865        if (err)
 866                return 4;
 867
 868        return 0;
 869}
 870
 871static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
 872{
 873        int divider, base;
 874
 875        base = TIMER_BASE;
 876
 877        switch (round_mode) {
 878        case TRIG_ROUND_NEAREST:
 879        default:
 880                divider = (*nanosec + base / 2) / base;
 881                break;
 882        case TRIG_ROUND_DOWN:
 883                divider = (*nanosec) / base;
 884                break;
 885        case TRIG_ROUND_UP:
 886                divider = (*nanosec + base - 1) / base;
 887                break;
 888        }
 889
 890        *nanosec = base * divider;
 891        return divider;
 892}
 893
 894static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 895{
 896        struct comedi_cmd *cmd = &s->async->cmd;
 897
 898        /* XXX configure ports for input */
 899        writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
 900
 901        if (1) {
 902                /* enable fifos A B C D */
 903                writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
 904
 905                /* set transfer width a 32 bits */
 906                writeb(TransferWidth(0) | TransferLength(0),
 907                       devpriv->mite->daq_io_addr + Transfer_Size_Control);
 908        } else {
 909                writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
 910                writeb(TransferWidth(3) | TransferLength(0),
 911                       devpriv->mite->daq_io_addr + Transfer_Size_Control);
 912        }
 913
 914        /* protocol configuration */
 915        if (cmd->scan_begin_src == TRIG_TIMER) {
 916                /* page 4-5, "input with internal REQs" */
 917                writeb(0, devpriv->mite->daq_io_addr + OpMode);
 918                writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
 919                writeb(1, devpriv->mite->daq_io_addr + Sequence);
 920                writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
 921                writeb(4, devpriv->mite->daq_io_addr + BlockMode);
 922                writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
 923                writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
 924                writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
 925                                             TRIG_ROUND_NEAREST),
 926                       devpriv->mite->daq_io_addr + StartDelay);
 927                writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
 928                writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
 929                writeb(1, devpriv->mite->daq_io_addr + AckDelay);
 930                writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
 931                writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
 932                /* manual, page 4-5: ClockSpeed comment is incorrectly listed
 933                 * on DAQOptions */
 934                writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
 935                writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
 936        } else {
 937                /* TRIG_EXT */
 938                /* page 4-5, "input with external REQs" */
 939                writeb(0, devpriv->mite->daq_io_addr + OpMode);
 940                writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
 941                writeb(0, devpriv->mite->daq_io_addr + Sequence);
 942                writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
 943                writeb(4, devpriv->mite->daq_io_addr + BlockMode);
 944                writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
 945                writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
 946                writel(1, devpriv->mite->daq_io_addr + StartDelay);
 947                writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
 948                writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
 949                writeb(1, devpriv->mite->daq_io_addr + AckDelay);
 950                writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
 951                writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
 952                writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
 953                writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
 954        }
 955
 956        if (cmd->stop_src == TRIG_COUNT) {
 957                writel(cmd->stop_arg,
 958                       devpriv->mite->daq_io_addr + Transfer_Count);
 959        } else {
 960                /* XXX */
 961        }
 962
 963#ifdef USE_DMA
 964        writeb(ClearPrimaryTC | ClearSecondaryTC,
 965               devpriv->mite->daq_io_addr + Group_1_First_Clear);
 966
 967        {
 968                int retval = setup_mite_dma(dev, s);
 969                if (retval)
 970                        return retval;
 971        }
 972#else
 973        writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
 974#endif
 975        writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
 976
 977        /* clear and enable interrupts */
 978        writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
 979        /* writeb(ClearExpired,
 980               devpriv->mite->daq_io_addr+Group_1_Second_Clear); */
 981
 982        writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
 983        writeb(0x03,
 984               devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
 985
 986        if (cmd->stop_src == TRIG_NONE) {
 987                devpriv->OpModeBits = DataLatching(0) | RunMode(7);
 988        } else {                /* TRIG_TIMER */
 989                devpriv->OpModeBits = Numbered | RunMode(7);
 990        }
 991        if (cmd->start_src == TRIG_NOW) {
 992                /* start */
 993                writeb(devpriv->OpModeBits,
 994                       devpriv->mite->daq_io_addr + OpMode);
 995                s->async->inttrig = NULL;
 996        } else {
 997                /* TRIG_INT */
 998                s->async->inttrig = ni_pcidio_inttrig;
 999        }
1000
1001        DPRINTK("ni_pcidio: command started\n");
1002        return 0;
1003}
1004
1005static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
1006{
1007        int retval;
1008
1009        retval = ni_pcidio_request_di_mite_channel(dev);
1010        if (retval)
1011                return retval;
1012
1013        devpriv->di_mite_chan->dir = COMEDI_INPUT;
1014
1015        mite_prep_dma(devpriv->di_mite_chan, 32, 32);
1016
1017        mite_dma_arm(devpriv->di_mite_chan);
1018        return 0;
1019}
1020
1021static int ni_pcidio_inttrig(struct comedi_device *dev,
1022                             struct comedi_subdevice *s, unsigned int trignum)
1023{
1024        if (trignum != 0)
1025                return -EINVAL;
1026
1027        writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
1028        s->async->inttrig = NULL;
1029
1030        return 1;
1031}
1032
1033static int ni_pcidio_cancel(struct comedi_device *dev,
1034                            struct comedi_subdevice *s)
1035{
1036        writeb(0x00,
1037               devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
1038        ni_pcidio_release_di_mite_channel(dev);
1039
1040        return 0;
1041}
1042
1043static int ni_pcidio_change(struct comedi_device *dev,
1044                            struct comedi_subdevice *s, unsigned long new_size)
1045{
1046        int ret;
1047
1048        ret = mite_buf_change(devpriv->di_mite_ring, s->async);
1049        if (ret < 0)
1050                return ret;
1051
1052        memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
1053
1054        return 0;
1055}
1056
1057static int pci_6534_load_fpga(struct comedi_device *dev, int fpga_index,
1058                              u8 *data, int data_len)
1059{
1060        static const int timeout = 1000;
1061        int i, j;
1062        writew(0x80 | fpga_index,
1063               devpriv->mite->daq_io_addr + Firmware_Control_Register);
1064        writew(0xc0 | fpga_index,
1065               devpriv->mite->daq_io_addr + Firmware_Control_Register);
1066        for (i = 0;
1067             (readw(devpriv->mite->daq_io_addr +
1068                    Firmware_Status_Register) & 0x2) == 0 && i < timeout; ++i) {
1069                udelay(1);
1070        }
1071        if (i == timeout) {
1072                printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
1073                       "waiting for status 0x2\n", fpga_index);
1074                return -EIO;
1075        }
1076        writew(0x80 | fpga_index,
1077               devpriv->mite->daq_io_addr + Firmware_Control_Register);
1078        for (i = 0;
1079             readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
1080             0x3 && i < timeout; ++i) {
1081                udelay(1);
1082        }
1083        if (i == timeout) {
1084                printk(KERN_WARNING "ni_pcidio: failed to load fpga %i, "
1085                       "waiting for status 0x3\n", fpga_index);
1086                return -EIO;
1087        }
1088        for (j = 0; j + 1 < data_len;) {
1089                unsigned int value = data[j++];
1090                value |= data[j++] << 8;
1091                writew(value,
1092                       devpriv->mite->daq_io_addr + Firmware_Data_Register);
1093                for (i = 0;
1094                     (readw(devpriv->mite->daq_io_addr +
1095                            Firmware_Status_Register) & 0x2) == 0
1096                     && i < timeout; ++i) {
1097                        udelay(1);
1098                }
1099                if (i == timeout) {
1100                        printk("ni_pcidio: failed to load word into fpga %i\n",
1101                               fpga_index);
1102                        return -EIO;
1103                }
1104                if (need_resched())
1105                        schedule();
1106        }
1107        writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1108        return 0;
1109}
1110
1111static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
1112{
1113        return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
1114}
1115
1116static int pci_6534_reset_fpgas(struct comedi_device *dev)
1117{
1118        int ret;
1119        int i;
1120        writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
1121        for (i = 0; i < 3; ++i) {
1122                ret = pci_6534_reset_fpga(dev, i);
1123                if (ret < 0)
1124                        break;
1125        }
1126        writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
1127        return ret;
1128}
1129
1130static void pci_6534_init_main_fpga(struct comedi_device *dev)
1131{
1132        writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
1133        writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
1134        writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
1135        writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
1136        writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
1137        writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
1138}
1139
1140static int pci_6534_upload_firmware(struct comedi_device *dev, int options[])
1141{
1142        int ret;
1143        void *main_fpga_data, *scarab_a_data, *scarab_b_data;
1144        int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len;
1145
1146        if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0)
1147                return 0;
1148        ret = pci_6534_reset_fpgas(dev);
1149        if (ret < 0)
1150                return ret;
1151        main_fpga_data = comedi_aux_data(options, 0);
1152        main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
1153        ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len);
1154        if (ret < 0)
1155                return ret;
1156        pci_6534_init_main_fpga(dev);
1157        scarab_a_data = comedi_aux_data(options, 1);
1158        scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
1159        ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len);
1160        if (ret < 0)
1161                return ret;
1162        scarab_b_data = comedi_aux_data(options, 2);
1163        scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
1164        ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len);
1165        if (ret < 0)
1166                return ret;
1167        return 0;
1168}
1169
1170static int nidio_attach(struct comedi_device *dev, struct comedi_devconfig *it)
1171{
1172        struct comedi_subdevice *s;
1173        int i;
1174        int ret;
1175        int n_subdevices;
1176        unsigned int irq;
1177
1178        printk(KERN_INFO "comedi%d: nidio:", dev->minor);
1179
1180        ret = alloc_private(dev, sizeof(struct nidio96_private));
1181        if (ret < 0)
1182                return ret;
1183        spin_lock_init(&devpriv->mite_channel_lock);
1184
1185        ret = nidio_find_device(dev, it->options[0], it->options[1]);
1186        if (ret < 0)
1187                return ret;
1188
1189        ret = mite_setup(devpriv->mite);
1190        if (ret < 0) {
1191                printk(KERN_WARNING "error setting up mite\n");
1192                return ret;
1193        }
1194        comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
1195        devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
1196        if (devpriv->di_mite_ring == NULL)
1197                return -ENOMEM;
1198
1199        dev->board_name = this_board->name;
1200        irq = mite_irq(devpriv->mite);
1201        printk(KERN_INFO " %s", dev->board_name);
1202        if (this_board->uses_firmware) {
1203                ret = pci_6534_upload_firmware(dev, it->options);
1204                if (ret < 0)
1205                        return ret;
1206        }
1207        if (!this_board->is_diodaq)
1208                n_subdevices = this_board->n_8255;
1209        else
1210                n_subdevices = 1;
1211
1212        ret = alloc_subdevices(dev, n_subdevices);
1213        if (ret < 0)
1214                return ret;
1215
1216        if (!this_board->is_diodaq) {
1217                for (i = 0; i < this_board->n_8255; i++) {
1218                        subdev_8255_init(dev, dev->subdevices + i,
1219                                         nidio96_8255_cb,
1220                                         (unsigned long)(devpriv->mite->
1221                                                         daq_io_addr +
1222                                                         NIDIO_8255_BASE(i)));
1223                }
1224        } else {
1225
1226                printk(KERN_INFO " rev=%d",
1227                       readb(devpriv->mite->daq_io_addr + Chip_Version));
1228
1229                s = dev->subdevices + 0;
1230
1231                dev->read_subdev = s;
1232                s->type = COMEDI_SUBD_DIO;
1233                s->subdev_flags =
1234                    SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
1235                    SDF_CMD_READ;
1236                s->n_chan = 32;
1237                s->range_table = &range_digital;
1238                s->maxdata = 1;
1239                s->insn_config = &ni_pcidio_insn_config;
1240                s->insn_bits = &ni_pcidio_insn_bits;
1241                s->do_cmd = &ni_pcidio_cmd;
1242                s->do_cmdtest = &ni_pcidio_cmdtest;
1243                s->cancel = &ni_pcidio_cancel;
1244                s->len_chanlist = 32;   /* XXX */
1245                s->buf_change = &ni_pcidio_change;
1246                s->async_dma_dir = DMA_BIDIRECTIONAL;
1247
1248                writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
1249                writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
1250                writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));
1251
1252                /* disable interrupts on board */
1253                writeb(0x00,
1254                       devpriv->mite->daq_io_addr +
1255                       Master_DMA_And_Interrupt_Control);
1256
1257                ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
1258                                  "ni_pcidio", dev);
1259                if (ret < 0)
1260                        printk(KERN_WARNING " irq not available");
1261
1262                dev->irq = irq;
1263        }
1264
1265        printk("\n");
1266
1267        return 0;
1268}
1269
1270static int nidio_detach(struct comedi_device *dev)
1271{
1272        int i;
1273
1274        if (this_board && !this_board->is_diodaq) {
1275                for (i = 0; i < this_board->n_8255; i++)
1276                        subdev_8255_cleanup(dev, dev->subdevices + i);
1277        }
1278
1279        if (dev->irq)
1280                free_irq(dev->irq, dev);
1281
1282        if (devpriv) {
1283                if (devpriv->di_mite_ring) {
1284                        mite_free_ring(devpriv->di_mite_ring);
1285                        devpriv->di_mite_ring = NULL;
1286                }
1287                if (devpriv->mite)
1288                        mite_unsetup(devpriv->mite);
1289        }
1290        return 0;
1291}
1292
1293static int nidio_find_device(struct comedi_device *dev, int bus, int slot)
1294{
1295        struct mite_struct *mite;
1296        int i;
1297
1298        for (mite = mite_devices; mite; mite = mite->next) {
1299                if (mite->used)
1300                        continue;
1301                if (bus || slot) {
1302                        if (bus != mite->pcidev->bus->number ||
1303                            slot != PCI_SLOT(mite->pcidev->devfn))
1304                                continue;
1305                }
1306                for (i = 0; i < n_nidio_boards; i++) {
1307                        if (mite_device_id(mite) == nidio_boards[i].dev_id) {
1308                                dev->board_ptr = nidio_boards + i;
1309                                devpriv->mite = mite;
1310
1311                                return 0;
1312                        }
1313                }
1314        }
1315        printk(KERN_WARNING "no device found\n");
1316        mite_list_devices();
1317        return -EIO;
1318}
1319
1320static int __devinit driver_pcidio_pci_probe(struct pci_dev *dev,
1321                                             const struct pci_device_id *ent)
1322{
1323        return comedi_pci_auto_config(dev, driver_pcidio.driver_name);
1324}
1325
1326static void __devexit driver_pcidio_pci_remove(struct pci_dev *dev)
1327{
1328        comedi_pci_auto_unconfig(dev);
1329}
1330
1331static struct pci_driver driver_pcidio_pci_driver = {
1332        .id_table = ni_pcidio_pci_table,
1333        .probe = &driver_pcidio_pci_probe,
1334        .remove = __devexit_p(&driver_pcidio_pci_remove)
1335};
1336
1337static int __init driver_pcidio_init_module(void)
1338{
1339        int retval;
1340
1341        retval = comedi_driver_register(&driver_pcidio);
1342        if (retval < 0)
1343                return retval;
1344
1345        driver_pcidio_pci_driver.name = (char *)driver_pcidio.driver_name;
1346        return pci_register_driver(&driver_pcidio_pci_driver);
1347}
1348
1349static void __exit driver_pcidio_cleanup_module(void)
1350{
1351        pci_unregister_driver(&driver_pcidio_pci_driver);
1352        comedi_driver_unregister(&driver_pcidio);
1353}
1354
1355module_init(driver_pcidio_init_module);
1356module_exit(driver_pcidio_cleanup_module);
1357
1358MODULE_AUTHOR("Comedi http://www.comedi.org");
1359MODULE_DESCRIPTION("Comedi low-level driver");
1360MODULE_LICENSE("GPL");
1361