linux/drivers/staging/comedi/drivers/ni_pcidio.c
<<
>>
Prefs
   1/*
   2    comedi/drivers/ni_pcidio.c
   3    driver for National Instruments PCI-DIO-32HS
   4
   5    COMEDI - Linux Control and Measurement Device Interface
   6    Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
   7
   8    This program is free software; you can redistribute it and/or modify
   9    it under the terms of the GNU General Public License as published by
  10    the Free Software Foundation; either version 2 of the License, or
  11    (at your option) any later version.
  12
  13    This program is distributed in the hope that it will be useful,
  14    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16    GNU General Public License for more details.
  17*/
  18/*
  19Driver: ni_pcidio
  20Description: National Instruments PCI-DIO32HS, PCI-6533
  21Author: ds
  22Status: works
  23Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio)
  24         [National Instruments] PXI-6533, PCI-6533 (pxi-6533)
  25         [National Instruments] PCI-6534 (pci-6534)
  26Updated: Mon, 09 Jan 2012 14:27:23 +0000
  27
  28The DIO32HS board appears as one subdevice, with 32 channels.
  29Each channel is individually I/O configurable.  The channel order
  30is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0.  The driver only
  31supports simple digital I/O; no handshaking is supported.
  32
  33DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
  34
  35The PCI-DIO-32HS/PCI-6533 has a configurable external trigger. Setting
  36scan_begin_arg to 0 or CR_EDGE triggers on the leading edge. Setting
  37scan_begin_arg to CR_INVERT or (CR_EDGE | CR_INVERT) triggers on the
  38trailing edge.
  39
  40This driver could be easily modified to support AT-MIO32HS and
  41AT-MIO96.
  42
  43The PCI-6534 requires a firmware upload after power-up to work, the
  44firmware data and instructions for loading it with comedi_config
  45it are contained in the
  46comedi_nonfree_firmware tarball available from http://www.comedi.org
  47*/
  48
  49#define USE_DMA
  50
  51#include <linux/module.h>
  52#include <linux/delay.h>
  53#include <linux/interrupt.h>
  54#include <linux/sched.h>
  55
  56#include "../comedidev.h"
  57
  58#include "comedi_fc.h"
  59#include "mite.h"
  60
  61/* defines for the PCI-DIO-32HS */
  62
  63#define Window_Address                  4       /* W */
  64#define Interrupt_And_Window_Status     4       /* R */
  65#define IntStatus1                              (1<<0)
  66#define IntStatus2                              (1<<1)
  67#define WindowAddressStatus_mask                0x7c
  68
  69#define Master_DMA_And_Interrupt_Control 5      /* W */
  70#define InterruptLine(x)                        ((x)&3)
  71#define OpenInt                         (1<<2)
  72#define Group_Status                    5       /* R */
  73#define DataLeft                                (1<<0)
  74#define Req                                     (1<<2)
  75#define StopTrig                                (1<<3)
  76
  77#define Group_1_Flags                   6       /* R */
  78#define Group_2_Flags                   7       /* R */
  79#define TransferReady                           (1<<0)
  80#define CountExpired                            (1<<1)
  81#define Waited                          (1<<5)
  82#define PrimaryTC                               (1<<6)
  83#define SecondaryTC                             (1<<7)
  84  /* #define SerialRose */
  85  /* #define ReqRose */
  86  /* #define Paused */
  87
  88#define Group_1_First_Clear             6       /* W */
  89#define Group_2_First_Clear             7       /* W */
  90#define ClearWaited                             (1<<3)
  91#define ClearPrimaryTC                  (1<<4)
  92#define ClearSecondaryTC                        (1<<5)
  93#define DMAReset                                (1<<6)
  94#define FIFOReset                               (1<<7)
  95#define ClearAll                                0xf8
  96
  97#define Group_1_FIFO                    8       /* W */
  98#define Group_2_FIFO                    12      /* W */
  99
 100#define Transfer_Count                  20
 101#define Chip_ID_D                       24
 102#define Chip_ID_I                       25
 103#define Chip_ID_O                       26
 104#define Chip_Version                    27
 105#define Port_IO(x)                      (28+(x))
 106#define Port_Pin_Directions(x)          (32+(x))
 107#define Port_Pin_Mask(x)                (36+(x))
 108#define Port_Pin_Polarities(x)          (40+(x))
 109
 110#define Master_Clock_Routing            45
 111#define RTSIClocking(x)                 (((x)&3)<<4)
 112
 113#define Group_1_Second_Clear            46      /* W */
 114#define Group_2_Second_Clear            47      /* W */
 115#define ClearExpired                            (1<<0)
 116
 117#define Port_Pattern(x)                 (48+(x))
 118
 119#define Data_Path                       64
 120#define FIFOEnableA             (1<<0)
 121#define FIFOEnableB             (1<<1)
 122#define FIFOEnableC             (1<<2)
 123#define FIFOEnableD             (1<<3)
 124#define Funneling(x)            (((x)&3)<<4)
 125#define GroupDirection  (1<<7)
 126
 127#define Protocol_Register_1             65
 128#define OpMode                          Protocol_Register_1
 129#define RunMode(x)              ((x)&7)
 130#define Numbered                (1<<3)
 131
 132#define Protocol_Register_2             66
 133#define ClockReg                        Protocol_Register_2
 134#define ClockLine(x)            (((x)&3)<<5)
 135#define InvertStopTrig  (1<<7)
 136#define DataLatching(x)       (((x)&3)<<5)
 137
 138#define Protocol_Register_3             67
 139#define Sequence                        Protocol_Register_3
 140
 141#define Protocol_Register_14            68      /* 16 bit */
 142#define ClockSpeed                      Protocol_Register_14
 143
 144#define Protocol_Register_4             70
 145#define ReqReg                          Protocol_Register_4
 146#define ReqConditioning(x)      (((x)&7)<<3)
 147
 148#define Protocol_Register_5             71
 149#define BlockMode                       Protocol_Register_5
 150
 151#define FIFO_Control                    72
 152#define ReadyLevel(x)           ((x)&7)
 153
 154#define Protocol_Register_6             73
 155#define LinePolarities                  Protocol_Register_6
 156#define InvertAck               (1<<0)
 157#define InvertReq               (1<<1)
 158#define InvertClock             (1<<2)
 159#define InvertSerial            (1<<3)
 160#define OpenAck         (1<<4)
 161#define OpenClock               (1<<5)
 162
 163#define Protocol_Register_7             74
 164#define AckSer                          Protocol_Register_7
 165#define AckLine(x)              (((x)&3)<<2)
 166#define ExchangePins            (1<<7)
 167
 168#define Interrupt_Control               75
 169  /* bits same as flags */
 170
 171#define DMA_Line_Control_Group1         76
 172#define DMA_Line_Control_Group2         108
 173/* channel zero is none */
 174static inline unsigned primary_DMAChannel_bits(unsigned channel)
 175{
 176        return channel & 0x3;
 177}
 178
 179static inline unsigned secondary_DMAChannel_bits(unsigned channel)
 180{
 181        return (channel << 2) & 0xc;
 182}
 183
 184#define Transfer_Size_Control           77
 185#define TransferWidth(x)        ((x)&3)
 186#define TransferLength(x)       (((x)&3)<<3)
 187#define RequireRLevel           (1<<5)
 188
 189#define Protocol_Register_15            79
 190#define DAQOptions                      Protocol_Register_15
 191#define StartSource(x)                  ((x)&0x3)
 192#define InvertStart                             (1<<2)
 193#define StopSource(x)                           (((x)&0x3)<<3)
 194#define ReqStart                                (1<<6)
 195#define PreStart                                (1<<7)
 196
 197#define Pattern_Detection               81
 198#define DetectionMethod                 (1<<0)
 199#define InvertMatch                             (1<<1)
 200#define IE_Pattern_Detection                    (1<<2)
 201
 202#define Protocol_Register_9             82
 203#define ReqDelay                        Protocol_Register_9
 204
 205#define Protocol_Register_10            83
 206#define ReqNotDelay                     Protocol_Register_10
 207
 208#define Protocol_Register_11            84
 209#define AckDelay                        Protocol_Register_11
 210
 211#define Protocol_Register_12            85
 212#define AckNotDelay                     Protocol_Register_12
 213
 214#define Protocol_Register_13            86
 215#define Data1Delay                      Protocol_Register_13
 216
 217#define Protocol_Register_8             88      /* 32 bit */
 218#define StartDelay                      Protocol_Register_8
 219
 220/* Firmware files for PCI-6524 */
 221#define FW_PCI_6534_MAIN                "ni6534a.bin"
 222#define FW_PCI_6534_SCARAB_DI           "niscrb01.bin"
 223#define FW_PCI_6534_SCARAB_DO           "niscrb02.bin"
 224MODULE_FIRMWARE(FW_PCI_6534_MAIN);
 225MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DI);
 226MODULE_FIRMWARE(FW_PCI_6534_SCARAB_DO);
 227
 228enum pci_6534_firmware_registers {      /* 16 bit */
 229        Firmware_Control_Register = 0x100,
 230        Firmware_Status_Register = 0x104,
 231        Firmware_Data_Register = 0x108,
 232        Firmware_Mask_Register = 0x10c,
 233        Firmware_Debug_Register = 0x110,
 234};
 235/* main fpga registers (32 bit)*/
 236enum pci_6534_fpga_registers {
 237        FPGA_Control1_Register = 0x200,
 238        FPGA_Control2_Register = 0x204,
 239        FPGA_Irq_Mask_Register = 0x208,
 240        FPGA_Status_Register = 0x20c,
 241        FPGA_Signature_Register = 0x210,
 242        FPGA_SCALS_Counter_Register = 0x280,    /*write-clear */
 243        FPGA_SCAMS_Counter_Register = 0x284,    /*write-clear */
 244        FPGA_SCBLS_Counter_Register = 0x288,    /*write-clear */
 245        FPGA_SCBMS_Counter_Register = 0x28c,    /*write-clear */
 246        FPGA_Temp_Control_Register = 0x2a0,
 247        FPGA_DAR_Register = 0x2a8,
 248        FPGA_ELC_Read_Register = 0x2b8,
 249        FPGA_ELC_Write_Register = 0x2bc,
 250};
 251enum FPGA_Control_Bits {
 252        FPGA_Enable_Bit = 0x8000,
 253};
 254
 255#define TIMER_BASE 50           /* nanoseconds */
 256
 257#ifdef USE_DMA
 258#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
 259#else
 260#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
 261#endif
 262
 263enum nidio_boardid {
 264        BOARD_PCIDIO_32HS,
 265        BOARD_PXI6533,
 266        BOARD_PCI6534,
 267};
 268
 269struct nidio_board {
 270        const char *name;
 271        unsigned int uses_firmware:1;
 272};
 273
 274static const struct nidio_board nidio_boards[] = {
 275        [BOARD_PCIDIO_32HS] = {
 276                .name           = "pci-dio-32hs",
 277        },
 278        [BOARD_PXI6533] = {
 279                .name           = "pxi-6533",
 280        },
 281        [BOARD_PCI6534] = {
 282                .name           = "pci-6534",
 283                .uses_firmware  = 1,
 284        },
 285};
 286
 287struct nidio96_private {
 288        struct mite_struct *mite;
 289        int boardtype;
 290        int dio;
 291        unsigned short OpModeBits;
 292        struct mite_channel *di_mite_chan;
 293        struct mite_dma_descriptor_ring *di_mite_ring;
 294        spinlock_t mite_channel_lock;
 295};
 296
 297static int ni_pcidio_request_di_mite_channel(struct comedi_device *dev)
 298{
 299        struct nidio96_private *devpriv = dev->private;
 300        unsigned long flags;
 301
 302        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
 303        BUG_ON(devpriv->di_mite_chan);
 304        devpriv->di_mite_chan =
 305            mite_request_channel_in_range(devpriv->mite,
 306                                          devpriv->di_mite_ring, 1, 2);
 307        if (devpriv->di_mite_chan == NULL) {
 308                spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 309                dev_err(dev->class_dev, "failed to reserve mite dma channel\n");
 310                return -EBUSY;
 311        }
 312        devpriv->di_mite_chan->dir = COMEDI_INPUT;
 313        writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
 314               secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
 315               dev->mmio + DMA_Line_Control_Group1);
 316        mmiowb();
 317        spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 318        return 0;
 319}
 320
 321static void ni_pcidio_release_di_mite_channel(struct comedi_device *dev)
 322{
 323        struct nidio96_private *devpriv = dev->private;
 324        unsigned long flags;
 325
 326        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
 327        if (devpriv->di_mite_chan) {
 328                mite_dma_disarm(devpriv->di_mite_chan);
 329                mite_dma_reset(devpriv->di_mite_chan);
 330                mite_release_channel(devpriv->di_mite_chan);
 331                devpriv->di_mite_chan = NULL;
 332                writeb(primary_DMAChannel_bits(0) |
 333                       secondary_DMAChannel_bits(0),
 334                       dev->mmio + DMA_Line_Control_Group1);
 335                mmiowb();
 336        }
 337        spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 338}
 339
 340static int setup_mite_dma(struct comedi_device *dev, struct comedi_subdevice *s)
 341{
 342        struct nidio96_private *devpriv = dev->private;
 343        int retval;
 344        unsigned long flags;
 345
 346        retval = ni_pcidio_request_di_mite_channel(dev);
 347        if (retval)
 348                return retval;
 349
 350        /* write alloc the entire buffer */
 351        comedi_buf_write_alloc(s, s->async->prealloc_bufsz);
 352
 353        spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
 354        if (devpriv->di_mite_chan) {
 355                mite_prep_dma(devpriv->di_mite_chan, 32, 32);
 356                mite_dma_arm(devpriv->di_mite_chan);
 357        } else
 358                retval = -EIO;
 359        spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
 360
 361        return retval;
 362}
 363
 364static int ni_pcidio_poll(struct comedi_device *dev, struct comedi_subdevice *s)
 365{
 366        struct nidio96_private *devpriv = dev->private;
 367        unsigned long irq_flags;
 368        int count;
 369
 370        spin_lock_irqsave(&dev->spinlock, irq_flags);
 371        spin_lock(&devpriv->mite_channel_lock);
 372        if (devpriv->di_mite_chan)
 373                mite_sync_input_dma(devpriv->di_mite_chan, s);
 374        spin_unlock(&devpriv->mite_channel_lock);
 375        count = comedi_buf_n_bytes_ready(s);
 376        spin_unlock_irqrestore(&dev->spinlock, irq_flags);
 377        return count;
 378}
 379
 380static irqreturn_t nidio_interrupt(int irq, void *d)
 381{
 382        struct comedi_device *dev = d;
 383        struct nidio96_private *devpriv = dev->private;
 384        struct comedi_subdevice *s = dev->read_subdev;
 385        struct comedi_async *async = s->async;
 386        struct mite_struct *mite = devpriv->mite;
 387
 388        /* int i, j; */
 389        unsigned int auxdata = 0;
 390        unsigned short data1 = 0;
 391        unsigned short data2 = 0;
 392        int flags;
 393        int status;
 394        int work = 0;
 395        unsigned int m_status = 0;
 396
 397        /* interrupcions parasites */
 398        if (!dev->attached) {
 399                /* assume it's from another card */
 400                return IRQ_NONE;
 401        }
 402
 403        /* Lock to avoid race with comedi_poll */
 404        spin_lock(&dev->spinlock);
 405
 406        status = readb(dev->mmio + Interrupt_And_Window_Status);
 407        flags = readb(dev->mmio + Group_1_Flags);
 408
 409        spin_lock(&devpriv->mite_channel_lock);
 410        if (devpriv->di_mite_chan)
 411                m_status = mite_get_status(devpriv->di_mite_chan);
 412
 413        if (m_status & CHSR_INT) {
 414                if (m_status & CHSR_LINKC) {
 415                        writel(CHOR_CLRLC,
 416                               mite->mite_io_addr +
 417                               MITE_CHOR(devpriv->di_mite_chan->channel));
 418                        mite_sync_input_dma(devpriv->di_mite_chan, s);
 419                        /* XXX need to byteswap */
 420                }
 421                if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
 422                                 CHSR_DRQ1 | CHSR_MRDY)) {
 423                        dev_dbg(dev->class_dev,
 424                                "unknown mite interrupt, disabling IRQ\n");
 425                        async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 426                        disable_irq(dev->irq);
 427                }
 428        }
 429        spin_unlock(&devpriv->mite_channel_lock);
 430
 431        while (status & DataLeft) {
 432                work++;
 433                if (work > 20) {
 434                        dev_dbg(dev->class_dev, "too much work in interrupt\n");
 435                        writeb(0x00,
 436                               dev->mmio + Master_DMA_And_Interrupt_Control);
 437                        break;
 438                }
 439
 440                flags &= IntEn;
 441
 442                if (flags & TransferReady) {
 443                        while (flags & TransferReady) {
 444                                work++;
 445                                if (work > 100) {
 446                                        dev_dbg(dev->class_dev,
 447                                                "too much work in interrupt\n");
 448                                        writeb(0x00, dev->mmio +
 449                                               Master_DMA_And_Interrupt_Control
 450                                              );
 451                                        goto out;
 452                                }
 453                                auxdata = readl(dev->mmio + Group_1_FIFO);
 454                                data1 = auxdata & 0xffff;
 455                                data2 = (auxdata & 0xffff0000) >> 16;
 456                                comedi_buf_put(s, data1);
 457                                comedi_buf_put(s, data2);
 458                                flags = readb(dev->mmio + Group_1_Flags);
 459                        }
 460                        async->events |= COMEDI_CB_BLOCK;
 461                }
 462
 463                if (flags & CountExpired) {
 464                        writeb(ClearExpired, dev->mmio + Group_1_Second_Clear);
 465                        async->events |= COMEDI_CB_EOA;
 466
 467                        writeb(0x00, dev->mmio + OpMode);
 468                        break;
 469                } else if (flags & Waited) {
 470                        writeb(ClearWaited, dev->mmio + Group_1_First_Clear);
 471                        async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 472                        break;
 473                } else if (flags & PrimaryTC) {
 474                        writeb(ClearPrimaryTC,
 475                               dev->mmio + Group_1_First_Clear);
 476                        async->events |= COMEDI_CB_EOA;
 477                } else if (flags & SecondaryTC) {
 478                        writeb(ClearSecondaryTC,
 479                               dev->mmio + Group_1_First_Clear);
 480                        async->events |= COMEDI_CB_EOA;
 481                }
 482
 483                flags = readb(dev->mmio + Group_1_Flags);
 484                status = readb(dev->mmio + Interrupt_And_Window_Status);
 485        }
 486
 487out:
 488        cfc_handle_events(dev, s);
 489#if 0
 490        if (!tag)
 491                writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control);
 492#endif
 493
 494        spin_unlock(&dev->spinlock);
 495        return IRQ_HANDLED;
 496}
 497
 498static int ni_pcidio_insn_config(struct comedi_device *dev,
 499                                 struct comedi_subdevice *s,
 500                                 struct comedi_insn *insn,
 501                                 unsigned int *data)
 502{
 503        int ret;
 504
 505        ret = comedi_dio_insn_config(dev, s, insn, data, 0);
 506        if (ret)
 507                return ret;
 508
 509        writel(s->io_bits, dev->mmio + Port_Pin_Directions(0));
 510
 511        return insn->n;
 512}
 513
 514static int ni_pcidio_insn_bits(struct comedi_device *dev,
 515                               struct comedi_subdevice *s,
 516                               struct comedi_insn *insn,
 517                               unsigned int *data)
 518{
 519        if (comedi_dio_update_state(s, data))
 520                writel(s->state, dev->mmio + Port_IO(0));
 521
 522        data[1] = readl(dev->mmio + Port_IO(0));
 523
 524        return insn->n;
 525}
 526
 527static int ni_pcidio_ns_to_timer(int *nanosec, unsigned int flags)
 528{
 529        int divider, base;
 530
 531        base = TIMER_BASE;
 532
 533        switch (flags & CMDF_ROUND_MASK) {
 534        case CMDF_ROUND_NEAREST:
 535        default:
 536                divider = (*nanosec + base / 2) / base;
 537                break;
 538        case CMDF_ROUND_DOWN:
 539                divider = (*nanosec) / base;
 540                break;
 541        case CMDF_ROUND_UP:
 542                divider = (*nanosec + base - 1) / base;
 543                break;
 544        }
 545
 546        *nanosec = base * divider;
 547        return divider;
 548}
 549
 550static int ni_pcidio_cmdtest(struct comedi_device *dev,
 551                             struct comedi_subdevice *s, struct comedi_cmd *cmd)
 552{
 553        int err = 0;
 554        unsigned int arg;
 555
 556        /* Step 1 : check if triggers are trivially valid */
 557
 558        err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW | TRIG_INT);
 559        err |= cfc_check_trigger_src(&cmd->scan_begin_src,
 560                                        TRIG_TIMER | TRIG_EXT);
 561        err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
 562        err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 563        err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 564
 565        if (err)
 566                return 1;
 567
 568        /* Step 2a : make sure trigger sources are unique */
 569
 570        err |= cfc_check_trigger_is_unique(cmd->start_src);
 571        err |= cfc_check_trigger_is_unique(cmd->scan_begin_src);
 572        err |= cfc_check_trigger_is_unique(cmd->stop_src);
 573
 574        /* Step 2b : and mutually compatible */
 575
 576        if (err)
 577                return 2;
 578
 579        /* Step 3: check if arguments are trivially valid */
 580
 581        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
 582
 583#define MAX_SPEED       (TIMER_BASE)    /* in nanoseconds */
 584
 585        if (cmd->scan_begin_src == TRIG_TIMER) {
 586                err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg,
 587                                                 MAX_SPEED);
 588                /* no minimum speed */
 589        } else {
 590                /* TRIG_EXT */
 591                /* should be level/edge, hi/lo specification here */
 592                if ((cmd->scan_begin_arg & ~(CR_EDGE | CR_INVERT)) != 0) {
 593                        cmd->scan_begin_arg &= (CR_EDGE | CR_INVERT);
 594                        err |= -EINVAL;
 595                }
 596        }
 597
 598        err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
 599        err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
 600
 601        if (cmd->stop_src == TRIG_COUNT)
 602                err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
 603        else    /* TRIG_NONE */
 604                err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 605
 606        if (err)
 607                return 3;
 608
 609        /* step 4: fix up any arguments */
 610
 611        if (cmd->scan_begin_src == TRIG_TIMER) {
 612                arg = cmd->scan_begin_arg;
 613                ni_pcidio_ns_to_timer(&arg, cmd->flags);
 614                err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, arg);
 615        }
 616
 617        if (err)
 618                return 4;
 619
 620        return 0;
 621}
 622
 623static int ni_pcidio_inttrig(struct comedi_device *dev,
 624                             struct comedi_subdevice *s,
 625                             unsigned int trig_num)
 626{
 627        struct nidio96_private *devpriv = dev->private;
 628        struct comedi_cmd *cmd = &s->async->cmd;
 629
 630        if (trig_num != cmd->start_arg)
 631                return -EINVAL;
 632
 633        writeb(devpriv->OpModeBits, dev->mmio + OpMode);
 634        s->async->inttrig = NULL;
 635
 636        return 1;
 637}
 638
 639static int ni_pcidio_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 640{
 641        struct nidio96_private *devpriv = dev->private;
 642        struct comedi_cmd *cmd = &s->async->cmd;
 643
 644        /* XXX configure ports for input */
 645        writel(0x0000, dev->mmio + Port_Pin_Directions(0));
 646
 647        if (1) {
 648                /* enable fifos A B C D */
 649                writeb(0x0f, dev->mmio + Data_Path);
 650
 651                /* set transfer width a 32 bits */
 652                writeb(TransferWidth(0) | TransferLength(0),
 653                       dev->mmio + Transfer_Size_Control);
 654        } else {
 655                writeb(0x03, dev->mmio + Data_Path);
 656                writeb(TransferWidth(3) | TransferLength(0),
 657                       dev->mmio + Transfer_Size_Control);
 658        }
 659
 660        /* protocol configuration */
 661        if (cmd->scan_begin_src == TRIG_TIMER) {
 662                /* page 4-5, "input with internal REQs" */
 663                writeb(0, dev->mmio + OpMode);
 664                writeb(0x00, dev->mmio + ClockReg);
 665                writeb(1, dev->mmio + Sequence);
 666                writeb(0x04, dev->mmio + ReqReg);
 667                writeb(4, dev->mmio + BlockMode);
 668                writeb(3, dev->mmio + LinePolarities);
 669                writeb(0xc0, dev->mmio + AckSer);
 670                writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
 671                                             CMDF_ROUND_NEAREST),
 672                       dev->mmio + StartDelay);
 673                writeb(1, dev->mmio + ReqDelay);
 674                writeb(1, dev->mmio + ReqNotDelay);
 675                writeb(1, dev->mmio + AckDelay);
 676                writeb(0x0b, dev->mmio + AckNotDelay);
 677                writeb(0x01, dev->mmio + Data1Delay);
 678                /* manual, page 4-5: ClockSpeed comment is incorrectly listed
 679                 * on DAQOptions */
 680                writew(0, dev->mmio + ClockSpeed);
 681                writeb(0, dev->mmio + DAQOptions);
 682        } else {
 683                /* TRIG_EXT */
 684                /* page 4-5, "input with external REQs" */
 685                writeb(0, dev->mmio + OpMode);
 686                writeb(0x00, dev->mmio + ClockReg);
 687                writeb(0, dev->mmio + Sequence);
 688                writeb(0x00, dev->mmio + ReqReg);
 689                writeb(4, dev->mmio + BlockMode);
 690                if (!(cmd->scan_begin_arg & CR_INVERT)) /* Leading Edge */
 691                        writeb(0, dev->mmio + LinePolarities);
 692                else                                    /* Trailing Edge */
 693                        writeb(2, dev->mmio + LinePolarities);
 694                writeb(0x00, dev->mmio + AckSer);
 695                writel(1, dev->mmio + StartDelay);
 696                writeb(1, dev->mmio + ReqDelay);
 697                writeb(1, dev->mmio + ReqNotDelay);
 698                writeb(1, dev->mmio + AckDelay);
 699                writeb(0x0C, dev->mmio + AckNotDelay);
 700                writeb(0x10, dev->mmio + Data1Delay);
 701                writew(0, dev->mmio + ClockSpeed);
 702                writeb(0x60, dev->mmio + DAQOptions);
 703        }
 704
 705        if (cmd->stop_src == TRIG_COUNT) {
 706                writel(cmd->stop_arg,
 707                       dev->mmio + Transfer_Count);
 708        } else {
 709                /* XXX */
 710        }
 711
 712#ifdef USE_DMA
 713        writeb(ClearPrimaryTC | ClearSecondaryTC,
 714               dev->mmio + Group_1_First_Clear);
 715
 716        {
 717                int retval = setup_mite_dma(dev, s);
 718
 719                if (retval)
 720                        return retval;
 721        }
 722#else
 723        writeb(0x00, dev->mmio + DMA_Line_Control_Group1);
 724#endif
 725        writeb(0x00, dev->mmio + DMA_Line_Control_Group2);
 726
 727        /* clear and enable interrupts */
 728        writeb(0xff, dev->mmio + Group_1_First_Clear);
 729        /* writeb(ClearExpired, dev->mmio+Group_1_Second_Clear); */
 730
 731        writeb(IntEn, dev->mmio + Interrupt_Control);
 732        writeb(0x03, dev->mmio + Master_DMA_And_Interrupt_Control);
 733
 734        if (cmd->stop_src == TRIG_NONE) {
 735                devpriv->OpModeBits = DataLatching(0) | RunMode(7);
 736        } else {                /* TRIG_TIMER */
 737                devpriv->OpModeBits = Numbered | RunMode(7);
 738        }
 739        if (cmd->start_src == TRIG_NOW) {
 740                /* start */
 741                writeb(devpriv->OpModeBits, dev->mmio + OpMode);
 742                s->async->inttrig = NULL;
 743        } else {
 744                /* TRIG_INT */
 745                s->async->inttrig = ni_pcidio_inttrig;
 746        }
 747
 748        return 0;
 749}
 750
 751static int ni_pcidio_cancel(struct comedi_device *dev,
 752                            struct comedi_subdevice *s)
 753{
 754        writeb(0x00, dev->mmio + Master_DMA_And_Interrupt_Control);
 755        ni_pcidio_release_di_mite_channel(dev);
 756
 757        return 0;
 758}
 759
 760static int ni_pcidio_change(struct comedi_device *dev,
 761                            struct comedi_subdevice *s)
 762{
 763        struct nidio96_private *devpriv = dev->private;
 764        int ret;
 765
 766        ret = mite_buf_change(devpriv->di_mite_ring, s);
 767        if (ret < 0)
 768                return ret;
 769
 770        memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
 771
 772        return 0;
 773}
 774
 775static int pci_6534_load_fpga(struct comedi_device *dev,
 776                              const u8 *data, size_t data_len,
 777                              unsigned long context)
 778{
 779        static const int timeout = 1000;
 780        int fpga_index = context;
 781        int i;
 782        size_t j;
 783
 784        writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
 785        writew(0xc0 | fpga_index, dev->mmio + Firmware_Control_Register);
 786        for (i = 0;
 787             (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0 &&
 788             i < timeout; ++i) {
 789                udelay(1);
 790        }
 791        if (i == timeout) {
 792                dev_warn(dev->class_dev,
 793                         "ni_pcidio: failed to load fpga %i, waiting for status 0x2\n",
 794                         fpga_index);
 795                return -EIO;
 796        }
 797        writew(0x80 | fpga_index, dev->mmio + Firmware_Control_Register);
 798        for (i = 0;
 799             readw(dev->mmio + Firmware_Status_Register) != 0x3 &&
 800             i < timeout; ++i) {
 801                udelay(1);
 802        }
 803        if (i == timeout) {
 804                dev_warn(dev->class_dev,
 805                         "ni_pcidio: failed to load fpga %i, waiting for status 0x3\n",
 806                         fpga_index);
 807                return -EIO;
 808        }
 809        for (j = 0; j + 1 < data_len;) {
 810                unsigned int value = data[j++];
 811
 812                value |= data[j++] << 8;
 813                writew(value, dev->mmio + Firmware_Data_Register);
 814                for (i = 0;
 815                     (readw(dev->mmio + Firmware_Status_Register) & 0x2) == 0
 816                     && i < timeout; ++i) {
 817                        udelay(1);
 818                }
 819                if (i == timeout) {
 820                        dev_warn(dev->class_dev,
 821                                 "ni_pcidio: failed to load word into fpga %i\n",
 822                                 fpga_index);
 823                        return -EIO;
 824                }
 825                if (need_resched())
 826                        schedule();
 827        }
 828        writew(0x0, dev->mmio + Firmware_Control_Register);
 829        return 0;
 830}
 831
 832static int pci_6534_reset_fpga(struct comedi_device *dev, int fpga_index)
 833{
 834        return pci_6534_load_fpga(dev, NULL, 0, fpga_index);
 835}
 836
 837static int pci_6534_reset_fpgas(struct comedi_device *dev)
 838{
 839        int ret;
 840        int i;
 841
 842        writew(0x0, dev->mmio + Firmware_Control_Register);
 843        for (i = 0; i < 3; ++i) {
 844                ret = pci_6534_reset_fpga(dev, i);
 845                if (ret < 0)
 846                        break;
 847        }
 848        writew(0x0, dev->mmio + Firmware_Mask_Register);
 849        return ret;
 850}
 851
 852static void pci_6534_init_main_fpga(struct comedi_device *dev)
 853{
 854        writel(0, dev->mmio + FPGA_Control1_Register);
 855        writel(0, dev->mmio + FPGA_Control2_Register);
 856        writel(0, dev->mmio + FPGA_SCALS_Counter_Register);
 857        writel(0, dev->mmio + FPGA_SCAMS_Counter_Register);
 858        writel(0, dev->mmio + FPGA_SCBLS_Counter_Register);
 859        writel(0, dev->mmio + FPGA_SCBMS_Counter_Register);
 860}
 861
 862static int pci_6534_upload_firmware(struct comedi_device *dev)
 863{
 864        struct nidio96_private *devpriv = dev->private;
 865        static const char *const fw_file[3] = {
 866                FW_PCI_6534_SCARAB_DI,  /* loaded into scarab A for DI */
 867                FW_PCI_6534_SCARAB_DO,  /* loaded into scarab B for DO */
 868                FW_PCI_6534_MAIN,       /* loaded into main FPGA */
 869        };
 870        int ret;
 871        int n;
 872
 873        ret = pci_6534_reset_fpgas(dev);
 874        if (ret < 0)
 875                return ret;
 876        /* load main FPGA first, then the two scarabs */
 877        for (n = 2; n >= 0; n--) {
 878                ret = comedi_load_firmware(dev, &devpriv->mite->pcidev->dev,
 879                                           fw_file[n],
 880                                           pci_6534_load_fpga, n);
 881                if (ret == 0 && n == 2)
 882                        pci_6534_init_main_fpga(dev);
 883                if (ret < 0)
 884                        break;
 885        }
 886        return ret;
 887}
 888
 889static void nidio_reset_board(struct comedi_device *dev)
 890{
 891        writel(0, dev->mmio + Port_IO(0));
 892        writel(0, dev->mmio + Port_Pin_Directions(0));
 893        writel(0, dev->mmio + Port_Pin_Mask(0));
 894
 895        /* disable interrupts on board */
 896        writeb(0, dev->mmio + Master_DMA_And_Interrupt_Control);
 897}
 898
 899static int nidio_auto_attach(struct comedi_device *dev,
 900                             unsigned long context)
 901{
 902        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 903        const struct nidio_board *board = NULL;
 904        struct nidio96_private *devpriv;
 905        struct comedi_subdevice *s;
 906        int ret;
 907        unsigned int irq;
 908
 909        if (context < ARRAY_SIZE(nidio_boards))
 910                board = &nidio_boards[context];
 911        if (!board)
 912                return -ENODEV;
 913        dev->board_ptr = board;
 914        dev->board_name = board->name;
 915
 916        ret = comedi_pci_enable(dev);
 917        if (ret)
 918                return ret;
 919
 920        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 921        if (!devpriv)
 922                return -ENOMEM;
 923
 924        spin_lock_init(&devpriv->mite_channel_lock);
 925
 926        devpriv->mite = mite_alloc(pcidev);
 927        if (!devpriv->mite)
 928                return -ENOMEM;
 929
 930        ret = mite_setup(dev, devpriv->mite);
 931        if (ret < 0)
 932                return ret;
 933
 934        devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
 935        if (devpriv->di_mite_ring == NULL)
 936                return -ENOMEM;
 937
 938        if (board->uses_firmware) {
 939                ret = pci_6534_upload_firmware(dev);
 940                if (ret < 0)
 941                        return ret;
 942        }
 943
 944        nidio_reset_board(dev);
 945
 946        ret = comedi_alloc_subdevices(dev, 1);
 947        if (ret)
 948                return ret;
 949
 950        dev_info(dev->class_dev, "%s rev=%d\n", dev->board_name,
 951                 readb(dev->mmio + Chip_Version));
 952
 953        s = &dev->subdevices[0];
 954
 955        dev->read_subdev = s;
 956        s->type = COMEDI_SUBD_DIO;
 957        s->subdev_flags =
 958                SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
 959                SDF_CMD_READ;
 960        s->n_chan = 32;
 961        s->range_table = &range_digital;
 962        s->maxdata = 1;
 963        s->insn_config = &ni_pcidio_insn_config;
 964        s->insn_bits = &ni_pcidio_insn_bits;
 965        s->do_cmd = &ni_pcidio_cmd;
 966        s->do_cmdtest = &ni_pcidio_cmdtest;
 967        s->cancel = &ni_pcidio_cancel;
 968        s->len_chanlist = 32;   /* XXX */
 969        s->buf_change = &ni_pcidio_change;
 970        s->async_dma_dir = DMA_BIDIRECTIONAL;
 971        s->poll = &ni_pcidio_poll;
 972
 973        irq = pcidev->irq;
 974        if (irq) {
 975                ret = request_irq(irq, nidio_interrupt, IRQF_SHARED,
 976                                  dev->board_name, dev);
 977                if (ret == 0)
 978                        dev->irq = irq;
 979        }
 980
 981        return 0;
 982}
 983
 984static void nidio_detach(struct comedi_device *dev)
 985{
 986        struct nidio96_private *devpriv = dev->private;
 987
 988        if (dev->irq)
 989                free_irq(dev->irq, dev);
 990        if (devpriv) {
 991                if (devpriv->di_mite_ring) {
 992                        mite_free_ring(devpriv->di_mite_ring);
 993                        devpriv->di_mite_ring = NULL;
 994                }
 995                mite_detach(devpriv->mite);
 996        }
 997        if (dev->mmio)
 998                iounmap(dev->mmio);
 999        comedi_pci_disable(dev);
1000}
1001
1002static struct comedi_driver ni_pcidio_driver = {
1003        .driver_name    = "ni_pcidio",
1004        .module         = THIS_MODULE,
1005        .auto_attach    = nidio_auto_attach,
1006        .detach         = nidio_detach,
1007};
1008
1009static int ni_pcidio_pci_probe(struct pci_dev *dev,
1010                               const struct pci_device_id *id)
1011{
1012        return comedi_pci_auto_config(dev, &ni_pcidio_driver, id->driver_data);
1013}
1014
1015static const struct pci_device_id ni_pcidio_pci_table[] = {
1016        { PCI_VDEVICE(NI, 0x1150), BOARD_PCIDIO_32HS },
1017        { PCI_VDEVICE(NI, 0x12b0), BOARD_PCI6534 },
1018        { PCI_VDEVICE(NI, 0x1320), BOARD_PXI6533 },
1019        { 0 }
1020};
1021MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
1022
1023static struct pci_driver ni_pcidio_pci_driver = {
1024        .name           = "ni_pcidio",
1025        .id_table       = ni_pcidio_pci_table,
1026        .probe          = ni_pcidio_pci_probe,
1027        .remove         = comedi_pci_auto_unconfig,
1028};
1029module_comedi_pci_driver(ni_pcidio_driver, ni_pcidio_pci_driver);
1030
1031MODULE_AUTHOR("Comedi http://www.comedi.org");
1032MODULE_DESCRIPTION("Comedi low-level driver");
1033MODULE_LICENSE("GPL");
1034