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