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