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