linux/drivers/staging/comedi/drivers/gsc_hpdi.c
<<
>>
Prefs
   1/*
   2 * gsc_hpdi.c
   3 * Comedi driver the General Standards Corporation
   4 * High Speed Parallel Digital Interface rs485 boards.
   5 *
   6 * Author:  Frank Mori Hess <fmhess@users.sourceforge.net>
   7 * Copyright (C) 2003 Coherent Imaging Systems
   8 *
   9 * COMEDI - Linux Control and Measurement Device Interface
  10 * Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of the GNU General Public License as published by
  14 * the Free Software Foundation; either version 2 of the License, or
  15 * (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 */
  22
  23/*
  24 * Driver: gsc_hpdi
  25 * Description: General Standards Corporation High
  26 *    Speed Parallel Digital Interface rs485 boards
  27 * Author: Frank Mori Hess <fmhess@users.sourceforge.net>
  28 * Status: only receive mode works, transmit not supported
  29 * Updated: Thu, 01 Nov 2012 16:17:38 +0000
  30 * Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
  31 *   PMC-HPDI32
  32 *
  33 * Configuration options:
  34 *    None.
  35 *
  36 * Manual configuration of supported devices is not supported; they are
  37 * configured automatically.
  38 *
  39 * There are some additional hpdi models available from GSC for which
  40 * support could be added to this driver.
  41 */
  42
  43#include <linux/module.h>
  44#include <linux/pci.h>
  45#include <linux/delay.h>
  46#include <linux/interrupt.h>
  47
  48#include "../comedidev.h"
  49
  50#include "plx9080.h"
  51#include "comedi_fc.h"
  52
  53/*
  54 * PCI BAR2 Register map (devpriv->mmio)
  55 */
  56#define FIRMWARE_REV_REG                        0x00
  57#define FEATURES_REG_PRESENT_BIT                (1 << 15)
  58#define BOARD_CONTROL_REG                       0x04
  59#define BOARD_RESET_BIT                         (1 << 0)
  60#define TX_FIFO_RESET_BIT                       (1 << 1)
  61#define RX_FIFO_RESET_BIT                       (1 << 2)
  62#define TX_ENABLE_BIT                           (1 << 4)
  63#define RX_ENABLE_BIT                           (1 << 5)
  64#define DEMAND_DMA_DIRECTION_TX_BIT             (1 << 6)  /* ch 0 only */
  65#define LINE_VALID_ON_STATUS_VALID_BIT          (1 << 7)
  66#define START_TX_BIT                            (1 << 8)
  67#define CABLE_THROTTLE_ENABLE_BIT               (1 << 9)
  68#define TEST_MODE_ENABLE_BIT                    (1 << 31)
  69#define BOARD_STATUS_REG                        0x08
  70#define COMMAND_LINE_STATUS_MASK                (0x7f << 0)
  71#define TX_IN_PROGRESS_BIT                      (1 << 7)
  72#define TX_NOT_EMPTY_BIT                        (1 << 8)
  73#define TX_NOT_ALMOST_EMPTY_BIT                 (1 << 9)
  74#define TX_NOT_ALMOST_FULL_BIT                  (1 << 10)
  75#define TX_NOT_FULL_BIT                         (1 << 11)
  76#define RX_NOT_EMPTY_BIT                        (1 << 12)
  77#define RX_NOT_ALMOST_EMPTY_BIT                 (1 << 13)
  78#define RX_NOT_ALMOST_FULL_BIT                  (1 << 14)
  79#define RX_NOT_FULL_BIT                         (1 << 15)
  80#define BOARD_JUMPER0_INSTALLED_BIT             (1 << 16)
  81#define BOARD_JUMPER1_INSTALLED_BIT             (1 << 17)
  82#define TX_OVERRUN_BIT                          (1 << 21)
  83#define RX_UNDERRUN_BIT                         (1 << 22)
  84#define RX_OVERRUN_BIT                          (1 << 23)
  85#define TX_PROG_ALMOST_REG                      0x0c
  86#define RX_PROG_ALMOST_REG                      0x10
  87#define ALMOST_EMPTY_BITS(x)                    (((x) & 0xffff) << 0)
  88#define ALMOST_FULL_BITS(x)                     (((x) & 0xff) << 16)
  89#define FEATURES_REG                            0x14
  90#define FIFO_SIZE_PRESENT_BIT                   (1 << 0)
  91#define FIFO_WORDS_PRESENT_BIT                  (1 << 1)
  92#define LEVEL_EDGE_INTERRUPTS_PRESENT_BIT       (1 << 2)
  93#define GPIO_SUPPORTED_BIT                      (1 << 3)
  94#define PLX_DMA_CH1_SUPPORTED_BIT               (1 << 4)
  95#define OVERRUN_UNDERRUN_SUPPORTED_BIT          (1 << 5)
  96#define FIFO_REG                                0x18
  97#define TX_STATUS_COUNT_REG                     0x1c
  98#define TX_LINE_VALID_COUNT_REG                 0x20,
  99#define TX_LINE_INVALID_COUNT_REG               0x24
 100#define RX_STATUS_COUNT_REG                     0x28
 101#define RX_LINE_COUNT_REG                       0x2c
 102#define INTERRUPT_CONTROL_REG                   0x30
 103#define FRAME_VALID_START_INTR                  (1 << 0)
 104#define FRAME_VALID_END_INTR                    (1 << 1)
 105#define TX_FIFO_EMPTY_INTR                      (1 << 8)
 106#define TX_FIFO_ALMOST_EMPTY_INTR               (1 << 9)
 107#define TX_FIFO_ALMOST_FULL_INTR                (1 << 10)
 108#define TX_FIFO_FULL_INTR                       (1 << 11)
 109#define RX_EMPTY_INTR                           (1 << 12)
 110#define RX_ALMOST_EMPTY_INTR                    (1 << 13)
 111#define RX_ALMOST_FULL_INTR                     (1 << 14)
 112#define RX_FULL_INTR                            (1 << 15)
 113#define INTERRUPT_STATUS_REG                    0x34
 114#define TX_CLOCK_DIVIDER_REG                    0x38
 115#define TX_FIFO_SIZE_REG                        0x40
 116#define RX_FIFO_SIZE_REG                        0x44
 117#define FIFO_SIZE_MASK                          (0xfffff << 0)
 118#define TX_FIFO_WORDS_REG                       0x48
 119#define RX_FIFO_WORDS_REG                       0x4c
 120#define INTERRUPT_EDGE_LEVEL_REG                0x50
 121#define INTERRUPT_POLARITY_REG                  0x54
 122
 123#define TIMER_BASE                              50      /* 20MHz master clock */
 124#define DMA_BUFFER_SIZE                         0x10000
 125#define NUM_DMA_BUFFERS                         4
 126#define NUM_DMA_DESCRIPTORS                     256
 127
 128struct hpdi_board {
 129        const char *name;
 130        int device_id;
 131        int subdevice_id;
 132};
 133
 134static const struct hpdi_board hpdi_boards[] = {
 135        {
 136                .name           = "pci-hpdi32",
 137                .device_id      = PCI_DEVICE_ID_PLX_9080,
 138                .subdevice_id   = 0x2400,
 139         },
 140#if 0
 141        {
 142                .name           = "pxi-hpdi32",
 143                .device_id      = 0x9656,
 144                .subdevice_id   = 0x2705,
 145         },
 146#endif
 147};
 148
 149struct hpdi_private {
 150        void __iomem *plx9080_mmio;
 151        void __iomem *mmio;
 152        uint32_t *dio_buffer[NUM_DMA_BUFFERS];  /*  dma buffers */
 153        /* physical addresses of dma buffers */
 154        dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];
 155        /* array of dma descriptors read by plx9080, allocated to get proper
 156         * alignment */
 157        struct plx_dma_desc *dma_desc;
 158        /* physical address of dma descriptor array */
 159        dma_addr_t dma_desc_phys_addr;
 160        unsigned int num_dma_descriptors;
 161        /* pointer to start of buffers indexed by descriptor */
 162        uint32_t *desc_dio_buffer[NUM_DMA_DESCRIPTORS];
 163        /* index of the dma descriptor that is currently being used */
 164        unsigned int dma_desc_index;
 165        unsigned int tx_fifo_size;
 166        unsigned int rx_fifo_size;
 167        unsigned long dio_count;
 168        /* number of bytes at which to generate COMEDI_CB_BLOCK events */
 169        unsigned int block_size;
 170};
 171
 172static void gsc_hpdi_drain_dma(struct comedi_device *dev, unsigned int channel)
 173{
 174        struct hpdi_private *devpriv = dev->private;
 175        struct comedi_subdevice *s = dev->read_subdev;
 176        struct comedi_cmd *cmd = &s->async->cmd;
 177        unsigned int idx;
 178        unsigned int start;
 179        unsigned int desc;
 180        unsigned int size;
 181        unsigned int next;
 182
 183        if (channel)
 184                next = readl(devpriv->plx9080_mmio + PLX_DMA1_PCI_ADDRESS_REG);
 185        else
 186                next = readl(devpriv->plx9080_mmio + PLX_DMA0_PCI_ADDRESS_REG);
 187
 188        idx = devpriv->dma_desc_index;
 189        start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr);
 190        /* loop until we have read all the full buffers */
 191        for (desc = 0; (next < start || next >= start + devpriv->block_size) &&
 192             desc < devpriv->num_dma_descriptors; desc++) {
 193                /* transfer data from dma buffer to comedi buffer */
 194                size = devpriv->block_size / sizeof(uint32_t);
 195                if (cmd->stop_src == TRIG_COUNT) {
 196                        if (size > devpriv->dio_count)
 197                                size = devpriv->dio_count;
 198                        devpriv->dio_count -= size;
 199                }
 200                cfc_write_array_to_buffer(s, devpriv->desc_dio_buffer[idx],
 201                                          size * sizeof(uint32_t));
 202                idx++;
 203                idx %= devpriv->num_dma_descriptors;
 204                start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr);
 205
 206                devpriv->dma_desc_index = idx;
 207        }
 208        /*  XXX check for buffer overrun somehow */
 209}
 210
 211static irqreturn_t gsc_hpdi_interrupt(int irq, void *d)
 212{
 213        struct comedi_device *dev = d;
 214        struct hpdi_private *devpriv = dev->private;
 215        struct comedi_subdevice *s = dev->read_subdev;
 216        struct comedi_async *async = s->async;
 217        uint32_t hpdi_intr_status, hpdi_board_status;
 218        uint32_t plx_status;
 219        uint32_t plx_bits;
 220        uint8_t dma0_status, dma1_status;
 221        unsigned long flags;
 222
 223        if (!dev->attached)
 224                return IRQ_NONE;
 225
 226        plx_status = readl(devpriv->plx9080_mmio + PLX_INTRCS_REG);
 227        if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0)
 228                return IRQ_NONE;
 229
 230        hpdi_intr_status = readl(devpriv->mmio + INTERRUPT_STATUS_REG);
 231        hpdi_board_status = readl(devpriv->mmio + BOARD_STATUS_REG);
 232
 233        if (hpdi_intr_status)
 234                writel(hpdi_intr_status, devpriv->mmio + INTERRUPT_STATUS_REG);
 235
 236        /*  spin lock makes sure no one else changes plx dma control reg */
 237        spin_lock_irqsave(&dev->spinlock, flags);
 238        dma0_status = readb(devpriv->plx9080_mmio + PLX_DMA0_CS_REG);
 239        if (plx_status & ICS_DMA0_A) {  /*  dma chan 0 interrupt */
 240                writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
 241                       devpriv->plx9080_mmio + PLX_DMA0_CS_REG);
 242
 243                if (dma0_status & PLX_DMA_EN_BIT)
 244                        gsc_hpdi_drain_dma(dev, 0);
 245        }
 246        spin_unlock_irqrestore(&dev->spinlock, flags);
 247
 248        /*  spin lock makes sure no one else changes plx dma control reg */
 249        spin_lock_irqsave(&dev->spinlock, flags);
 250        dma1_status = readb(devpriv->plx9080_mmio + PLX_DMA1_CS_REG);
 251        if (plx_status & ICS_DMA1_A) {  /*  XXX *//*  dma chan 1 interrupt */
 252                writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
 253                       devpriv->plx9080_mmio + PLX_DMA1_CS_REG);
 254        }
 255        spin_unlock_irqrestore(&dev->spinlock, flags);
 256
 257        /*  clear possible plx9080 interrupt sources */
 258        if (plx_status & ICS_LDIA) {    /*  clear local doorbell interrupt */
 259                plx_bits = readl(devpriv->plx9080_mmio + PLX_DBR_OUT_REG);
 260                writel(plx_bits, devpriv->plx9080_mmio + PLX_DBR_OUT_REG);
 261        }
 262
 263        if (hpdi_board_status & RX_OVERRUN_BIT) {
 264                dev_err(dev->class_dev, "rx fifo overrun\n");
 265                async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 266        }
 267
 268        if (hpdi_board_status & RX_UNDERRUN_BIT) {
 269                dev_err(dev->class_dev, "rx fifo underrun\n");
 270                async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 271        }
 272
 273        if (devpriv->dio_count == 0)
 274                async->events |= COMEDI_CB_EOA;
 275
 276        cfc_handle_events(dev, s);
 277
 278        return IRQ_HANDLED;
 279}
 280
 281static void gsc_hpdi_abort_dma(struct comedi_device *dev, unsigned int channel)
 282{
 283        struct hpdi_private *devpriv = dev->private;
 284        unsigned long flags;
 285
 286        /*  spinlock for plx dma control/status reg */
 287        spin_lock_irqsave(&dev->spinlock, flags);
 288
 289        plx9080_abort_dma(devpriv->plx9080_mmio, channel);
 290
 291        spin_unlock_irqrestore(&dev->spinlock, flags);
 292}
 293
 294static int gsc_hpdi_cancel(struct comedi_device *dev,
 295                           struct comedi_subdevice *s)
 296{
 297        struct hpdi_private *devpriv = dev->private;
 298
 299        writel(0, devpriv->mmio + BOARD_CONTROL_REG);
 300        writel(0, devpriv->mmio + INTERRUPT_CONTROL_REG);
 301
 302        gsc_hpdi_abort_dma(dev, 0);
 303
 304        return 0;
 305}
 306
 307static int gsc_hpdi_cmd(struct comedi_device *dev,
 308                        struct comedi_subdevice *s)
 309{
 310        struct hpdi_private *devpriv = dev->private;
 311        struct comedi_async *async = s->async;
 312        struct comedi_cmd *cmd = &async->cmd;
 313        unsigned long flags;
 314        uint32_t bits;
 315
 316        if (s->io_bits)
 317                return -EINVAL;
 318
 319        writel(RX_FIFO_RESET_BIT, devpriv->mmio + BOARD_CONTROL_REG);
 320
 321        gsc_hpdi_abort_dma(dev, 0);
 322
 323        devpriv->dma_desc_index = 0;
 324
 325        /*
 326         * These register are supposedly unused during chained dma,
 327         * but I have found that left over values from last operation
 328         * occasionally cause problems with transfer of first dma
 329         * block.  Initializing them to zero seems to fix the problem.
 330         */
 331        writel(0, devpriv->plx9080_mmio + PLX_DMA0_TRANSFER_SIZE_REG);
 332        writel(0, devpriv->plx9080_mmio + PLX_DMA0_PCI_ADDRESS_REG);
 333        writel(0, devpriv->plx9080_mmio + PLX_DMA0_LOCAL_ADDRESS_REG);
 334
 335        /* give location of first dma descriptor */
 336        bits = devpriv->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT |
 337               PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI;
 338        writel(bits, devpriv->plx9080_mmio + PLX_DMA0_DESCRIPTOR_REG);
 339
 340        /* enable dma transfer */
 341        spin_lock_irqsave(&dev->spinlock, flags);
 342        writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT,
 343               devpriv->plx9080_mmio + PLX_DMA0_CS_REG);
 344        spin_unlock_irqrestore(&dev->spinlock, flags);
 345
 346        if (cmd->stop_src == TRIG_COUNT)
 347                devpriv->dio_count = cmd->stop_arg;
 348        else
 349                devpriv->dio_count = 1;
 350
 351        /* clear over/under run status flags */
 352        writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
 353               devpriv->mmio + BOARD_STATUS_REG);
 354
 355        /* enable interrupts */
 356        writel(RX_FULL_INTR, devpriv->mmio + INTERRUPT_CONTROL_REG);
 357
 358        writel(RX_ENABLE_BIT, devpriv->mmio + BOARD_CONTROL_REG);
 359
 360        return 0;
 361}
 362
 363static int gsc_hpdi_check_chanlist(struct comedi_device *dev,
 364                                   struct comedi_subdevice *s,
 365                                   struct comedi_cmd *cmd)
 366{
 367        int i;
 368
 369        for (i = 0; i < cmd->chanlist_len; i++) {
 370                unsigned int chan = CR_CHAN(cmd->chanlist[i]);
 371
 372                if (chan != i) {
 373                        dev_dbg(dev->class_dev,
 374                                "chanlist must be ch 0 to 31 in order\n");
 375                        return -EINVAL;
 376                }
 377        }
 378
 379        return 0;
 380}
 381
 382static int gsc_hpdi_cmd_test(struct comedi_device *dev,
 383                             struct comedi_subdevice *s,
 384                             struct comedi_cmd *cmd)
 385{
 386        int err = 0;
 387
 388        if (s->io_bits)
 389                return -EINVAL;
 390
 391        /* Step 1 : check if triggers are trivially valid */
 392
 393        err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
 394        err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
 395        err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
 396        err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 397        err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 398
 399        if (err)
 400                return 1;
 401
 402        /* Step 2a : make sure trigger sources are unique */
 403
 404        err |= cfc_check_trigger_is_unique(cmd->stop_src);
 405
 406        /* Step 2b : and mutually compatible */
 407
 408        if (err)
 409                return 2;
 410
 411        /* Step 3: check if arguments are trivially valid */
 412
 413        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
 414
 415        if (!cmd->chanlist_len || !cmd->chanlist) {
 416                cmd->chanlist_len = 32;
 417                err |= -EINVAL;
 418        }
 419        err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
 420
 421        if (cmd->stop_src == TRIG_COUNT)
 422                err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
 423        else    /* TRIG_NONE */
 424                err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 425
 426        if (err)
 427                return 3;
 428
 429        /* step 4: fix up any arguments */
 430
 431        if (err)
 432                return 4;
 433
 434        /* Step 5: check channel list if it exists */
 435        if (cmd->chanlist && cmd->chanlist_len > 0)
 436                err |= gsc_hpdi_check_chanlist(dev, s, cmd);
 437
 438        if (err)
 439                return 5;
 440
 441        return 0;
 442
 443}
 444
 445/* setup dma descriptors so a link completes every 'len' bytes */
 446static int gsc_hpdi_setup_dma_descriptors(struct comedi_device *dev,
 447                                          unsigned int len)
 448{
 449        struct hpdi_private *devpriv = dev->private;
 450        dma_addr_t phys_addr = devpriv->dma_desc_phys_addr;
 451        uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
 452                             PLX_XFER_LOCAL_TO_PCI;
 453        unsigned int offset = 0;
 454        unsigned int idx = 0;
 455        unsigned int i;
 456
 457        if (len > DMA_BUFFER_SIZE)
 458                len = DMA_BUFFER_SIZE;
 459        len -= len % sizeof(uint32_t);
 460        if (len == 0)
 461                return -EINVAL;
 462
 463        for (i = 0; i < NUM_DMA_DESCRIPTORS && idx < NUM_DMA_BUFFERS; i++) {
 464                devpriv->dma_desc[i].pci_start_addr =
 465                    cpu_to_le32(devpriv->dio_buffer_phys_addr[idx] + offset);
 466                devpriv->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
 467                devpriv->dma_desc[i].transfer_size = cpu_to_le32(len);
 468                devpriv->dma_desc[i].next = cpu_to_le32((phys_addr +
 469                        (i + 1) * sizeof(devpriv->dma_desc[0])) | next_bits);
 470
 471                devpriv->desc_dio_buffer[i] = devpriv->dio_buffer[idx] +
 472                                              (offset / sizeof(uint32_t));
 473
 474                offset += len;
 475                if (len + offset > DMA_BUFFER_SIZE) {
 476                        offset = 0;
 477                        idx++;
 478                }
 479        }
 480        devpriv->num_dma_descriptors = i;
 481        /* fix last descriptor to point back to first */
 482        devpriv->dma_desc[i - 1].next = cpu_to_le32(phys_addr | next_bits);
 483
 484        devpriv->block_size = len;
 485
 486        return len;
 487}
 488
 489static int gsc_hpdi_dio_insn_config(struct comedi_device *dev,
 490                                    struct comedi_subdevice *s,
 491                                    struct comedi_insn *insn,
 492                                    unsigned int *data)
 493{
 494        int ret;
 495
 496        switch (data[0]) {
 497        case INSN_CONFIG_BLOCK_SIZE:
 498                ret = gsc_hpdi_setup_dma_descriptors(dev, data[1]);
 499                if (ret)
 500                        return ret;
 501
 502                data[1] = ret;
 503                break;
 504        default:
 505                ret = comedi_dio_insn_config(dev, s, insn, data, 0xffffffff);
 506                if (ret)
 507                        return ret;
 508                break;
 509        }
 510
 511        return insn->n;
 512}
 513
 514static int gsc_hpdi_init(struct comedi_device *dev)
 515{
 516        struct hpdi_private *devpriv = dev->private;
 517        uint32_t plx_intcsr_bits;
 518
 519        /* wait 10usec after reset before accessing fifos */
 520        writel(BOARD_RESET_BIT, devpriv->mmio + BOARD_CONTROL_REG);
 521        udelay(10);
 522
 523        writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
 524               devpriv->mmio + RX_PROG_ALMOST_REG);
 525        writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
 526               devpriv->mmio + TX_PROG_ALMOST_REG);
 527
 528        devpriv->tx_fifo_size = readl(devpriv->mmio + TX_FIFO_SIZE_REG) &
 529                                FIFO_SIZE_MASK;
 530        devpriv->rx_fifo_size = readl(devpriv->mmio + RX_FIFO_SIZE_REG) &
 531                                FIFO_SIZE_MASK;
 532
 533        writel(0, devpriv->mmio + INTERRUPT_CONTROL_REG);
 534
 535        /*  enable interrupts */
 536        plx_intcsr_bits =
 537            ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
 538            ICS_DMA0_E;
 539        writel(plx_intcsr_bits, devpriv->plx9080_mmio + PLX_INTRCS_REG);
 540
 541        return 0;
 542}
 543
 544static void gsc_hpdi_init_plx9080(struct comedi_device *dev)
 545{
 546        struct hpdi_private *devpriv = dev->private;
 547        uint32_t bits;
 548        void __iomem *plx_iobase = devpriv->plx9080_mmio;
 549
 550#ifdef __BIG_ENDIAN
 551        bits = BIGEND_DMA0 | BIGEND_DMA1;
 552#else
 553        bits = 0;
 554#endif
 555        writel(bits, devpriv->plx9080_mmio + PLX_BIGEND_REG);
 556
 557        writel(0, devpriv->plx9080_mmio + PLX_INTRCS_REG);
 558
 559        gsc_hpdi_abort_dma(dev, 0);
 560        gsc_hpdi_abort_dma(dev, 1);
 561
 562        /*  configure dma0 mode */
 563        bits = 0;
 564        /*  enable ready input */
 565        bits |= PLX_DMA_EN_READYIN_BIT;
 566        /*  enable dma chaining */
 567        bits |= PLX_EN_CHAIN_BIT;
 568        /*  enable interrupt on dma done
 569         *  (probably don't need this, since chain never finishes) */
 570        bits |= PLX_EN_DMA_DONE_INTR_BIT;
 571        /*  don't increment local address during transfers
 572         *  (we are transferring from a fixed fifo register) */
 573        bits |= PLX_LOCAL_ADDR_CONST_BIT;
 574        /*  route dma interrupt to pci bus */
 575        bits |= PLX_DMA_INTR_PCI_BIT;
 576        /*  enable demand mode */
 577        bits |= PLX_DEMAND_MODE_BIT;
 578        /*  enable local burst mode */
 579        bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
 580        bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
 581        writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
 582}
 583
 584static const struct hpdi_board *gsc_hpdi_find_board(struct pci_dev *pcidev)
 585{
 586        unsigned int i;
 587
 588        for (i = 0; i < ARRAY_SIZE(hpdi_boards); i++)
 589                if (pcidev->device == hpdi_boards[i].device_id &&
 590                    pcidev->subsystem_device == hpdi_boards[i].subdevice_id)
 591                        return &hpdi_boards[i];
 592        return NULL;
 593}
 594
 595static int gsc_hpdi_auto_attach(struct comedi_device *dev,
 596                                unsigned long context_unused)
 597{
 598        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 599        const struct hpdi_board *thisboard;
 600        struct hpdi_private *devpriv;
 601        struct comedi_subdevice *s;
 602        int i;
 603        int retval;
 604
 605        thisboard = gsc_hpdi_find_board(pcidev);
 606        if (!thisboard) {
 607                dev_err(dev->class_dev, "gsc_hpdi: pci %s not supported\n",
 608                        pci_name(pcidev));
 609                return -EINVAL;
 610        }
 611        dev->board_ptr = thisboard;
 612        dev->board_name = thisboard->name;
 613
 614        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 615        if (!devpriv)
 616                return -ENOMEM;
 617
 618        retval = comedi_pci_enable(dev);
 619        if (retval)
 620                return retval;
 621        pci_set_master(pcidev);
 622
 623        devpriv->plx9080_mmio = pci_ioremap_bar(pcidev, 0);
 624        devpriv->mmio = pci_ioremap_bar(pcidev, 2);
 625        if (!devpriv->plx9080_mmio || !devpriv->mmio) {
 626                dev_warn(dev->class_dev, "failed to remap io memory\n");
 627                return -ENOMEM;
 628        }
 629
 630        gsc_hpdi_init_plx9080(dev);
 631
 632        /*  get irq */
 633        if (request_irq(pcidev->irq, gsc_hpdi_interrupt, IRQF_SHARED,
 634                        dev->board_name, dev)) {
 635                dev_warn(dev->class_dev,
 636                         "unable to allocate irq %u\n", pcidev->irq);
 637                return -EINVAL;
 638        }
 639        dev->irq = pcidev->irq;
 640
 641        dev_dbg(dev->class_dev, " irq %u\n", dev->irq);
 642
 643        /*  allocate pci dma buffers */
 644        for (i = 0; i < NUM_DMA_BUFFERS; i++) {
 645                devpriv->dio_buffer[i] =
 646                    pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
 647                                         &devpriv->dio_buffer_phys_addr[i]);
 648        }
 649        /*  allocate dma descriptors */
 650        devpriv->dma_desc = pci_alloc_consistent(pcidev,
 651                                                 sizeof(struct plx_dma_desc) *
 652                                                 NUM_DMA_DESCRIPTORS,
 653                                                 &devpriv->dma_desc_phys_addr);
 654        if (devpriv->dma_desc_phys_addr & 0xf) {
 655                dev_warn(dev->class_dev,
 656                         " dma descriptors not quad-word aligned (bug)\n");
 657                return -EIO;
 658        }
 659
 660        retval = gsc_hpdi_setup_dma_descriptors(dev, 0x1000);
 661        if (retval < 0)
 662                return retval;
 663
 664        retval = comedi_alloc_subdevices(dev, 1);
 665        if (retval)
 666                return retval;
 667
 668        /* Digital I/O subdevice */
 669        s = &dev->subdevices[0];
 670        dev->read_subdev = s;
 671        s->type         = COMEDI_SUBD_DIO;
 672        s->subdev_flags = SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL |
 673                          SDF_CMD_READ;
 674        s->n_chan       = 32;
 675        s->len_chanlist = 32;
 676        s->maxdata      = 1;
 677        s->range_table  = &range_digital;
 678        s->insn_config  = gsc_hpdi_dio_insn_config;
 679        s->do_cmd       = gsc_hpdi_cmd;
 680        s->do_cmdtest   = gsc_hpdi_cmd_test;
 681        s->cancel       = gsc_hpdi_cancel;
 682
 683        return gsc_hpdi_init(dev);
 684}
 685
 686static void gsc_hpdi_detach(struct comedi_device *dev)
 687{
 688        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 689        struct hpdi_private *devpriv = dev->private;
 690        unsigned int i;
 691
 692        if (dev->irq)
 693                free_irq(dev->irq, dev);
 694        if (devpriv) {
 695                if (devpriv->plx9080_mmio) {
 696                        writel(0, devpriv->plx9080_mmio + PLX_INTRCS_REG);
 697                        iounmap(devpriv->plx9080_mmio);
 698                }
 699                if (devpriv->mmio)
 700                        iounmap(devpriv->mmio);
 701                /*  free pci dma buffers */
 702                for (i = 0; i < NUM_DMA_BUFFERS; i++) {
 703                        if (devpriv->dio_buffer[i])
 704                                pci_free_consistent(pcidev,
 705                                                    DMA_BUFFER_SIZE,
 706                                                    devpriv->dio_buffer[i],
 707                                                    devpriv->
 708                                                    dio_buffer_phys_addr[i]);
 709                }
 710                /*  free dma descriptors */
 711                if (devpriv->dma_desc)
 712                        pci_free_consistent(pcidev,
 713                                            sizeof(struct plx_dma_desc) *
 714                                            NUM_DMA_DESCRIPTORS,
 715                                            devpriv->dma_desc,
 716                                            devpriv->dma_desc_phys_addr);
 717        }
 718        comedi_pci_disable(dev);
 719}
 720
 721static struct comedi_driver gsc_hpdi_driver = {
 722        .driver_name    = "gsc_hpdi",
 723        .module         = THIS_MODULE,
 724        .auto_attach    = gsc_hpdi_auto_attach,
 725        .detach         = gsc_hpdi_detach,
 726};
 727
 728static int gsc_hpdi_pci_probe(struct pci_dev *dev,
 729                              const struct pci_device_id *id)
 730{
 731        return comedi_pci_auto_config(dev, &gsc_hpdi_driver, id->driver_data);
 732}
 733
 734static const struct pci_device_id gsc_hpdi_pci_table[] = {
 735        { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX,
 736                    0x2400, 0, 0, 0},
 737        { 0 }
 738};
 739MODULE_DEVICE_TABLE(pci, gsc_hpdi_pci_table);
 740
 741static struct pci_driver gsc_hpdi_pci_driver = {
 742        .name           = "gsc_hpdi",
 743        .id_table       = gsc_hpdi_pci_table,
 744        .probe          = gsc_hpdi_pci_probe,
 745        .remove         = comedi_pci_auto_unconfig,
 746};
 747module_comedi_pci_driver(gsc_hpdi_driver, gsc_hpdi_pci_driver);
 748
 749MODULE_AUTHOR("Comedi http://www.comedi.org");
 750MODULE_DESCRIPTION("Comedi low-level driver");
 751MODULE_LICENSE("GPL");
 752
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.