linux/drivers/staging/comedi/drivers/gsc_hpdi.c
<<
>>
Prefs
   1/*
   2    comedi/drivers/gsc_hpdi.c
   3    This is a driver for the General Standards Corporation High
   4    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    You should have received a copy of the GNU General Public License
  23    along with this program; if not, write to the Free Software
  24    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25
  26************************************************************************/
  27
  28/*
  29
  30Driver: gsc_hpdi
  31Description: General Standards Corporation High
  32    Speed Parallel Digital Interface rs485 boards
  33Author: Frank Mori Hess <fmhess@users.sourceforge.net>
  34Status: only receive mode works, transmit not supported
  35Updated: 2003-02-20
  36Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
  37  PMC-HPDI32
  38
  39Configuration options:
  40   [0] - PCI bus of device (optional)
  41   [1] - PCI slot of device (optional)
  42
  43There are some additional hpdi models available from GSC for which
  44support could be added to this driver.
  45
  46*/
  47
  48#include <linux/interrupt.h>
  49#include "../comedidev.h"
  50#include <linux/delay.h>
  51
  52#include "comedi_pci.h"
  53#include "plx9080.h"
  54#include "comedi_fc.h"
  55
  56static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it);
  57static int hpdi_detach(struct comedi_device *dev);
  58void abort_dma(struct comedi_device *dev, unsigned int channel);
  59static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
  60static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
  61                         struct comedi_cmd *cmd);
  62static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
  63static irqreturn_t handle_interrupt(int irq, void *d);
  64static int dio_config_block_size(struct comedi_device *dev, unsigned int *data);
  65
  66#undef HPDI_DEBUG               /*  disable debugging messages */
  67/* #define HPDI_DEBUG      enable debugging code */
  68
  69#ifdef HPDI_DEBUG
  70#define DEBUG_PRINT(format, args...)  printk(format , ## args)
  71#else
  72#define DEBUG_PRINT(format, args...)
  73#endif
  74
  75#define TIMER_BASE 50           /*  20MHz master clock */
  76#define DMA_BUFFER_SIZE 0x10000
  77#define NUM_DMA_BUFFERS 4
  78#define NUM_DMA_DESCRIPTORS 256
  79
  80/* indices of base address regions */
  81enum base_address_regions {
  82        PLX9080_BADDRINDEX = 0,
  83        HPDI_BADDRINDEX = 2,
  84};
  85
  86enum hpdi_registers {
  87        FIRMWARE_REV_REG = 0x0,
  88        BOARD_CONTROL_REG = 0x4,
  89        BOARD_STATUS_REG = 0x8,
  90        TX_PROG_ALMOST_REG = 0xc,
  91        RX_PROG_ALMOST_REG = 0x10,
  92        FEATURES_REG = 0x14,
  93        FIFO_REG = 0x18,
  94        TX_STATUS_COUNT_REG = 0x1c,
  95        TX_LINE_VALID_COUNT_REG = 0x20,
  96        TX_LINE_INVALID_COUNT_REG = 0x24,
  97        RX_STATUS_COUNT_REG = 0x28,
  98        RX_LINE_COUNT_REG = 0x2c,
  99        INTERRUPT_CONTROL_REG = 0x30,
 100        INTERRUPT_STATUS_REG = 0x34,
 101        TX_CLOCK_DIVIDER_REG = 0x38,
 102        TX_FIFO_SIZE_REG = 0x40,
 103        RX_FIFO_SIZE_REG = 0x44,
 104        TX_FIFO_WORDS_REG = 0x48,
 105        RX_FIFO_WORDS_REG = 0x4c,
 106        INTERRUPT_EDGE_LEVEL_REG = 0x50,
 107        INTERRUPT_POLARITY_REG = 0x54,
 108};
 109
 110int command_channel_valid(unsigned int channel)
 111{
 112        if (channel == 0 || channel > 6) {
 113                printk("gsc_hpdi: bug! invalid cable command channel\n");
 114                return 0;
 115        }
 116        return 1;
 117}
 118
 119/* bit definitions */
 120
 121enum firmware_revision_bits {
 122        FEATURES_REG_PRESENT_BIT = 0x8000,
 123};
 124int firmware_revision(uint32_t fwr_bits)
 125{
 126        return fwr_bits & 0xff;
 127}
 128
 129int pcb_revision(uint32_t fwr_bits)
 130{
 131        return (fwr_bits >> 8) & 0xff;
 132}
 133
 134int hpdi_subid(uint32_t fwr_bits)
 135{
 136        return (fwr_bits >> 16) & 0xff;
 137}
 138
 139enum board_control_bits {
 140        BOARD_RESET_BIT = 0x1,  /* wait 10usec before accessing fifos */
 141        TX_FIFO_RESET_BIT = 0x2,
 142        RX_FIFO_RESET_BIT = 0x4,
 143        TX_ENABLE_BIT = 0x10,
 144        RX_ENABLE_BIT = 0x20,
 145        DEMAND_DMA_DIRECTION_TX_BIT = 0x40,     /* for channel 0, channel 1 can only transmit (when present) */
 146        LINE_VALID_ON_STATUS_VALID_BIT = 0x80,
 147        START_TX_BIT = 0x10,
 148        CABLE_THROTTLE_ENABLE_BIT = 0x20,
 149        TEST_MODE_ENABLE_BIT = 0x80000000,
 150};
 151uint32_t command_discrete_output_bits(unsigned int channel, int output,
 152                                      int output_value)
 153{
 154        uint32_t bits = 0;
 155
 156        if (command_channel_valid(channel) == 0)
 157                return 0;
 158        if (output) {
 159                bits |= 0x1 << (16 + channel);
 160                if (output_value)
 161                        bits |= 0x1 << (24 + channel);
 162        } else
 163                bits |= 0x1 << (24 + channel);
 164
 165        return bits;
 166}
 167
 168enum board_status_bits {
 169        COMMAND_LINE_STATUS_MASK = 0x7f,
 170        TX_IN_PROGRESS_BIT = 0x80,
 171        TX_NOT_EMPTY_BIT = 0x100,
 172        TX_NOT_ALMOST_EMPTY_BIT = 0x200,
 173        TX_NOT_ALMOST_FULL_BIT = 0x400,
 174        TX_NOT_FULL_BIT = 0x800,
 175        RX_NOT_EMPTY_BIT = 0x1000,
 176        RX_NOT_ALMOST_EMPTY_BIT = 0x2000,
 177        RX_NOT_ALMOST_FULL_BIT = 0x4000,
 178        RX_NOT_FULL_BIT = 0x8000,
 179        BOARD_JUMPER0_INSTALLED_BIT = 0x10000,
 180        BOARD_JUMPER1_INSTALLED_BIT = 0x20000,
 181        TX_OVERRUN_BIT = 0x200000,
 182        RX_UNDERRUN_BIT = 0x400000,
 183        RX_OVERRUN_BIT = 0x800000,
 184};
 185
 186uint32_t almost_full_bits(unsigned int num_words)
 187{
 188/* XXX need to add or subtract one? */
 189        return (num_words << 16) & 0xff0000;
 190}
 191
 192uint32_t almost_empty_bits(unsigned int num_words)
 193{
 194        return num_words & 0xffff;
 195}
 196
 197unsigned int almost_full_num_words(uint32_t bits)
 198{
 199/* XXX need to add or subtract one? */
 200        return (bits >> 16) & 0xffff;
 201}
 202
 203unsigned int almost_empty_num_words(uint32_t bits)
 204{
 205        return bits & 0xffff;
 206}
 207
 208enum features_bits {
 209        FIFO_SIZE_PRESENT_BIT = 0x1,
 210        FIFO_WORDS_PRESENT_BIT = 0x2,
 211        LEVEL_EDGE_INTERRUPTS_PRESENT_BIT = 0x4,
 212        GPIO_SUPPORTED_BIT = 0x8,
 213        PLX_DMA_CH1_SUPPORTED_BIT = 0x10,
 214        OVERRUN_UNDERRUN_SUPPORTED_BIT = 0x20,
 215};
 216
 217enum interrupt_sources {
 218        FRAME_VALID_START_INTR = 0,
 219        FRAME_VALID_END_INTR = 1,
 220        TX_FIFO_EMPTY_INTR = 8,
 221        TX_FIFO_ALMOST_EMPTY_INTR = 9,
 222        TX_FIFO_ALMOST_FULL_INTR = 10,
 223        TX_FIFO_FULL_INTR = 11,
 224        RX_EMPTY_INTR = 12,
 225        RX_ALMOST_EMPTY_INTR = 13,
 226        RX_ALMOST_FULL_INTR = 14,
 227        RX_FULL_INTR = 15,
 228};
 229int command_intr_source(unsigned int channel)
 230{
 231        if (command_channel_valid(channel) == 0)
 232                channel = 1;
 233        return channel + 1;
 234}
 235
 236uint32_t intr_bit(int interrupt_source)
 237{
 238        return 0x1 << interrupt_source;
 239}
 240
 241uint32_t tx_clock_divisor_bits(unsigned int divisor)
 242{
 243        return divisor & 0xff;
 244}
 245
 246unsigned int fifo_size(uint32_t fifo_size_bits)
 247{
 248        return fifo_size_bits & 0xfffff;
 249}
 250
 251unsigned int fifo_words(uint32_t fifo_words_bits)
 252{
 253        return fifo_words_bits & 0xfffff;
 254}
 255
 256uint32_t intr_edge_bit(int interrupt_source)
 257{
 258        return 0x1 << interrupt_source;
 259}
 260
 261uint32_t intr_active_high_bit(int interrupt_source)
 262{
 263        return 0x1 << interrupt_source;
 264}
 265
 266struct hpdi_board {
 267
 268        char *name;
 269        int device_id;          /*  pci device id */
 270        int subdevice_id;       /*  pci subdevice id */
 271};
 272
 273static const struct hpdi_board hpdi_boards[] = {
 274        {
 275         .name = "pci-hpdi32",
 276         .device_id = PCI_DEVICE_ID_PLX_9080,
 277         .subdevice_id = 0x2400,
 278         },
 279#if 0
 280        {
 281         .name = "pxi-hpdi32",
 282         .device_id = 0x9656,
 283         .subdevice_id = 0x2705,
 284         },
 285#endif
 286};
 287
 288static DEFINE_PCI_DEVICE_TABLE(hpdi_pci_table) = {
 289        {
 290        PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX,
 291                    0x2400, 0, 0, 0}, {
 292        0}
 293};
 294
 295MODULE_DEVICE_TABLE(pci, hpdi_pci_table);
 296
 297static inline struct hpdi_board *board(const struct comedi_device *dev)
 298{
 299        return (struct hpdi_board *)dev->board_ptr;
 300}
 301
 302struct hpdi_private {
 303
 304        struct pci_dev *hw_dev; /*  pointer to board's pci_dev struct */
 305        /*  base addresses (physical) */
 306        resource_size_t plx9080_phys_iobase;
 307        resource_size_t hpdi_phys_iobase;
 308        /*  base addresses (ioremapped) */
 309        void *plx9080_iobase;
 310        void *hpdi_iobase;
 311        uint32_t *dio_buffer[NUM_DMA_BUFFERS];  /*  dma buffers */
 312        dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS];       /*  physical addresses of dma buffers */
 313        struct plx_dma_desc *dma_desc;  /*  array of dma descriptors read by plx9080, allocated to get proper alignment */
 314        dma_addr_t dma_desc_phys_addr;  /*  physical address of dma descriptor array */
 315        unsigned int num_dma_descriptors;
 316        uint32_t *desc_dio_buffer[NUM_DMA_DESCRIPTORS]; /*  pointer to start of buffers indexed by descriptor */
 317        volatile unsigned int dma_desc_index;   /*  index of the dma descriptor that is currently being used */
 318        unsigned int tx_fifo_size;
 319        unsigned int rx_fifo_size;
 320        volatile unsigned long dio_count;
 321        volatile uint32_t bits[24];     /*  software copies of values written to hpdi registers */
 322        volatile unsigned int block_size;       /*  number of bytes at which to generate COMEDI_CB_BLOCK events */
 323        unsigned dio_config_output:1;
 324};
 325
 326static inline struct hpdi_private *priv(struct comedi_device *dev)
 327{
 328        return dev->private;
 329}
 330
 331static struct comedi_driver driver_hpdi = {
 332        .driver_name = "gsc_hpdi",
 333        .module = THIS_MODULE,
 334        .attach = hpdi_attach,
 335        .detach = hpdi_detach,
 336};
 337
 338COMEDI_PCI_INITCLEANUP(driver_hpdi, hpdi_pci_table);
 339
 340static int dio_config_insn(struct comedi_device *dev,
 341                           struct comedi_subdevice *s, struct comedi_insn *insn,
 342                           unsigned int *data)
 343{
 344        switch (data[0]) {
 345        case INSN_CONFIG_DIO_OUTPUT:
 346                priv(dev)->dio_config_output = 1;
 347                return insn->n;
 348                break;
 349        case INSN_CONFIG_DIO_INPUT:
 350                priv(dev)->dio_config_output = 0;
 351                return insn->n;
 352                break;
 353        case INSN_CONFIG_DIO_QUERY:
 354                data[1] =
 355                    priv(dev)->dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
 356                return insn->n;
 357                break;
 358        case INSN_CONFIG_BLOCK_SIZE:
 359                return dio_config_block_size(dev, data);
 360                break;
 361        default:
 362                break;
 363        }
 364
 365        return -EINVAL;
 366}
 367
 368static void disable_plx_interrupts(struct comedi_device *dev)
 369{
 370        writel(0, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
 371}
 372
 373/* initialize plx9080 chip */
 374static void init_plx9080(struct comedi_device *dev)
 375{
 376        uint32_t bits;
 377        void *plx_iobase = priv(dev)->plx9080_iobase;
 378
 379        /*  plx9080 dump */
 380        DEBUG_PRINT(" plx interrupt status 0x%x\n",
 381                    readl(plx_iobase + PLX_INTRCS_REG));
 382        DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
 383        DEBUG_PRINT(" plx control reg 0x%x\n",
 384                    readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG));
 385
 386        DEBUG_PRINT(" plx revision 0x%x\n",
 387                    readl(plx_iobase + PLX_REVISION_REG));
 388        DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
 389                    readl(plx_iobase + PLX_DMA0_MODE_REG));
 390        DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
 391                    readl(plx_iobase + PLX_DMA1_MODE_REG));
 392        DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
 393                    readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
 394        DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
 395                    readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
 396        DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
 397                    readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
 398        DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
 399                    readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
 400        DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
 401                    readb(plx_iobase + PLX_DMA0_CS_REG));
 402        DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
 403                    readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
 404        DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
 405#ifdef __BIG_ENDIAN
 406        bits = BIGEND_DMA0 | BIGEND_DMA1;
 407#else
 408        bits = 0;
 409#endif
 410        writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
 411
 412        disable_plx_interrupts(dev);
 413
 414        abort_dma(dev, 0);
 415        abort_dma(dev, 1);
 416
 417        /*  configure dma0 mode */
 418        bits = 0;
 419        /*  enable ready input */
 420        bits |= PLX_DMA_EN_READYIN_BIT;
 421        /*  enable dma chaining */
 422        bits |= PLX_EN_CHAIN_BIT;
 423        /*  enable interrupt on dma done (probably don't need this, since chain never finishes) */
 424        bits |= PLX_EN_DMA_DONE_INTR_BIT;
 425        /*  don't increment local address during transfers (we are transferring from a fixed fifo register) */
 426        bits |= PLX_LOCAL_ADDR_CONST_BIT;
 427        /*  route dma interrupt to pci bus */
 428        bits |= PLX_DMA_INTR_PCI_BIT;
 429        /*  enable demand mode */
 430        bits |= PLX_DEMAND_MODE_BIT;
 431        /*  enable local burst mode */
 432        bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
 433        bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
 434        writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
 435}
 436
 437/* Allocate and initialize the subdevice structures.
 438 */
 439static int setup_subdevices(struct comedi_device *dev)
 440{
 441        struct comedi_subdevice *s;
 442
 443        if (alloc_subdevices(dev, 1) < 0)
 444                return -ENOMEM;
 445
 446        s = dev->subdevices + 0;
 447        /* analog input subdevice */
 448        dev->read_subdev = s;
 449/*      dev->write_subdev = s; */
 450        s->type = COMEDI_SUBD_DIO;
 451        s->subdev_flags =
 452            SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ;
 453        s->n_chan = 32;
 454        s->len_chanlist = 32;
 455        s->maxdata = 1;
 456        s->range_table = &range_digital;
 457        s->insn_config = dio_config_insn;
 458        s->do_cmd = hpdi_cmd;
 459        s->do_cmdtest = hpdi_cmd_test;
 460        s->cancel = hpdi_cancel;
 461
 462        return 0;
 463}
 464
 465static int init_hpdi(struct comedi_device *dev)
 466{
 467        uint32_t plx_intcsr_bits;
 468
 469        writel(BOARD_RESET_BIT, priv(dev)->hpdi_iobase + BOARD_CONTROL_REG);
 470        udelay(10);
 471
 472        writel(almost_empty_bits(32) | almost_full_bits(32),
 473               priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG);
 474        writel(almost_empty_bits(32) | almost_full_bits(32),
 475               priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG);
 476
 477        priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
 478                                                  TX_FIFO_SIZE_REG));
 479        priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
 480                                                  RX_FIFO_SIZE_REG));
 481
 482        writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
 483
 484        /*  enable interrupts */
 485        plx_intcsr_bits =
 486            ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
 487            ICS_DMA0_E;
 488        writel(plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
 489
 490        return 0;
 491}
 492
 493/* setup dma descriptors so a link completes every 'transfer_size' bytes */
 494static int setup_dma_descriptors(struct comedi_device *dev,
 495                                 unsigned int transfer_size)
 496{
 497        unsigned int buffer_index, buffer_offset;
 498        uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
 499            PLX_XFER_LOCAL_TO_PCI;
 500        unsigned int i;
 501
 502        if (transfer_size > DMA_BUFFER_SIZE)
 503                transfer_size = DMA_BUFFER_SIZE;
 504        transfer_size -= transfer_size % sizeof(uint32_t);
 505        if (transfer_size == 0)
 506                return -1;
 507
 508        DEBUG_PRINT(" transfer_size %i\n", transfer_size);
 509        DEBUG_PRINT(" descriptors at 0x%lx\n",
 510                    (unsigned long)priv(dev)->dma_desc_phys_addr);
 511
 512        buffer_offset = 0;
 513        buffer_index = 0;
 514        for (i = 0; i < NUM_DMA_DESCRIPTORS &&
 515             buffer_index < NUM_DMA_BUFFERS; i++) {
 516                priv(dev)->dma_desc[i].pci_start_addr =
 517                    cpu_to_le32(priv(dev)->dio_buffer_phys_addr[buffer_index] +
 518                                buffer_offset);
 519                priv(dev)->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
 520                priv(dev)->dma_desc[i].transfer_size =
 521                    cpu_to_le32(transfer_size);
 522                priv(dev)->dma_desc[i].next =
 523                    cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i +
 524                                                                  1) *
 525                                 sizeof(priv(dev)->dma_desc[0])) | next_bits);
 526
 527                priv(dev)->desc_dio_buffer[i] =
 528                    priv(dev)->dio_buffer[buffer_index] +
 529                    (buffer_offset / sizeof(uint32_t));
 530
 531                buffer_offset += transfer_size;
 532                if (transfer_size + buffer_offset > DMA_BUFFER_SIZE) {
 533                        buffer_offset = 0;
 534                        buffer_index++;
 535                }
 536
 537                DEBUG_PRINT(" desc %i\n", i);
 538                DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n",
 539                            priv(dev)->desc_dio_buffer[i],
 540                            (unsigned long)priv(dev)->dma_desc[i].
 541                            pci_start_addr);
 542                DEBUG_PRINT(" next 0x%lx\n",
 543                            (unsigned long)priv(dev)->dma_desc[i].next);
 544        }
 545        priv(dev)->num_dma_descriptors = i;
 546        /*  fix last descriptor to point back to first */
 547        priv(dev)->dma_desc[i - 1].next =
 548            cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits);
 549        DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1,
 550                    (unsigned long)priv(dev)->dma_desc[i - 1].next);
 551
 552        priv(dev)->block_size = transfer_size;
 553
 554        return transfer_size;
 555}
 556
 557static int hpdi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
 558{
 559        struct pci_dev *pcidev;
 560        int i;
 561        int retval;
 562
 563        printk("comedi%d: gsc_hpdi\n", dev->minor);
 564
 565        if (alloc_private(dev, sizeof(struct hpdi_private)) < 0)
 566                return -ENOMEM;
 567
 568        pcidev = NULL;
 569        for (i = 0; i < ARRAY_SIZE(hpdi_boards) && dev->board_ptr == NULL; i++) {
 570                do {
 571                        pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX,
 572                                                hpdi_boards[i].device_id,
 573                                                PCI_VENDOR_ID_PLX,
 574                                                hpdi_boards[i].subdevice_id,
 575                                                pcidev);
 576                        /*  was a particular bus/slot requested? */
 577                        if (it->options[0] || it->options[1]) {
 578                                /*  are we on the wrong bus/slot? */
 579                                if (pcidev->bus->number != it->options[0] ||
 580                                    PCI_SLOT(pcidev->devfn) != it->options[1])
 581                                        continue;
 582                        }
 583                        if (pcidev) {
 584                                priv(dev)->hw_dev = pcidev;
 585                                dev->board_ptr = hpdi_boards + i;
 586                                break;
 587                        }
 588                } while (pcidev != NULL);
 589        }
 590        if (dev->board_ptr == NULL) {
 591                printk("gsc_hpdi: no hpdi card found\n");
 592                return -EIO;
 593        }
 594
 595        printk("gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
 596               pcidev->bus->number, PCI_SLOT(pcidev->devfn));
 597
 598        if (comedi_pci_enable(pcidev, driver_hpdi.driver_name)) {
 599                printk(KERN_WARNING
 600                       " failed enable PCI device and request regions\n");
 601                return -EIO;
 602        }
 603        pci_set_master(pcidev);
 604
 605        /* Initialize dev->board_name */
 606        dev->board_name = board(dev)->name;
 607
 608        priv(dev)->plx9080_phys_iobase =
 609            pci_resource_start(pcidev, PLX9080_BADDRINDEX);
 610        priv(dev)->hpdi_phys_iobase =
 611            pci_resource_start(pcidev, HPDI_BADDRINDEX);
 612
 613        /*  remap, won't work with 2.0 kernels but who cares */
 614        priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
 615                                            pci_resource_len(pcidev,
 616                                                             PLX9080_BADDRINDEX));
 617        priv(dev)->hpdi_iobase =
 618            ioremap(priv(dev)->hpdi_phys_iobase,
 619                    pci_resource_len(pcidev, HPDI_BADDRINDEX));
 620        if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) {
 621                printk(" failed to remap io memory\n");
 622                return -ENOMEM;
 623        }
 624
 625        DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
 626        DEBUG_PRINT(" hpdi remapped to 0x%p\n", priv(dev)->hpdi_iobase);
 627
 628        init_plx9080(dev);
 629
 630        /*  get irq */
 631        if (request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
 632                        driver_hpdi.driver_name, dev)) {
 633                printk(" unable to allocate irq %u\n", pcidev->irq);
 634                return -EINVAL;
 635        }
 636        dev->irq = pcidev->irq;
 637
 638        printk(" irq %u\n", dev->irq);
 639
 640        /*  alocate pci dma buffers */
 641        for (i = 0; i < NUM_DMA_BUFFERS; i++) {
 642                priv(dev)->dio_buffer[i] =
 643                    pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
 644                                         &priv(dev)->dio_buffer_phys_addr[i]);
 645                DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n",
 646                            priv(dev)->dio_buffer[i],
 647                            (unsigned long)priv(dev)->dio_buffer_phys_addr[i]);
 648        }
 649        /*  allocate dma descriptors */
 650        priv(dev)->dma_desc = pci_alloc_consistent(priv(dev)->hw_dev,
 651                                                   sizeof(struct plx_dma_desc) *
 652                                                   NUM_DMA_DESCRIPTORS,
 653                                                   &priv(dev)->
 654                                                   dma_desc_phys_addr);
 655        if (priv(dev)->dma_desc_phys_addr & 0xf) {
 656                printk(" dma descriptors not quad-word aligned (bug)\n");
 657                return -EIO;
 658        }
 659
 660        retval = setup_dma_descriptors(dev, 0x1000);
 661        if (retval < 0)
 662                return retval;
 663
 664        retval = setup_subdevices(dev);
 665        if (retval < 0)
 666                return retval;
 667
 668        return init_hpdi(dev);
 669}
 670
 671static int hpdi_detach(struct comedi_device *dev)
 672{
 673        unsigned int i;
 674
 675        printk("comedi%d: gsc_hpdi: remove\n", dev->minor);
 676
 677        if (dev->irq)
 678                free_irq(dev->irq, dev);
 679        if (priv(dev)) {
 680                if (priv(dev)->hw_dev) {
 681                        if (priv(dev)->plx9080_iobase) {
 682                                disable_plx_interrupts(dev);
 683                                iounmap((void *)priv(dev)->plx9080_iobase);
 684                        }
 685                        if (priv(dev)->hpdi_iobase)
 686                                iounmap((void *)priv(dev)->hpdi_iobase);
 687                        /*  free pci dma buffers */
 688                        for (i = 0; i < NUM_DMA_BUFFERS; i++) {
 689                                if (priv(dev)->dio_buffer[i])
 690                                        pci_free_consistent(priv(dev)->hw_dev,
 691                                                            DMA_BUFFER_SIZE,
 692                                                            priv(dev)->
 693                                                            dio_buffer[i],
 694                                                            priv
 695                                                            (dev)->dio_buffer_phys_addr
 696                                                            [i]);
 697                        }
 698                        /*  free dma descriptors */
 699                        if (priv(dev)->dma_desc)
 700                                pci_free_consistent(priv(dev)->hw_dev,
 701                                                    sizeof(struct plx_dma_desc)
 702                                                    * NUM_DMA_DESCRIPTORS,
 703                                                    priv(dev)->dma_desc,
 704                                                    priv(dev)->
 705                                                    dma_desc_phys_addr);
 706                        if (priv(dev)->hpdi_phys_iobase) {
 707                                comedi_pci_disable(priv(dev)->hw_dev);
 708                        }
 709                        pci_dev_put(priv(dev)->hw_dev);
 710                }
 711        }
 712        return 0;
 713}
 714
 715static int dio_config_block_size(struct comedi_device *dev, unsigned int *data)
 716{
 717        unsigned int requested_block_size;
 718        int retval;
 719
 720        requested_block_size = data[1];
 721
 722        retval = setup_dma_descriptors(dev, requested_block_size);
 723        if (retval < 0)
 724                return retval;
 725
 726        data[1] = retval;
 727
 728        return 2;
 729}
 730
 731static int di_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 732                       struct comedi_cmd *cmd)
 733{
 734        int err = 0;
 735        int tmp;
 736        int i;
 737
 738        /* step 1: make sure trigger sources are trivially valid */
 739
 740        tmp = cmd->start_src;
 741        cmd->start_src &= TRIG_NOW;
 742        if (!cmd->start_src || tmp != cmd->start_src)
 743                err++;
 744
 745        tmp = cmd->scan_begin_src;
 746        cmd->scan_begin_src &= TRIG_EXT;
 747        if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
 748                err++;
 749
 750        tmp = cmd->convert_src;
 751        cmd->convert_src &= TRIG_NOW;
 752        if (!cmd->convert_src || tmp != cmd->convert_src)
 753                err++;
 754
 755        tmp = cmd->scan_end_src;
 756        cmd->scan_end_src &= TRIG_COUNT;
 757        if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
 758                err++;
 759
 760        tmp = cmd->stop_src;
 761        cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
 762        if (!cmd->stop_src || tmp != cmd->stop_src)
 763                err++;
 764
 765        if (err)
 766                return 1;
 767
 768        /* step 2: make sure trigger sources are unique and mutually compatible */
 769
 770        /*  uniqueness check */
 771        if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
 772                err++;
 773
 774        if (err)
 775                return 2;
 776
 777        /* step 3: make sure arguments are trivially compatible */
 778
 779        if (!cmd->chanlist_len) {
 780                cmd->chanlist_len = 32;
 781                err++;
 782        }
 783        if (cmd->scan_end_arg != cmd->chanlist_len) {
 784                cmd->scan_end_arg = cmd->chanlist_len;
 785                err++;
 786        }
 787
 788        switch (cmd->stop_src) {
 789        case TRIG_COUNT:
 790                if (!cmd->stop_arg) {
 791                        cmd->stop_arg = 1;
 792                        err++;
 793                }
 794                break;
 795        case TRIG_NONE:
 796                if (cmd->stop_arg != 0) {
 797                        cmd->stop_arg = 0;
 798                        err++;
 799                }
 800                break;
 801        default:
 802                break;
 803        }
 804
 805        if (err)
 806                return 3;
 807
 808        /* step 4: fix up any arguments */
 809
 810        if (err)
 811                return 4;
 812
 813        if (cmd->chanlist) {
 814                for (i = 1; i < cmd->chanlist_len; i++) {
 815                        if (CR_CHAN(cmd->chanlist[i]) != i) {
 816                                /*  XXX could support 8 channels or 16 channels */
 817                                comedi_error(dev,
 818                                             "chanlist must be channels 0 to 31 in order");
 819                                err++;
 820                                break;
 821                        }
 822                }
 823        }
 824
 825        if (err)
 826                return 5;
 827
 828        return 0;
 829}
 830
 831static int hpdi_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
 832                         struct comedi_cmd *cmd)
 833{
 834        if (priv(dev)->dio_config_output) {
 835                return -EINVAL;
 836        } else
 837                return di_cmd_test(dev, s, cmd);
 838}
 839
 840static inline void hpdi_writel(struct comedi_device *dev, uint32_t bits,
 841                               unsigned int offset)
 842{
 843        writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)],
 844               priv(dev)->hpdi_iobase + offset);
 845}
 846
 847static int di_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 848{
 849        uint32_t bits;
 850        unsigned long flags;
 851        struct comedi_async *async = s->async;
 852        struct comedi_cmd *cmd = &async->cmd;
 853
 854        hpdi_writel(dev, RX_FIFO_RESET_BIT, BOARD_CONTROL_REG);
 855
 856        DEBUG_PRINT("hpdi: in di_cmd\n");
 857
 858        abort_dma(dev, 0);
 859
 860        priv(dev)->dma_desc_index = 0;
 861
 862        /* These register are supposedly unused during chained dma,
 863         * but I have found that left over values from last operation
 864         * occasionally cause problems with transfer of first dma
 865         * block.  Initializing them to zero seems to fix the problem. */
 866        writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
 867        writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
 868        writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
 869        /*  give location of first dma descriptor */
 870        bits =
 871            priv(dev)->dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT |
 872            PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI;
 873        writel(bits, priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
 874
 875        /*  spinlock for plx dma control/status reg */
 876        spin_lock_irqsave(&dev->spinlock, flags);
 877        /*  enable dma transfer */
 878        writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT,
 879               priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
 880        spin_unlock_irqrestore(&dev->spinlock, flags);
 881
 882        if (cmd->stop_src == TRIG_COUNT)
 883                priv(dev)->dio_count = cmd->stop_arg;
 884        else
 885                priv(dev)->dio_count = 1;
 886
 887        /*  clear over/under run status flags */
 888        writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
 889               priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
 890        /*  enable interrupts */
 891        writel(intr_bit(RX_FULL_INTR),
 892               priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
 893
 894        DEBUG_PRINT("hpdi: starting rx\n");
 895        hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG);
 896
 897        return 0;
 898}
 899
 900static int hpdi_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
 901{
 902        if (priv(dev)->dio_config_output) {
 903                return -EINVAL;
 904        } else
 905                return di_cmd(dev, s);
 906}
 907
 908static void drain_dma_buffers(struct comedi_device *dev, unsigned int channel)
 909{
 910        struct comedi_async *async = dev->read_subdev->async;
 911        uint32_t next_transfer_addr;
 912        int j;
 913        int num_samples = 0;
 914        void *pci_addr_reg;
 915
 916        if (channel)
 917                pci_addr_reg =
 918                    priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
 919        else
 920                pci_addr_reg =
 921                    priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
 922
 923        /*  loop until we have read all the full buffers */
 924        j = 0;
 925        for (next_transfer_addr = readl(pci_addr_reg);
 926             (next_transfer_addr <
 927              le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index].
 928                          pci_start_addr)
 929              || next_transfer_addr >=
 930              le32_to_cpu(priv(dev)->dma_desc[priv(dev)->dma_desc_index].
 931                          pci_start_addr) + priv(dev)->block_size)
 932             && j < priv(dev)->num_dma_descriptors; j++) {
 933                /*  transfer data from dma buffer to comedi buffer */
 934                num_samples = priv(dev)->block_size / sizeof(uint32_t);
 935                if (async->cmd.stop_src == TRIG_COUNT) {
 936                        if (num_samples > priv(dev)->dio_count)
 937                                num_samples = priv(dev)->dio_count;
 938                        priv(dev)->dio_count -= num_samples;
 939                }
 940                cfc_write_array_to_buffer(dev->read_subdev,
 941                                          priv(dev)->desc_dio_buffer[priv(dev)->
 942                                                                     dma_desc_index],
 943                                          num_samples * sizeof(uint32_t));
 944                priv(dev)->dma_desc_index++;
 945                priv(dev)->dma_desc_index %= priv(dev)->num_dma_descriptors;
 946
 947                DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long)
 948                            priv(dev)->dma_desc[priv(dev)->dma_desc_index].
 949                            next);
 950                DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
 951        }
 952        /*  XXX check for buffer overrun somehow */
 953}
 954
 955static irqreturn_t handle_interrupt(int irq, void *d)
 956{
 957        struct comedi_device *dev = d;
 958        struct comedi_subdevice *s = dev->read_subdev;
 959        struct comedi_async *async = s->async;
 960        uint32_t hpdi_intr_status, hpdi_board_status;
 961        uint32_t plx_status;
 962        uint32_t plx_bits;
 963        uint8_t dma0_status, dma1_status;
 964        unsigned long flags;
 965
 966        if (!dev->attached) {
 967                return IRQ_NONE;
 968        }
 969
 970        plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
 971        if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) {
 972                return IRQ_NONE;
 973        }
 974
 975        hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
 976        hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
 977
 978        async->events = 0;
 979
 980        if (hpdi_intr_status) {
 981                DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status);
 982                writel(hpdi_intr_status,
 983                       priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
 984        }
 985        /*  spin lock makes sure noone else changes plx dma control reg */
 986        spin_lock_irqsave(&dev->spinlock, flags);
 987        dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
 988        if (plx_status & ICS_DMA0_A) {  /*  dma chan 0 interrupt */
 989                writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
 990                       priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
 991
 992                DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
 993                if (dma0_status & PLX_DMA_EN_BIT) {
 994                        drain_dma_buffers(dev, 0);
 995                }
 996                DEBUG_PRINT(" cleared dma ch0 interrupt\n");
 997        }
 998        spin_unlock_irqrestore(&dev->spinlock, flags);
 999
