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