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