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 (dev->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        uint32_t *dio_buffer[NUM_DMA_BUFFERS];  /*  dma buffers */
 152        /* physical addresses of dma buffers */
 153        dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];
 154        /* array of dma descriptors read by plx9080, allocated to get proper
 155         * alignment */
 156        struct plx_dma_desc *dma_desc;
 157        /* physical address of dma descriptor array */
 158        dma_addr_t dma_desc_phys_addr;
 159        unsigned int num_dma_descriptors;
 160        /* pointer to start of buffers indexed by descriptor */
 161        uint32_t *desc_dio_buffer[NUM_DMA_DESCRIPTORS];
 162        /* index of the dma descriptor that is currently being used */
 163        unsigned int dma_desc_index;
 164        unsigned int tx_fifo_size;
 165        unsigned int rx_fifo_size;
 166        unsigned long dio_count;
 167        /* number of bytes at which to generate COMEDI_CB_BLOCK events */
 168        unsigned int block_size;
 169};
 170
 171static void gsc_hpdi_drain_dma(struct comedi_device *dev, unsigned int channel)
 172{
 173        struct hpdi_private *devpriv = dev->private;
 174        struct comedi_subdevice *s = dev->read_subdev;
 175        struct comedi_cmd *cmd = &s->async->cmd;
 176        unsigned int idx;
 177        unsigned int start;
 178        unsigned int desc;
 179        unsigned int size;
 180        unsigned int next;
 181
 182        if (channel)
 183                next = readl(devpriv->plx9080_mmio + PLX_DMA1_PCI_ADDRESS_REG);
 184        else
 185                next = readl(devpriv->plx9080_mmio + PLX_DMA0_PCI_ADDRESS_REG);
 186
 187        idx = devpriv->dma_desc_index;
 188        start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr);
 189        /* loop until we have read all the full buffers */
 190        for (desc = 0; (next < start || next >= start + devpriv->block_size) &&
 191             desc < devpriv->num_dma_descriptors; desc++) {
 192                /* transfer data from dma buffer to comedi buffer */
 193                size = devpriv->block_size / sizeof(uint32_t);
 194                if (cmd->stop_src == TRIG_COUNT) {
 195                        if (size > devpriv->dio_count)
 196                                size = devpriv->dio_count;
 197                        devpriv->dio_count -= size;
 198                }
 199                comedi_buf_write_samples(s, devpriv->desc_dio_buffer[idx],
 200                                         size);
 201                idx++;
 202                idx %= devpriv->num_dma_descriptors;
 203                start = le32_to_cpu(devpriv->dma_desc[idx].pci_start_addr);
 204
 205                devpriv->dma_desc_index = idx;
 206        }
 207        /*  XXX check for buffer overrun somehow */
 208}
 209
 210static irqreturn_t gsc_hpdi_interrupt(int irq, void *d)
 211{
 212        struct comedi_device *dev = d;
 213        struct hpdi_private *devpriv = dev->private;
 214        struct comedi_subdevice *s = dev->read_subdev;
 215        struct comedi_async *async = s->async;
 216        uint32_t hpdi_intr_status, hpdi_board_status;
 217        uint32_t plx_status;
 218        uint32_t plx_bits;
 219        uint8_t dma0_status, dma1_status;
 220        unsigned long flags;
 221
 222        if (!dev->attached)
 223                return IRQ_NONE;
 224
 225        plx_status = readl(devpriv->plx9080_mmio + PLX_INTRCS_REG);
 226        if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0)
 227                return IRQ_NONE;
 228
 229        hpdi_intr_status = readl(dev->mmio + INTERRUPT_STATUS_REG);
 230        hpdi_board_status = readl(dev->mmio + BOARD_STATUS_REG);
 231
 232        if (hpdi_intr_status)
 233                writel(hpdi_intr_status, dev->mmio + INTERRUPT_STATUS_REG);
 234
 235        /*  spin lock makes sure no one else changes plx dma control reg */
 236        spin_lock_irqsave(&dev->spinlock, flags);
 237        dma0_status = readb(devpriv->plx9080_mmio + PLX_DMA0_CS_REG);
 238        if (plx_status & ICS_DMA0_A) {  /*  dma chan 0 interrupt */
 239                writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
 240                       devpriv->plx9080_mmio + PLX_DMA0_CS_REG);
 241
 242                if (dma0_status & PLX_DMA_EN_BIT)
 243                        gsc_hpdi_drain_dma(dev, 0);
 244        }
 245        spin_unlock_irqrestore(&dev->spinlock, flags);
 246
 247        /*  spin lock makes sure no one else changes plx dma control reg */
 248        spin_lock_irqsave(&dev->spinlock, flags);
 249        dma1_status = readb(devpriv->plx9080_mmio + PLX_DMA1_CS_REG);
 250        if (plx_status & ICS_DMA1_A) {  /*  XXX *//*  dma chan 1 interrupt */
 251                writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
 252                       devpriv->plx9080_mmio + PLX_DMA1_CS_REG);
 253        }
 254        spin_unlock_irqrestore(&dev->spinlock, flags);
 255
 256        /*  clear possible plx9080 interrupt sources */
 257        if (plx_status & ICS_LDIA) {    /*  clear local doorbell interrupt */
 258                plx_bits = readl(devpriv->plx9080_mmio + PLX_DBR_OUT_REG);
 259                writel(plx_bits, devpriv->plx9080_mmio + PLX_DBR_OUT_REG);
 260        }
 261
 262        if (hpdi_board_status & RX_OVERRUN_BIT) {
 263                dev_err(dev->class_dev, "rx fifo overrun\n");
 264                async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 265        }
 266
 267        if (hpdi_board_status & RX_UNDERRUN_BIT) {
 268                dev_err(dev->class_dev, "rx fifo underrun\n");
 269                async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
 270        }
 271
 272        if (devpriv->dio_count == 0)
 273                async->events |= COMEDI_CB_EOA;
 274
 275        comedi_handle_events(dev, s);
 276
 277        return IRQ_HANDLED;
 278}
 279
 280static void gsc_hpdi_abort_dma(struct comedi_device *dev, unsigned int channel)
 281{
 282        struct hpdi_private *devpriv = dev->private;
 283        unsigned long flags;
 284
 285        /*  spinlock for plx dma control/status reg */
 286        spin_lock_irqsave(&dev->spinlock, flags);
 287
 288        plx9080_abort_dma(devpriv->plx9080_mmio, channel);
 289
 290        spin_unlock_irqrestore(&dev->spinlock, flags);
 291}
 292
 293static int gsc_hpdi_cancel(struct comedi_device *dev,
 294                           struct comedi_subdevice *s)
 295{
 296        writel(0, dev->mmio + BOARD_CONTROL_REG);
 297        writel(0, dev->mmio + INTERRUPT_CONTROL_REG);
 298
 299        gsc_hpdi_abort_dma(dev, 0);
 300
 301        return 0;
 302}
 303
 304static int gsc_hpdi_cmd(struct comedi_device *dev,
 305                        struct comedi_subdevice *s)
 306{
 307        struct hpdi_private *devpriv = dev->private;
 308        struct comedi_async *async = s->async;
 309        struct comedi_cmd *cmd = &async->cmd;
 310        unsigned long flags;
 311        uint32_t bits;
 312
 313        if (s->io_bits)
 314                return -EINVAL;
 315
 316        writel(RX_FIFO_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);
 317
 318        gsc_hpdi_abort_dma(dev, 0);
 319
 320        devpriv->dma_desc_index = 0;
 321
 322        /*
 323         * These register are supposedly unused during chained dma,
 324         * but I have found that left over values from last operation
 325         * occasionally cause problems with transfer of first dma
 326         * block.  Initializing them to zero seems to fix the problem.
 327         */
 328        writel(0, devpriv->plx9080_mmio + PLX_DMA0_TRANSFER_SIZE_REG);
 329        writel(0, devpriv->plx9080_mmio + PLX_DMA0_PCI_ADDRESS_REG);
 330        writel(0, devpriv->plx9080_mmio + PLX_DMA0_LOCAL_ADDRESS_REG);
 331
 332        /* give location of first dma descriptor */
 333        bits = devpriv->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT |
 334               PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI;
 335        writel(bits, devpriv->plx9080_mmio + PLX_DMA0_DESCRIPTOR_REG);
 336
 337        /* enable dma transfer */
 338        spin_lock_irqsave(&dev->spinlock, flags);
 339        writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT,
 340               devpriv->plx9080_mmio + PLX_DMA0_CS_REG);
 341        spin_unlock_irqrestore(&dev->spinlock, flags);
 342
 343        if (cmd->stop_src == TRIG_COUNT)
 344                devpriv->dio_count = cmd->stop_arg;
 345        else
 346                devpriv->dio_count = 1;
 347
 348        /* clear over/under run status flags */
 349        writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT, dev->mmio + BOARD_STATUS_REG);
 350
 351        /* enable interrupts */
 352        writel(RX_FULL_INTR, dev->mmio + INTERRUPT_CONTROL_REG);
 353
 354        writel(RX_ENABLE_BIT, dev->mmio + BOARD_CONTROL_REG);
 355
 356        return 0;
 357}
 358
 359static int gsc_hpdi_check_chanlist(struct comedi_device *dev,
 360                                   struct comedi_subdevice *s,
 361                                   struct comedi_cmd *cmd)
 362{
 363        int i;
 364
 365        for (i = 0; i < cmd->chanlist_len; i++) {
 366                unsigned int chan = CR_CHAN(cmd->chanlist[i]);
 367
 368                if (chan != i) {
 369                        dev_dbg(dev->class_dev,
 370                                "chanlist must be ch 0 to 31 in order\n");
 371                        return -EINVAL;
 372                }
 373        }
 374
 375        return 0;
 376}
 377
 378static int gsc_hpdi_cmd_test(struct comedi_device *dev,
 379                             struct comedi_subdevice *s,
 380                             struct comedi_cmd *cmd)
 381{
 382        int err = 0;
 383
 384        if (s->io_bits)
 385                return -EINVAL;
 386
 387        /* Step 1 : check if triggers are trivially valid */
 388
 389        err |= cfc_check_trigger_src(&cmd->start_src, TRIG_NOW);
 390        err |= cfc_check_trigger_src(&cmd->scan_begin_src, TRIG_EXT);
 391        err |= cfc_check_trigger_src(&cmd->convert_src, TRIG_NOW);
 392        err |= cfc_check_trigger_src(&cmd->scan_end_src, TRIG_COUNT);
 393        err |= cfc_check_trigger_src(&cmd->stop_src, TRIG_COUNT | TRIG_NONE);
 394
 395        if (err)
 396                return 1;
 397
 398        /* Step 2a : make sure trigger sources are unique */
 399
 400        err |= cfc_check_trigger_is_unique(cmd->stop_src);
 401
 402        /* Step 2b : and mutually compatible */
 403
 404        if (err)
 405                return 2;
 406
 407        /* Step 3: check if arguments are trivially valid */
 408
 409        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
 410
 411        if (!cmd->chanlist_len || !cmd->chanlist) {
 412                cmd->chanlist_len = 32;
 413                err |= -EINVAL;
 414        }
 415        err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
 416
 417        if (cmd->stop_src == TRIG_COUNT)
 418                err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
 419        else    /* TRIG_NONE */
 420                err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 421
 422        if (err)
 423                return 3;
 424
 425        /* Step 4: fix up any arguments */
 426
 427        /* Step 5: check channel list if it exists */
 428
 429        if (cmd->chanlist && cmd->chanlist_len > 0)
 430                err |= gsc_hpdi_check_chanlist(dev, s, cmd);
 431
 432        if (err)
 433                return 5;
 434
 435        return 0;
 436
 437}
 438
 439/* setup dma descriptors so a link completes every 'len' bytes */
 440static int gsc_hpdi_setup_dma_descriptors(struct comedi_device *dev,
 441                                          unsigned int len)
 442{
 443        struct hpdi_private *devpriv = dev->private;
 444        dma_addr_t phys_addr = devpriv->dma_desc_phys_addr;
 445        uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
 446                             PLX_XFER_LOCAL_TO_PCI;
 447        unsigned int offset = 0;
 448        unsigned int idx = 0;
 449        unsigned int i;
 450
 451        if (len > DMA_BUFFER_SIZE)
 452                len = DMA_BUFFER_SIZE;
 453        len -= len % sizeof(uint32_t);
 454        if (len == 0)
 455                return -EINVAL;
 456
 457        for (i = 0; i < NUM_DMA_DESCRIPTORS && idx < NUM_DMA_BUFFERS; i++) {
 458                devpriv->dma_desc[i].pci_start_addr =
 459                    cpu_to_le32(devpriv->dio_buffer_phys_addr[idx] + offset);
 460                devpriv->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
 461                devpriv->dma_desc[i].transfer_size = cpu_to_le32(len);
 462                devpriv->dma_desc[i].next = cpu_to_le32((phys_addr +
 463                        (i + 1) * sizeof(devpriv->dma_desc[0])) | next_bits);
 464
 465                devpriv->desc_dio_buffer[i] = devpriv->dio_buffer[idx] +
 466                                              (offset / sizeof(uint32_t));
 467
 468                offset += len;
 469                if (len + offset > DMA_BUFFER_SIZE) {
 470                        offset = 0;
 471                        idx++;
 472                }
 473        }
 474        devpriv->num_dma_descriptors = i;
 475        /* fix last descriptor to point back to first */
 476        devpriv->dma_desc[i - 1].next = cpu_to_le32(phys_addr | next_bits);
 477
 478        devpriv->block_size = len;
 479
 480        return len;
 481}
 482
 483static int gsc_hpdi_dio_insn_config(struct comedi_device *dev,
 484                                    struct comedi_subdevice *s,
 485                                    struct comedi_insn *insn,
 486                                    unsigned int *data)
 487{
 488        int ret;
 489
 490        switch (data[0]) {
 491        case INSN_CONFIG_BLOCK_SIZE:
 492                ret = gsc_hpdi_setup_dma_descriptors(dev, data[1]);
 493                if (ret)
 494                        return ret;
 495
 496                data[1] = ret;
 497                break;
 498        default:
 499                ret = comedi_dio_insn_config(dev, s, insn, data, 0xffffffff);
 500                if (ret)
 501                        return ret;
 502                break;
 503        }
 504
 505        return insn->n;
 506}
 507
 508static void gsc_hpdi_free_dma(struct comedi_device *dev)
 509{
 510        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 511        struct hpdi_private *devpriv = dev->private;
 512        int i;
 513
 514        if (!devpriv)
 515                return;
 516
 517        /* free pci dma buffers */
 518        for (i = 0; i < NUM_DMA_BUFFERS; i++) {
 519                if (devpriv->dio_buffer[i])
 520                        pci_free_consistent(pcidev,
 521                                            DMA_BUFFER_SIZE,
 522                                            devpriv->dio_buffer[i],
 523                                            devpriv->dio_buffer_phys_addr[i]);
 524        }
 525        /* free dma descriptors */
 526        if (devpriv->dma_desc)
 527                pci_free_consistent(pcidev,
 528                                    sizeof(struct plx_dma_desc) *
 529                                    NUM_DMA_DESCRIPTORS,
 530                                    devpriv->dma_desc,
 531                                    devpriv->dma_desc_phys_addr);
 532}
 533
 534static int gsc_hpdi_init(struct comedi_device *dev)
 535{
 536        struct hpdi_private *devpriv = dev->private;
 537        uint32_t plx_intcsr_bits;
 538
 539        /* wait 10usec after reset before accessing fifos */
 540        writel(BOARD_RESET_BIT, dev->mmio + BOARD_CONTROL_REG);
 541        udelay(10);
 542
 543        writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
 544               dev->mmio + RX_PROG_ALMOST_REG);
 545        writel(ALMOST_EMPTY_BITS(32) | ALMOST_FULL_BITS(32),
 546               dev->mmio + TX_PROG_ALMOST_REG);
 547
 548        devpriv->tx_fifo_size = readl(dev->mmio + TX_FIFO_SIZE_REG) &
 549                                FIFO_SIZE_MASK;
 550        devpriv->rx_fifo_size = readl(dev->mmio + RX_FIFO_SIZE_REG) &
 551                                FIFO_SIZE_MASK;
 552
 553        writel(0, dev->mmio + INTERRUPT_CONTROL_REG);
 554
 555        /*  enable interrupts */
 556        plx_intcsr_bits =
 557            ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
 558            ICS_DMA0_E;
 559        writel(plx_intcsr_bits, devpriv->plx9080_mmio + PLX_INTRCS_REG);
 560
 561        return 0;
 562}
 563
 564static void gsc_hpdi_init_plx9080(struct comedi_device *dev)
 565{
 566        struct hpdi_private *devpriv = dev->private;
 567        uint32_t bits;
 568        void __iomem *plx_iobase = devpriv->plx9080_mmio;
 569
 570#ifdef __BIG_ENDIAN
 571        bits = BIGEND_DMA0 | BIGEND_DMA1;
 572#else
 573        bits = 0;
 574#endif
 575        writel(bits, devpriv->plx9080_mmio + PLX_BIGEND_REG);
 576
 577        writel(0, devpriv->plx9080_mmio + PLX_INTRCS_REG);
 578
 579        gsc_hpdi_abort_dma(dev, 0);
 580        gsc_hpdi_abort_dma(dev, 1);
 581
 582        /*  configure dma0 mode */
 583        bits = 0;
 584        /*  enable ready input */
 585        bits |= PLX_DMA_EN_READYIN_BIT;
 586        /*  enable dma chaining */
 587        bits |= PLX_EN_CHAIN_BIT;
 588        /*  enable interrupt on dma done
 589         *  (probably don't need this, since chain never finishes) */
 590        bits |= PLX_EN_DMA_DONE_INTR_BIT;
 591        /*  don't increment local address during transfers
 592         *  (we are transferring from a fixed fifo register) */
 593        bits |= PLX_LOCAL_ADDR_CONST_BIT;
 594        /*  route dma interrupt to pci bus */
 595        bits |= PLX_DMA_INTR_PCI_BIT;
 596        /*  enable demand mode */
 597        bits |= PLX_DEMAND_MODE_BIT;
 598        /*  enable local burst mode */
 599        bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
 600        bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
 601        writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
 602}
 603
 604static const struct hpdi_board *gsc_hpdi_find_board(struct pci_dev *pcidev)
 605{
 606        unsigned int i;
 607
 608        for (i = 0; i < ARRAY_SIZE(hpdi_boards); i++)
 609                if (pcidev->device == hpdi_boards[i].device_id &&
 610                    pcidev->subsystem_device == hpdi_boards[i].subdevice_id)
 611                        return &hpdi_boards[i];
 612        return NULL;
 613}
 614
 615static int gsc_hpdi_auto_attach(struct comedi_device *dev,
 616                                unsigned long context_unused)
 617{
 618        struct pci_dev *pcidev = comedi_to_pci_dev(dev);
 619        const struct hpdi_board *thisboard;
 620        struct hpdi_private *devpriv;
 621        struct comedi_subdevice *s;
 622        int i;
 623        int retval;
 624
 625        thisboard = gsc_hpdi_find_board(pcidev);
 626        if (!thisboard) {
 627                dev_err(dev->class_dev, "gsc_hpdi: pci %s not supported\n",
 628                        pci_name(pcidev));
 629                return -EINVAL;
 630        }
 631        dev->board_ptr = thisboard;
 632        dev->board_name = thisboard->name;
 633
 634        devpriv = comedi_alloc_devpriv(dev, sizeof(*devpriv));
 635        if (!devpriv)
 636                return -ENOMEM;
 637
 638        retval = comedi_pci_enable(dev);
 639        if (retval)
 640                return retval;
 641        pci_set_master(pcidev);
 642
 643        devpriv->plx9080_mmio = pci_ioremap_bar(pcidev, 0);
 644        dev->mmio = pci_ioremap_bar(pcidev, 2);
 645        if (!devpriv->plx9080_mmio || !dev->mmio) {
 646                dev_warn(dev->class_dev, "failed to remap io memory\n");
 647                return -ENOMEM;
 648        }
 649
 650        gsc_hpdi_init_plx9080(dev);
 651
 652        /*  get irq */
 653        if (request_irq(pcidev->irq, gsc_hpdi_interrupt, IRQF_SHARED,
 654                        dev->board_name, dev)) {
 655                dev_warn(dev->class_dev,
 656                         "unable to allocate irq %u\n", pcidev->irq);
 657                return -EINVAL;
 658        }
 659        dev->irq = pcidev->irq;
 660
 661        dev_dbg(dev->class_dev, " irq %u\n", dev->irq);
 662
 663        /*  allocate pci dma buffers */
 664        for (i = 0; i < NUM_DMA_BUFFERS; i++) {
 665                devpriv->dio_buffer[i] =
 666                    pci_alloc_consistent(pcidev, DMA_BUFFER_SIZE,
 667                                         &devpriv->dio_buffer_phys_addr[i]);
 668        }
 669        /*  allocate dma descriptors */
 670        devpriv->dma_desc = pci_alloc_consistent(pcidev,
 671                                                 sizeof(struct plx_dma_desc) *
 672                                                 NUM_DMA_DESCRIPTORS,
 673                                                 &devpriv->dma_desc_phys_addr);
 674        if (devpriv->dma_desc_phys_addr & 0xf) {
 675                dev_warn(dev->class_dev,
 676                         " dma descriptors not quad-word aligned (bug)\n");
 677                return -EIO;
 678        }
 679
 680        retval = gsc_hpdi_setup_dma_descriptors(dev, 0x1000);
 681        if (retval < 0)
 682                return retval;
 683
 684        retval = comedi_alloc_subdevices(dev, 1);
 685        if (retval)
 686                return retval;
 687
 688        /* Digital I/O subdevice */
 689        s = &dev->subdevices[0];
 690        dev->read_subdev = s;
 691        s->type         = COMEDI_SUBD_DIO;
 692        s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
 693                          SDF_CMD_READ;
 694        s->n_chan       = 32;
 695        s->len_chanlist = 32;
 696        s->maxdata      = 1;
 697        s->range_table  = &range_digital;
 698        s->insn_config  = gsc_hpdi_dio_insn_config;
 699        s->do_cmd       = gsc_hpdi_cmd;
 700        s->do_cmdtest   = gsc_hpdi_cmd_test;
 701        s->cancel       = gsc_hpdi_cancel;
 702
 703        return gsc_hpdi_init(dev);
 704}
 705
 706static void gsc_hpdi_detach(struct comedi_device *dev)
 707{
 708        struct hpdi_private *devpriv = dev->private;
 709
 710        if (dev->irq)
 711                free_irq(dev->irq, dev);
 712        if (devpriv) {
 713                if (devpriv->plx9080_mmio) {
 714                        writel(0, devpriv->plx9080_mmio + PLX_INTRCS_REG);
 715                        iounmap(devpriv->plx9080_mmio);
 716                }
 717                if (dev->mmio)
 718                        iounmap(dev->mmio);
 719        }
 720        comedi_pci_disable(dev);
 721        gsc_hpdi_free_dma(dev);
 722}
 723
 724static struct comedi_driver gsc_hpdi_driver = {
 725        .driver_name    = "gsc_hpdi",
 726        .module         = THIS_MODULE,
 727        .auto_attach    = gsc_hpdi_auto_attach,
 728        .detach         = gsc_hpdi_detach,
 729};
 730
 731static int gsc_hpdi_pci_probe(struct pci_dev *dev,
 732                              const struct pci_device_id *id)
 733{
 734        return comedi_pci_auto_config(dev, &gsc_hpdi_driver, id->driver_data);
 735}
 736
 737static const struct pci_device_id gsc_hpdi_pci_table[] = {
 738        { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX,
 739                    0x2400, 0, 0, 0},
 740        { 0 }
 741};
 742MODULE_DEVICE_TABLE(pci, gsc_hpdi_pci_table);
 743
 744static struct pci_driver gsc_hpdi_pci_driver = {
 745        .name           = "gsc_hpdi",
 746        .id_table       = gsc_hpdi_pci_table,
 747        .probe          = gsc_hpdi_pci_probe,
 748        .remove         = comedi_pci_auto_unconfig,
 749};
 750module_comedi_pci_driver(gsc_hpdi_driver, gsc_hpdi_pci_driver);
 751
 752MODULE_AUTHOR("Comedi http://www.comedi.org");
 753MODULE_DESCRIPTION("Comedi low-level driver");
 754MODULE_LICENSE("GPL");
 755
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.