1000        /*  spin lock makes sure noone else changes plx dma control reg */
1001        spin_lock_irqsave(&dev->spinlock, flags);
1002        dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
1003        if (plx_status & ICS_DMA1_A) {  /*  XXX *//*  dma chan 1 interrupt */
1004                writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
1005                       priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
1006                DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
1007
1008                DEBUG_PRINT(" cleared dma ch1 interrupt\n");
1009        }
1010        spin_unlock_irqrestore(&dev->spinlock, flags);
1011
1012        /*  clear possible plx9080 interrupt sources */
1013        if (plx_status & ICS_LDIA) {    /*  clear local doorbell interrupt */
1014                plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
1015                writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
1016                DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
1017        }
1018
1019        if (hpdi_board_status & RX_OVERRUN_BIT) {
1020                comedi_error(dev, "rx fifo overrun");
1021                async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1022                DEBUG_PRINT("dma0_status 0x%x\n",
1023                            (int)readb(priv(dev)->plx9080_iobase +
1024                                       PLX_DMA0_CS_REG));
1025        }
1026
1027        if (hpdi_board_status & RX_UNDERRUN_BIT) {
1028                comedi_error(dev, "rx fifo underrun");
1029                async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
1030        }
1031
1032        if (priv(dev)->dio_count == 0)
1033                async->events |= COMEDI_CB_EOA;
1034
1035        DEBUG_PRINT("board status 0x%x, ", hpdi_board_status);
1036        DEBUG_PRINT("plx status 0x%x\n", plx_status);
1037        if (async->events)
1038                DEBUG_PRINT(" events 0x%x\n", async->events);
1039
1040        cfc_handle_events(dev, s);
1041
1042        return IRQ_HANDLED;
1043}
1044
1045void abort_dma(struct comedi_device *dev, unsigned int channel)
1046{
1047        unsigned long flags;
1048
1049        /*  spinlock for plx dma control/status reg */
1050        spin_lock_irqsave(&dev->spinlock, flags);
1051
1052        plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
1053
1054        spin_unlock_irqrestore(&dev->spinlock, flags);
1055}
1056
1057static int hpdi_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
1058{
1059        hpdi_writel(dev, 0, BOARD_CONTROL_REG);
1060
1061        writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
1062
1063        abort_dma(dev, 0);
1064
1065        return 0;
1066}
1067