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