root/drivers/staging/comedi/drivers/ni_pcidio.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. primary_DMAChannel_bits
  2. secondary_DMAChannel_bits
  3. ni_pcidio_request_di_mite_channel
  4. ni_pcidio_release_di_mite_channel
  5. setup_mite_dma
  6. ni_pcidio_poll
  7. nidio_interrupt
  8. ni_pcidio_insn_config
  9. ni_pcidio_insn_bits
  10. ni_pcidio_ns_to_timer
  11. ni_pcidio_cmdtest
  12. ni_pcidio_inttrig
  13. ni_pcidio_cmd
  14. ni_pcidio_cancel
  15. ni_pcidio_change
  16. pci_6534_load_fpga
  17. pci_6534_reset_fpga
  18. pci_6534_reset_fpgas
  19. pci_6534_init_main_fpga
  20. pci_6534_upload_firmware
  21. nidio_reset_board
  22. nidio_auto_attach
  23. nidio_detach
  24. ni_pcidio_pci_probe

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

/* [<][>][^][v][top][bottom][index][help] */